设计模式——六大原则

Posted boycelee

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式——六大原则相关的知识,希望对你有一定的参考价值。

设计模式六大原则

标签(空格分隔): 设计模式


  • 单一职责
    一个类,能引起其变化的原因只能有一个。如果一个类中,承担的职责越多,代码耦合度就越高,在修改需求时就会由于修改一个职责而影响另一个职责的使用。
    反例:

    class Terrestrial{
           public void breathe(String animal){
              System.out.println(animal+"呼吸空气");
          }
       }
       class Aquatic{
          public void breathe(String animal){
              System.out.println(animal+"呼吸水");
          }
       }
    
       public class Client{
          public static void main(String[] args){
              Terrestrial terrestrial = new Terrestrial();
              terrestrial.breathe("牛");
              terrestrial.breathe("羊");
              terrestrial.breathe("猪");
    
              Aquatic aquatic = new Aquatic();
              aquatic.breathe("鱼");
           }
       }

问题:如果修改鱼吸水,就会破坏单一原则,所以就需要把类分成陆生和水生。但其实在实际项目中,往往会遇到在项目开始时,并不能考虑到后期需求的更改,会不会使原先设计的类破坏单一原则。

  • 开放-封闭原则
    一个类,只能够拓展,不能够修改。对拓展开放,当需求变更时,可以对现有代码进行拓展;对修改封闭,类一旦设计完成,就不要对其进行任何修改。具体做法,核心思想是对抽象编程,而不是对具体编程,抽象要相对稳定,让类依赖于固定的抽象,就是对修改封闭(不去修改父类方法)。对扩展开放,通过面向对象的思想使用继承或多态去实现子类,子类在父类函数基础上去完善父类提供的方法。
    反例:

       public class BankProcess
       {  //存款 
              public void Deposite(){}
               //取款
               public void Withdraw(){ }
               //转账
               public void Transfer(){}
       }
        public class BankStaff
       {
               private BankProcess bankpro = new BankProcess();
               public void BankHandle(Client client)
               {
                   switch (client.Type)
                   {  //存款
                       case "deposite":
                           bankpro.Deposite();
                           break;
                           //取款
                       case "withdraw":
                           bankpro.Withdraw();
                           break;
                           //转账
                       case "transfer":
                           bankpro.Transfer();
                           break;
                   }
               }
       }

问题:这样的设计,一旦需求更改,需要新加基金功能,就会对违反开放-封闭原则,所以应该修改成抽象类或接口,然后由抽象类(接口)去派生(实现)。在应对新需求时,就可以添加新的子类(实现)去应对需求变更,就不会违背开放-封闭原则。

  • 里氏替换原则
    子类行必须能够替换掉他的父类型。一个软件单位,其子类可以替换其父类,且软件单位功能不受影响,父类才真正被复用,子类也就能够在父类基础上扩展自己的方法。在设计时尽量充抽象类继承而避免从具体类继承。
    尽量不去重写或者重载父类方法,因为可能存在多个子类继承抽象基类,如果其中一个子类修改父类方法,就很可能对其他继承的子类造成影响。

    
       class A{  
           public int func1(int a, int b){  
               return a-b;  
           }  
       }  
    
       public class Client{  
           public static void main(String[] args){  
               A a = new A();  
               System.out.println("100-50="+a.func1(100, 50));  
               System.out.println("100-80="+a.func1(100, 80));  
           }  
       }  
    // 后来,我们需要增加一个新的功能:完成两数相加,然后再与100求和,由类B来负责。即类B需要完成两个功能 
       class B extends A{  
           public int func1(int a, int b){  
               return a+b;  
           }  
    
           public int func2(int a, int b){  
               return func1(a,b)+100;  
           }  
       }  
    
       public class Client{  
           public static void main(String[] args){  
               B b = new B();  
               System.out.println("100-50="+b.func1(100, 50));  
               System.out.println("100-80="+b.func1(100, 80));  
               System.out.println("100+20+100="+b.func2(100, 20));  
           }  
       }  
  • 依赖倒置原则
    抽象高层模块不应该依赖底层模块,面向过程开发中上层调用下层,就造成了上层依赖下层,其中若下层发生变动,则会造成上层调用模块全部都需要改动,而依赖倒转就解决了这一问题。(Spring IOC)

  • 合成/聚合原则
    尽量使用合成/聚合,尽量不要使用类继承,子类与其父类关系密切,父类的修改必然会对子类造成影响,而如果不小心对父类方法进行修改,就会造成子类错误的发生,这种依赖关系增加了类与类之间的依赖关系,提高了耦合度。
    组合与聚合区别

  • 迪米特法则
    如果两个类之间不必直接通信,则这两个类就不应该直接相互作用,其中一个类需要调用另一个类的某一个方法的话,可以通过第三方进行转发调用。其核心思想就是类与类之间松耦合,类之间耦合度越低,其复用性越强。
    (1)优先考虑将一个类设置成不变类。
    (2)尽量降低一个类的访问权限。
    (3)谨慎使用Serializable。
    (4)尽量降低成员的访问权限。

以上是关于设计模式——六大原则的主要内容,如果未能解决你的问题,请参考以下文章

设计模式的六大原则

如何写出优秀的代码?设计模式六大原则告诉你

设计模式六大原则:开闭原则

设计模式六大原则:开闭原则

要想富先练功,设计模式之六大原则

11设计模式六大原则——开闭原则