Java程序设计六大原则设计模式

news2024/11/26 4:25:45

Java程序设计六大原则

一、单一职责原则:

一个接口或者类只有一个原因引起变化,即一个接口或者类只有一个职责,负责一件事情。(此原则同样适用于方法)

好处:1、复杂性降低;2、可读性提高;3、可维护性提高;4、变更风险降低

二、里氏替换原则:

父类能出现的地方子类就可以出现
定义解释:
1、子类必须完全实现父类的方法;

2、子类可以有自己的个性;

3、覆盖或者实现父类的方法时,输入参数可以被放大;

public class Father {undefined
    public Collection doSomething(HashMap map) {undefined
        System.out.println("父类被执行了");
        return map.values();
    }
}

public class Son extends Father {undefined
    public Collection  doSomething(Map  map) {undefined
        System.out.println("子类被执行了");
        return map.values();
    }    
}

public static void main(String[] args) {undefined
    Father father = new Father();
    Son son = new Son();
    HashMap<Object,Object> map = new HashMap<>();
    
    father.doSomething(map);
    son.doSomething(map);
}

以上代码执行时,子类重载了父类的doSomething方法,并且放大输入参数Hashmap→Map,执行以后,出现相同的结果,均输出"父类被执行了",并没有歪曲父类的意图,不会引起业务逻辑混乱,符合里氏替换原则。

4、覆写或者实现父类的方法时,输出结果可以被缩小;

三、依赖倒置原则:

1、高层不应该依赖底层,两者都应该依赖其抽象;

2、抽象不应该依赖细节,细节应该依赖抽象;
即模块间的依赖通过抽象发生,实现类之间不发生直接的依赖关系,其依赖关系是通过接口或者抽象类产生的。更加简单的定义就是"面向接口编程(OOD:Object-Oriented Design)"

四、接口隔离原则:

通俗的讲,接口尽量细化,同时接口中的方法尽量少。说明:单一职责原则侧重于业务逻辑,即职责尽量少;而接口隔离原则侧重于接口中的方法尽量少。

五、迪米特法则:

也称为最少知识原则:一个对象应该对其他对象有最少的了解。通俗的讲:一个类应该对自己需要耦合或者调用的类知道的越少越好

六、开闭原则:

软件实体应该对扩展开放,对修改关闭。就是说应该通过扩展来实现变化,而不是通过修改已有的代码来实现变化。

设计模式:

一、门面模式(外观模式):

是指提供一个统一的接口去访问多个子系统的多个不同的接口,它为子系统中的一组接口提供一个统一的高层接口。使得子系统更容易使用。

定义一个(或多个)具备所需接口的新类(门面类);
新类门户使用原来的系统;
客户使用门面类对象与原系统打交道;

1、activity内部直接使用三方网络请求库的api 来请求网络,导致activity和网络请求库高度耦合,且违背单一职责原则。

2、使用门面模式对网络请求框架进行封装,使用单例模式编写门面类,在门面类内部直接使用三方网络请求库的api 来请求网络(即门面类拥有网络库的功能),并定义网络返回结果的接口,最后通过接口回调的方式返回网络请求结果到activity。

// 接口
public interface IHttpApi {

    void register();

    void login();

    void getUserInfo();
}

// 三方网络库
public class OkHttp implements IHttpApi {
    @Override
    public void register() {
        System.out.println("OkHttp register");
    }

    @Override
    public void login() {
        System.out.println("OkHttp login");
    }

    @Override
    public void getUserInfo() {
        System.out.println("OkHttp getUserInfo");
    }
}


// 门面类
public class UserApi {

    private OkHttp okHttp;

    public static UserApi getInstance(){
        return UserApiHelper.userApi;
    }

    private static class UserApiHelper{
        private static UserApi userApi = new UserApi();
    }

    private UserApi() {
        okHttp = new OkHttp();
    }

    public void login(){
        System.out.println("UserApi login");
        okHttp.register();
        okHttp.login();
    }

    public void getUserInfo(){
        System.out.println("UserApi getUserInfo");
        okHttp.login();
        okHttp.getUserInfo();
    }
}

// 使用
public static void main(String[] args) {
        UserApi.getInstance().login();
        UserApi.getInstance().getUserInfo();
    }

优点:解耦activity和三方网络库,activity实现单一职责原则;

缺点:门面类和网络请求库高度耦合,当需要切换网络库时,需要修改整个门面类,违背了开闭原则。

二、代理模式(Proxy):

为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。

1、创建代理类,三方库实现类,统一规则接口;

