java设计模式——浅显易懂之七大原则

大家好,我是老王。一名正在学java设计模式的大三学生。准备连载java设计模式系列供自己以后复习和大家学习讨论。由于本人是初学者,站的角度更多是它是什么,我们要怎么做的角度进行思考,有出错的地方欢迎各位大牛指正,接下来直接进入正题。

一、引言

为什么要认识七大原则?
我们准备学的23种设计模式就是要遵循7大原则,它对每种设计模式进行约束,增加其扩展性和可维护性。
本文章将从以下两个角度用‘庸俗’的例子进行讲解,尽量做到通俗易懂

  • 提出官网说法
  • 自己理解

二、分类

1.单一职责原则
2.接口隔离原则
3.依赖倒转原则
4.里氏替换原则
5.开闭原则
6.迪米特法则
7.合成复原原则

三、详细描述

1. 单一职责原则

  • 官方定义:

    所谓职责是指类变化的原因。如果一个类有多于一个的动机被改变,那么这个类就具有多于一个的职责。而单一职责原则就是指一个类或者模块应该有且只有一个改变的原因。

  • 自己理解:

    其实看上面的说法我也是看不懂,但是简单讲就是描述一种思想,一个类(对象)只能干一种事情。
    例如一个修自行车的,你不能要求人家去修奔驰啊!!!你要修奔驰,得去找4s店啊。
    在java里也一样,每个类应该负责自己该负责的功能,做到专一。

2. 接口隔离原则

  • 官方定义:

    1.一个类对另外一个类的依赖性应当是建立在最小的接口上的。
    2.不应该强迫客户依赖于它们不用的方法。接口属于客户,不属于它所在的类层次结构。

  • 自己理解:

    什么意思呢,比如说一个接口定义了3个方法:
    1.查广东省总人口数()
    2.查广东省市级数()
    3.查广东省一线城市数()

    现在我有一个需求,我需要查 广东总人口数和查广东市级数,所以我实现了这个上面这个接口,但是接口中第三个方法:查广东省一线城市数是我不需要的,但是我为了我自己的需求,我必须也对它进行实现。

    因为这个接口多了一个方法是我不想要的,所以造成不是依赖最小接口,这就违反了一个类对另外一个类的依赖性应当是建立在最小的接口上的因此我应该把上面接口得3个方法逐一拆分,然后需要什么功能,就去实现对应得方法

3. 依赖倒转原则

  • 官方定义:

    程序要依赖于抽象接口,不要依赖于具体实现。简单的说就是要求对抽象进行编程,不要对实现进行编程,这样就降低了客户与实现模块间的耦合。

  • 自己理解:

    比如说有个类:laowang,只有一个方法就是goToBeijing,它接收一个参数:Car(汽车对象)

    class Laowang{
        public  void  goToBeijing(Car car){
            System.out.println("老王开着"+car.name+"去北京");
        }
    }
    
    //这是一个汽车对象类
    class Car{
    	public String name="汽车";
    } 
    
    //main方法
    public static void main(String[] args) {
        Laowang laowang = new Laowang();
        Car car = new Car();
        laowang.goToBeijing(car);
    }
    
    此时运行结果为:
    	老王开着汽车去北京
    

    现在来了新的麻烦,老王的汽车坏了,这时买了一辆飞机(AirPort),但是去北京得方法只定义了接受一个汽车对象的参数(Car),这怎么办呢????解决的办法倒是很简单,把参数改为飞机类型(AirPort)即可。
    但是这样真的好吗????如果我下次飞机坏了呢,买了辆和谐号?岂不是又得改代码?正确的解决办法如下
    让汽车,飞机都继承于一个交通工具类(Vehicle),然后让老王去北京接受参数改为(Vehicle)即可。此时你给我奥迪,我就开奥迪,你给我飞机,我就开飞机,你给我和谐号,我就开和谐号去北京。何乐而不为。代码如下:

    class Laowang{
        public  void  goToBeijing(Vehicle vehicle){
            System.out.println("老王开着"+vehicle.name+"去北京");
        }
    }
    
    //交通工具类
    class Vehicle{
       public String name;
    }
    //汽车类
    class Car extends Vehicle{
        public Car(){
            super.name="汽车";
        }
    }
    //飞机类
    class AirPort extends Vehicle{
        public AirPort(){
            super.name="飞机";
        }
    }
    //main方法
    public static void main(String[] args) {
        Laowang laowang = new Laowang();
        Car car = new Car();
        AirPort airPort=new AirPort();
        //给老王汽车
        laowang.goToBeijing(car);
        //给老王飞机
        laowang.goToBeijing(airPort);
    }
    运行结果如下:
    	老王开着汽车去北京
    	老王开着飞机去北京
    

    各位看懂了吗?这就是依赖倒置原则。老王去北京不要依赖于汽车这个类,而应该依赖于汽车的接口或抽象类:Vehicle交通工具,这样有利于扩展程序。

