大话设计模式之七大原则

设计模式七大原则

设计模式概述

​ 设计模式就是对软件设计过程中存在的普遍问题,所提出的解决方案。能够很好的解决一些常见的问题。

​ 设计模式的最终目的就是:高内聚低耦合

  • 代码重用性:相同功能的代码,不需要多次编写
  • 代码可读性:编程规范性,便于其他程序员阅读
  • 代码可扩展性:当增加新的功能后,对原来功能没有影响

七大原则

一、单一责任原则

​ 顾名思义,我们设计的类尽量负责一项功能,这样不容易造成代码混乱,避免出现一些bug。

反例:

Single类:

public class single{
    public static void main(String[] args){
        People people = new People;
        people.run("老师");
   		people.run("学生");
        people.run("校长");
    }
}

People类:

public class People{
    void run(String type){
        System.out.println(type+"给学生上课");
    }
}

​ 这样会造成,不管是老师、学生、校长都会调用这个方法,因为People不止负责了一个功能,所以该设计有问题。

改进

​ 对于上面的例子,我们采用单一职责原则重写一下,将People拆分成三个类,分别是学生、老师、校长。让他们负责各自的功能,使其互相不影响。如果想对学生做限制,那么只需要对学生类进行修改。

优化

​ 或者可以将上面People分为三个方法,每个方法对应不同的人员,将单一职责落在方法层面而不是类层面

优缺点

优点:

  • 降低类的复杂度,一个类只负责一个职责
  • 提高代码的可读性,逻辑清楚明了
  • 降低风险,只修改一个类,并不影响其他类的功能

缺点:

  • 代码增多(可以将单一职责落在方法层面进行优化)

二、接口隔离原则

​ 类不应该依赖不需要的接口,接口尽量小颗粒划分、如果将多个方法合并为一个接口,再提供给其他系统使用的时候,就必须实现该接口的所有方法,那些方法是根本不需要的,造成使用者的混淆

三、依赖倒转原则

  • 高层模块不应该依赖底层模块,二者都应该依赖接口或抽象类
  • 其核心就是面向接口编程
  • 依赖倒转原则主要是基于如下的设计概念:相对于细节的多变性,抽象的东西要更加稳定的多,以抽象为基础搭建的框架更加稳定
  • 抽象指接口或抽象类,细节指具体的实现类
反例:
  • 设计图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QaVgzavi-1593420283358)(https://raw.githubusercontent.com/iszhonghu/Picture-bed/master/img/20200629150212.png)]

Potato类

public class Potato{
    public void run(){
        System.out.println("买了土豆");
    }   
}

People类

public class People{
    public void bug(Potato potato){
        potato.run();
    }
}

Test类

public class Test{
    public staticvoid main(String[] args){
        People people = People();
        people.bug(new Potato());
    }
}
改进

​ 上述在反例中,如果不想买土豆,想买其他的蔬菜,就比较麻烦还需要改People方法,这就是代码中的模块和模块之间的耦合性太高。

  • 改进后的设计图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QuXNMN0h-1593420283360)(https://raw.githubusercontent.com/iszhonghu/Picture-bed/master/img/20200629150342.png)]

​ 这样我们从底层的类抽象出一个接口类,其直接和高层进行交互,而底层的一些类则不参与,这样能降低耦合度,提高稳定性。

  • Vegetables类
public interface Vegetables{
    public void run();
}
  • Potato类

    public class Potato implements Vegetables{
        public void run(){
            System.out.println("买了土豆");
        }   
    }
    
  • Tomato类

public class Tomato implements Vegetables{
    public void run(){
        System.out.println("买了番茄");
    }
}
  • People类
public class People{
    public void bug(Vegetables vegetable){
        vegetable.run();
    }
}
  • Test类
public class Test{
    public static void main(String[] args){
        People people = new People();
        people.bug(new Potato());
        people.bug(new Tomato());
    }
}
总结

​ 该原则的重点在于”倒转“,要从底层往上思考,尽量抽象抽象类和接口。此例子很好的解释了”上层模型不能依赖底层模块,应该都依赖于抽象“。

四、里氏替换原则

​ 主要是阐述了对继承extend的一些看法

继承的优点:

  • 提高代码的可重用性,子类也有父类的属性和方法
  • 提高代码的可扩展性,子类有自己特有的方法

继承的缺点:

  • 当父类发生改变的时候,要考虑子类的修改

​ 里氏替换原则是继承的基础,只有当子类替换父类时,软件功能仍不受影响,才说明父类真正被复用了。

原则一:

​ 子类必须实现父类的抽象方法,但不得重写(覆盖)父类的非抽象的方法

原则二:

​ 子类中可以增加自己特有的方法。

原则三;

​ 当子类覆盖或实现父类的方法时,方法的前置条件(即方法的形参)要比父类方法的输入参数更加宽松。

五、开闭原则

​ 前面四个原则都是为了开闭原则做铺垫,其是最基础、最重要的设计原则,核心为对扩展开发,对修改关闭、简单来说,通过扩展软件的行为来实现变化,而不是通过修改来实现。

六、迪米特原则

介绍:
  • 一个对象应该对其他对象保持最少的了解。
  • 类与类关系越密切,耦合度越大
  • 一个类对自己依赖的类知道的越少越好。也就是说,对于被依赖的类不管多么复杂,都尽量将逻辑封装在类的内部。对外除了提供的public 方法,不对外泄露任何信息
  • 迪米特法则还有个更简单的定义:只与直接(熟悉)的朋友通信

直接(熟悉)的朋友:每个对象都会与其他对象有耦合关系,只要两个对象之间有耦合关系, 我们就说这两个对象之间是朋友关系。耦合的方式很多,依赖,关联,组合,聚合等。
其中,我们称出现成员变量,方法参数,方法返回值中的类为直接的朋友,而出现在局部变量中的类不是直接的朋友。也就是说,陌生的类最好不要以局部变量 的形式出现在类的内部。

七、合成复用原则

  • 尽量使用合成/集合,不要用继承
  • 如果使用继承,会使得耦合性加强,尽量作为方法的输入参数或类的成员变量,这样可以避免耦合

最后

  • 如果觉得看完有收获,希望能给我点个赞,这将会是我更新的最大动力,感谢各位的支持
  • 欢迎各位关注我的公众号【java冢狐】,专注于java和计算机基础知识,保证让你看完有所收获,不信你打我
    友。也就是说,陌生的类最好不要以局部变量 的形式出现在类的内部。

七、合成复用原则

  • 尽量使用合成/集合,不要用继承
  • 如果使用继承,会使得耦合性加强,尽量作为方法的输入参数或类的成员变量,这样可以避免耦合

最后

  • 如果觉得看完有收获,希望能给我点个赞,这将会是我更新的最大动力,感谢各位的支持
  • 欢迎各位关注我的公众号【java冢狐】,专注于java和计算机基础知识,保证让你看完有所收获,不信你打我
  • 如果看完有不同的意见或者建议,欢迎多多评论一起交流。感谢各位的支持以及厚爱。

你可能感兴趣的:(所有文章,杂谈,设计模式,抽象类,java,编程语言)