public interface IHttpApi {

    void register();

    void login();

    void getUserInfo();
}

2、代理类和三方库都要实现统一规则接口,同时代理类拥有三方库实现类这个对象(以接口的形式持有)

// 三方库OkHttp 
public class OkHttp implements IHttpApi {
    @Override
    public void register() {
        System.out.println("OkHttp register");
    }

    @Override
    public void login() {
        System.out.println("OkHttp login");
    }

    @Override
    public void getUserInfo() {
        System.out.println("OkHttp getUserInfo");
    }
}

// 三方库Volley 
public class Volley implements IHttpApi {
    @Override
    public void register() {
        System.out.println("Volley register");
    }

    @Override
    public void login() {
        System.out.println("Volley login");
    }

    @Override
    public void getUserInfo() {
        System.out.println("Volley getUserInfo");
    }
}

// 代理类
public class UserApi implements IHttpApi {
    private IHttpApi iHttpApi;

    public UserApi(IHttpApi iHttpApi) {
        this.iHttpApi = iHttpApi;
    }


    @Override
    public void register() {
        System.out.println("UserApi register");
        iHttpApi.register();
    }

    @Override
    public void login() {
        System.out.println("UserApi login");
        iHttpApi.login();
    }

    @Override
    public void getUserInfo() {
        System.out.println("UserApi getUserInfo");
        iHttpApi.getUserInfo();
    }
}

3、三方库实现类,直接使用三方网络请求库的api 来请求网络(即三方库实现类拥有网络库的功能)

4、统一规则接口,即get和post方法

5、在初始代理类时,需要传入三方库实现类的类型(如:volley或okhttp)。

6、用户调用代理类实现的网络请求接口时,代理类通过调用 持有的三方库实现类 去调用三方网络请求库的api 来请求网络。

7、代理类本身不具备网络库的功能,充当中介的作用,去调用三方库实现类。

public static void main(String[] args) {
        // 代理OkHttp
        System.out.println("代理OkHttp");
        OkHttp okHttp = new OkHttp();
        UserApi userApi = new UserApi(okHttp);
        userApi.register();
        userApi.login();
        userApi.getUserInfo();
        // 代理Volley
        System.out.println("代理Volley");
        Volley volley = new Volley();
        userApi = new UserApi(volley);
        userApi.register();
        userApi.login();
        userApi.getUserInfo();
    }

优点:解耦代理类和三方网络库,当需要更换三方网络库时,直接在初始化代理类时,需要传入新的三方库实现类。

三方库实现类使用了里氏替换原则,子类必须完全实现父类的方法。

三、单例模式:

确保一个类只有一个实例,而且自行实例化并向整个系统或应用提供这个实例。

饿汉模式
懒汉模式
Double Check Lock
枚举单例
静态内部类实现单例(最优雅单例)

private static class SingletonHolder {
    private static final Singleton INSTANCE = new Singleton();
}

public static Singleton getSingleton5() {
    return SingletonHolder.INSTANCE;
}

四、建造者模式(Builder模式):

将一个复杂对象的创建和表示分离,使用相同的构建过程创建不同的对象。

public class TestPerson {
    private String mPersonName;
    private int mPersonAge;
    private int mSex;
    private String mCardNumber;

    public TestPerson TestPerson(){
        return new TestPerson(new TestPerson.Builder());
    }

    public TestPerson(TestPerson.Builder builder){
        this.mCardNumber = builder.mCardNumber;
        this.mSex = builder.mSex;
        this.mPersonAge = builder.mPersonAge;
        this.mPersonName = builder.mPersonName;
    }

    public static final class Builder {
        private String mPersonName;
        private int mPersonAge;
        private int mSex;
        private String mCardNumber;

        public Builder(){}

        public TestPerson build(){
            return new TestPerson(this);
        }

        public TestPerson.Builder addPersonName(String mPersonName) {
            this.mPersonName = mPersonName;
            return this;
        }

        public TestPerson.Builder addPersonAge(int mPersonAge) {
            this.mPersonAge = mPersonAge;
            return this;
        }

        public TestPerson.Builder addSex(int mSex) {
            this.mSex = mSex;
            return this;
        }

        public TestPerson.Builder addCardNumber(String mCardNumber) {
            this.mCardNumber = mCardNumber;
            return this;
        }
    }
}

TestPerson pserson = new TestPerson.Builder()
        .addPersonName("狗蛋")
        .addSex(1)
        .addPersonAge(18)
        .build();

五、观察者模式(Observer Pattern):