4. 里氏替换原则

  • 官方定义:

    1.如果对每一个类型为S的对象o1,都有类型为T的对象o2,使得以T定义的所有程序P在所有的对象o1都代换成o2时,程序P的行为没有发生变化,那么类型S是类型T的子类型。(别看了,你看不懂的,我也看不懂
    2.所有引用基类的地方必须能透明地使用其子类的对象。
  • 自己理解:

    定义看起来很复杂,但是思想很简单。里氏替换原则针对的是继承,说的是如果一个B类继承A类,那么你千万不要去重写父类(A类)的方法。迫不得已的情况下,让B类不要继承A类,然后用依赖,聚合,组合等方式调用父类方法。

5.开闭原则(OCP)

  • 官方定义:

    1.开闭原则规定“软件中的对象(类,模块,函数等等)应该对于扩展是开放的,但是对于修改是封闭的”。
  • 自己理解:

    这句官方定义看起来很矛盾对不对,保证对扩展开放,然后又对修改是关闭的?怎么理解这句话呢,是这样的:
    对(提供方)拓展开放,对(使用方)修改是封闭的。
    举个例子:脑回路跳转到依赖倒转中!!!!在老王汽车坏掉了后,想要开飞机去北京,是不是就得修改2个地方:(1)把老王goToBeiJing参数改为飞机。(2)增加了飞机类。 其实这就违反了开闭原则。提供方是飞机,那修改代码没毛病,但是对于使用方(老王)我需要修改源代码。这就违反了开闭原则。所以应该让老王goToBeiJing参数接收一个抽象类, 这样无论你拿什么给我开,我都可以开,不用修改老王的代码。

6.迪米特法则

  • 官方定义:

    迪米特法(Law of Demeter)又叫作最少知识原则,一个类对于其他类知道的越少越好,就是说一个对象应当对其他对象有尽可能少的了解,只和朋友通信,不和陌生人说话。
  • 自己理解:

    一个对象只能与它的直接朋友通信。直接朋友是什么呢?就是在类的成员变量,成员方法参数,返回值中出现的对象,都可以叫做直接朋友。
    那有直接朋友,就会有陌生人。举个例子:
    class Laowang{
    	public  void  goToBeijing(Vehicle vehicle){
            System.out.println("老王开着"+vehicle.name+"去北京");
            Car car = new Car;
        }
    }
    
    在这个类中,Vehicle出现在方法参数,那么它就是直接朋友,但是在方法体中,new了一个对象 Car,那么它就属于陌生人,因此要遵守迪米特法则,减少朋友的个数,不要和陌生人说话。

7.合成复原原则

  • 官方定义:

    合成/聚合复用原则是在一个新的对象里面使用一些已有的对象,使之成为新对象的一部分;新的对象通过向这些对象的委派达到复用已有功能的目的。
  • 自己理解:

    合成复用的意思是,如果你想要用一个对象里面的某个方法,比如我想要用A类的a方法,你有几种做法?
    (1)继承它,然后调用。
    (2)依赖它,然后调用。
    (3)聚合它,然后调用。
    (4)组合它,然后调用。

    合成复用原则强调在这种情况下,优先选择依赖,聚合,组合。 为什么?因为继承是有风险的,有可能破坏继承体系。造成维护困难。

四、结束语

学了java2年了,但是对面对对象的思想还不是很了解,以前只知道有这么个东西,现在学了设计模式,用得多了,才有足够得认识。例如继承,封装,多态,在设计模式中体现得淋漓尽致。接下来每学习一个设计模式,我都会连载一篇自己的理解。等学习完了后,对自己做过过得项目进行重构,坚信自己能坚持下去。

发布了1 篇原创文章 · 获赞 2 · 访问量 171

猜你喜欢

转载自blog.csdn.net/laowang__/article/details/104876177