当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知依赖它的对象。观察者模式属于行为型模式。

三要素:Observer是观察者接口,Observable是被观察者接口,ObservableImpl是被观察者实现类(管理所有观察者)。

Observer观察者接口:

public interface Observer {
    void update(String message);
}

Observable被观察者接口:

public interface Observable {
    // 添加观察者
    void addObserver(Observer observer);

    // 移除观察者
    void removeObserver(Observer observer);

    // 通知观察者
    void notifyObserver(String message);
}

ObservableImpl被观察者实现类:

public class ObservableImpl implements Observable {

    private List<Observer> observerList = new ArrayList<>();

    public static ObservableImpl getInstance() {
        return ObservableHelper.observable;
    }

    private static class ObservableHelper {
        private static ObservableImpl observable = new ObservableImpl();
    }

    @Override
    public void addObserver(Observer observer) {
        if (!observerList.contains(observer)) {
            observerList.add(observer);
        }
    }

    @Override
    public void removeObserver(Observer observer) {
        if (observerList.contains(observer)) {
            observerList.remove(observer);
        }
    }

    @Override
    public void notifyObserver(String message) {
        for (Observer observer : observerList) {
            observer.update(message);
        }
    }
}

ObserverImpl观察者实现类:

public class ObserverImpl implements Observer {

    private String observerName;

    public ObserverImpl(String observerName) {
        this.observerName = observerName;
    }

    @Override
    public void update(String message) {
        System.out.println(observerName + ":" + message);
    }
}

ObserverImpl观察者实现类,一般不需要单独编写实现类,这里是为了测试;比如:view要观察activity数据变化而刷新UI,view只要实现Observer观察者接口,view就是观察者实现类。

public static void main(String[] args) {
        // 创建观察者
        ObserverImpl observer1 = new ObserverImpl("observer1");
        ObserverImpl observer2 = new ObserverImpl("observer2");
        ObserverImpl observer3 = new ObserverImpl("observer3");
        // 添加观察者
        ObservableImpl.getInstance().addObserver(observer1);
        ObservableImpl.getInstance().addObserver(observer2);
        ObservableImpl.getInstance().addObserver(observer3);
        // 通知观察者
        ObservableImpl.getInstance().notifyObserver("更新数据");
    }

六、工厂模式:

定义一个用于创建对象的接口,让子类决定实例化哪个类。

创建一个接口:

public interface Car {
    void drive();
}

创建实现接口的实体类:

// 自行车
public class Bike implements Car{
    @Override
    public void drive() {
        System.out.println("Bike drive");
    }
}


// 大巴
public class Bus implements Car{
    @Override
    public void drive() {
        System.out.println("Bus drive");
    }
}

// 火车
public class Train implements Car {
    @Override
    public void drive() {
        System.out.println("Train drive");
    }
}

创建一个工厂,生成基于给定信息的实体类的对象:

public class CarFactory {
    public static Car makeCar(String type) {
        Car car = null;
        switch (type) {
            case "Bike":
                car = new Bike();
                break;
            case "Bus":
                car = new Bus();
                break;
            case "Train":
                car = new Train();
                break;
        }
        return car;
    }
}

使用该工厂,通过传递类型信息来获取实体类的对象。

public static void main(String[] args) {
        CarFactory.makeCar("Bike").drive();
        CarFactory.makeCar("Bus").drive();
        CarFactory.makeCar("Train").drive();
    }

七、策略模式:

定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换,策略模式让算法独立于使用它的客户而独立变化。

  • 针对同一类型问题的多种处理方式,仅仅是具体行为有差别时;
  • 需要安全地封装多种同一类型的操作时;
  • 出现同一抽象类有多个子类,而又需要使用if-else或者switch-case来选择具体子类时。

使用场景:RecyclerView.ViewHolder,一个新闻列表页面,根据不同的viewtype需要分别显示左文右图和左图右文的效果;

创建一个接口,这里使用RecyclerView.ViewHolder

public abstract static class ViewHolder {
        // ...
}

创建实现接口的实体类

static class ViewHolder extends RecyclerView.ViewHolder {
	private ImageView ivIcon;
	private TextView tvZhName;
	private TextView tvEnName;

	public ViewHolder(View view) {
		super(view);
		ivIcon = view.findViewById(R.id.iv_icon);
		tvZhName = view.findViewById(R.id.tv_zh_name);
		tvEnName = view.findViewById(R.id.tv_en_name);
	}
}

根据不同的viewtype创建不同策略(布局)的ViewHolder

public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
	View view = null;
	if (viewType == 15 || viewType == 16 || viewType == 17) {
		view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_long, parent, false);
	} else {
		view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_control, parent, false);
	}
	ViewHolder holder = new ViewHolder(view);
	return holder;
}

八、责任链模式:

避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/784968.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

深度学习和神经网络

人工神经网络分为两个阶段&#xff1a; 1 &#xff1a;接收来自其他n个神经元传递过来的信号&#xff0c;这些输入信号通过与相应的权重进行 加权求和传递给下个阶段。&#xff08;预激活阶段&#xff09; 2&#xff1a;把预激活的加权结果传递给激活函数 sum :加权 f:激活…

代码随想录算法训练营之JAVA|第十一天| 239. 滑动窗口最大值

今天是第11天刷leetcode&#xff0c;立个flag。 算法挑战链接 239. 滑动窗口最大值https://leetcode.cn/problems/sliding-window-maximum/description/ 第一想法 题目理解&#xff1a;找到滑动窗口中最大的值&#xff0c;写入数组中&#xff0c;返回该数组即可。 第一个想…

VeriEye 13.0商用虹膜识别软件python SDK试用指南

最近&#xff0c;商用虹膜识别软件VeriEye 13.0发布&#xff0c;且额外地新增了python接口&#xff0c;这样就很方便大家直接调用其提供的虹膜识别接口了。 在使用python接口前&#xff0c;需要先下载安装试用版SDK&#xff0c;然后激活许可证。具体如下&#xff1a; 1. VeriE…

代码审计利器 Fortify SCA 2023.1(23.1) Crack

Fortify SCA 支持丰富的开发环境、语言、平台和框架&#xff0c;可对开发与生产混合环境进行安全检查。 25 种编程语言 超过 911,000 个组件级 API 可检测超过 961 个漏洞类别 支持所有主流平台、构建环境和 IDE。 Fortify SCA是一款商业软件&#xff0c;价格较为昂贵&#xf…

基金”中考”百亿基金经理”惜墨如金”

时下是基金二季报披露高峰&#xff0c;基民往往会期盼基金经理能在季报里带来“定心丸”。但个别基金经理的投资分析仅一两百字带过&#xff0c;对业绩亏损和调仓思路等关键问题更是直接忽略。 券商中国记者发现&#xff0c;有管理规模超370亿的基金经理&#xff0c;投资运作分…

ZohoProjects入选2022年度项目及项目组合管理类

有效的项目管理方法保证项目按照进度、成本、质量要求进行交付&#xff0c;是针对单个项目或项目群的管理&#xff0c;从而确保项目符合企业的战略目标&#xff0c;实现企业收益最大化。 对于项目管理工作来说&#xff0c;我们通常会认为只有专业的经理才能胜任&#xff0c;软件…

【每日一题】—— C. Game with Reversing (Codeforces Round 879 (Div. 2))

&#x1f30f;博客主页&#xff1a;PH_modest的博客主页 &#x1f6a9;当前专栏&#xff1a;每日一题 &#x1f48c;其他专栏&#xff1a; &#x1f534; 每日反刍 &#x1f7e1; C跬步积累 &#x1f7e2; C语言跬步积累 &#x1f308;座右铭&#xff1a;广积粮&#xff0c;缓称…

flask框架的请求处理逻辑

Django 和 Flask 是 Python 的两个非常流行的 Web 框架&#xff0c;它们对 HTTP 请求的处理方式有一些区别。 在 Django 中&#xff0c;当你的应用接收到一个 HTTP 请求时&#xff0c;Django 会将请求封装为一个 HttpRequest 对象&#xff0c;然后通过视图函数的参数传递这个对…

【计算机网络】简易TCP网络小程序

文章目录 1. 简易TCP网络程序1.1 服务端1.1.1 服务端创建套接字1.1.2 服务端绑定1.1.3 服务端监听1.1.4 服务端获取连接1.1.5 服务端处理请求 1.2 客户端1.2.1 客户端创建套接字1.2.2 客户端连接服务器1.2.3 客户端发起请求 1.3 服务器测试1.4 单执行流服务器的弊端 2. 多进程版…

【个人笔记】Linux的用户登录与退出

目录 Linux 的发行版Linux 的登录1.命令行登录2.ssh登录3.图形界面登录图形模式与文字模式的切换方式 Linux 的退出Linux 的关机与重启Linux 查看用户登录Linux在线命令工具 Linux 的发行版 Linux 的发行版说简单点就是将 Linux 内核与应用软件做一个打包。 目前市面上较知名…

使用Spring Boot实现Redis键过期回调功能

使用Spring Boot实现Redis键过期回调功能 当使用Redis作为缓存或数据存储的时候&#xff0c;有时候需要在键过期时执行一些特定的操作&#xff0c;比如清除相关数据或发送通知。在Spring Boot中&#xff0c;可以通过实现RedisMessageListener接口来实现Redis键过期回调功能。下…

任务的综合应用

需求 创建 4 个任务&#xff1a;TaskLED_1&#xff0c;TaskLED_2&#xff0c;TaskKEY_1&#xff0c;TaskKEY_2 任务要求如下&#xff1a; TaskLED_1&#xff1a;间隔 500ms 闪烁 LED1 TaskLED_2&#xff1a;间隔 1000ms 闪烁 LED2 TaskKEY_1&#xff1a;如果 taskLED1 存在…

Windows10强制删除文件或文件夹内容

一、需求描述 我们的Windows电脑中,会存在一些特殊的应用场景比如【(文件、文件夹)被读写保护、隐藏、或被程序一直占用、被感染了病毒】导致无法删除;此时候就需要采取强制删除的方式解决。 二、需求分析 文件、文件夹被占用,无法正常删除;但是有需要强制删除。 三、解…

安全攻击 --- XSS攻击

XSS跨站脚本攻击 &#xff08;1&#xff09;简介 OWASP TOP 10 之一&#xff0c;XSS被称为跨站脚本攻击&#xff08;Cross-Site-Scripting&#xff09;主要基于JavaScript&#xff08;JS&#xff09;完成攻击行为XSS通过精心构造JS代码注入到网页中&#xff0c;并由浏览器解释…

生态合作丨MemFireDB通过麒麟软件NeoCertify认证

近日&#xff0c;敏博科技“MemFireDB分布式关系数据库系统V2.8”与麒麟软件“银河麒麟高级服务器操作系统V10” 完成兼容性测试&#xff0c;获得麒麟软件 NeoCertify 认证证书。测试结果显示&#xff0c;MemFireDB数据库在国产操作系统上运行稳定&#xff0c;产品已经达到通用…

曲线拟合曲面拟合(MATLAB拟合工具箱)前馈量计算(压力闭环控制应用)

利用PLC进行压力闭环控制的项目背景介绍请查看下面文章链接,这里不再赘述。 信捷PLC压力闭环控制应用(C语言完整PD、PID源代码)_RXXW_Dor的博客-CSDN博客闭环控制的系列文章,可以查看PID专栏的的系列文章,链接如下:张力控制之速度闭环(速度前馈量计算)_RXXW_Dor的博客-CSD…

Windows下Python调用海康SDK实时显示网络摄像头

参考资源&#xff1a; 1.《Windows下Python调用海康SDK实时显示网络摄像头》 2.《HikVision SDK: C 至 Python》 3.《linux下Python调用海康SDK实时显示网络摄像头》 4.《python调用海康sdk操作热成像设备获取对应点温度》 5.《Windows下Python调用海康SDK实时视频流获取》 6.《…

基于VUE3+Layui从头搭建通用后台管理系统(前端篇)六:后台主页功能实现下

一、本章内容 接上一章,继续实现后端主页内容,主要实现工具栏对应相关内容的实现,包括系统消息、系统公告、全屏切换、语言切换、主题切换等。 1. 详细课程地址: 待发布 2. 源码下载地址: 待发布 二、界面预览 三、开发视频 基于VUE3+Layui从头搭建通用后台管理系统合集…

(五)RabbitMQ-进阶 死信队列、延迟队列、防丢失机制

Lison <dreamlison163.com>, v1.0.0, 2023.06.23 RabbitMQ-进阶 死信队列、延迟队列、防丢失机制 文章目录 RabbitMQ-进阶 死信队列、延迟队列、防丢失机制死信队列延迟队列延迟队列介绍**延迟队列_死信队列_的实现**延迟队列_插件实现下载插件RabbitMQ 配置类RabbitMQ …

知网的caj格式怎么转化成pdf格式?两个方法简单快捷!

在使用知网等学术资源时&#xff0c;我们常常会遇到CAJ格式的文件&#xff0c;然而CAJ格式并不是常见的文件格式&#xff0c;给我们的查阅和分享带来一些不便。为了更方便地处理这些文件&#xff0c;我们可以将其转换为常见的PDF格式。在本文中&#xff0c;我将为您介绍两种简单…