六大设计原则

开闭原则
单一职责原则
里氏替换原则
依赖倒置原则
接口隔离原则
迪米特法则

开闭原则

OCP,open-closed principle,是面向对象设计中最基础的设计原则,它指导我们如何建立稳定灵活的系统,开闭原则只定义了对修改关闭,对扩展开放。
其实只要遵循下面5中设计模式,设计出来的软件就是符合开闭原则的。
开闭原则是目标,其他5个是实现方法。

类,方法可以扩展,不能修改。面对新需求,增加代码,不是修改代码。
关键就在于“抽象”。把系统的所有可能的行为抽象成一个抽象底层,要预见所有可能的扩展
参数类型、引用对象尽量使用接口或者抽象类,而不是实现类

里氏替换原则

继承有一些优点:
1.子类拥有父类的所有方法和属性,提高了代码的重用性。
2.还可以添加自己的功能,提高了代码的扩展性。

但又有点也同样存在缺点:
1.继承是侵入性的。只要继承,就必须拥有父类的所有属性和方法。
2.降低了代码的灵活性。因为继承时,父类会对子类有一种约束。
3.增强了耦合性。当需要对父类的代码进行修改时,必须考虑到对子类产生的影响。有时修改了一点点代码都有可能需要对打断程序进行重构。
如何扬长避短呢?方法是引入里氏替换原则

LSP,Liskov Substitution Principle
只要有父类出现的地方,都可以用子类来替代,而且不会出现任何错误和异常

约束主要体现在四个方面:
1.子类必须实现父类的抽象方法,但不得重写(覆盖)父类的非抽象(已实现)方法。

public class Test {

    public static void main(String[] args) {
        System.out.println("父类的运行结果");
        A a = new A();
        a.fun(1, 2);

        //父类存在的地方,可以用子类替代
        //子类B替代父类A
        System.out.println("子类替代父类后的运行结果");
        B b = new B();
        b.fun(1, 2);
    }

}

class A {
    public void fun(int a, int b) {
        System.out.println(a + "+" + b + "=" + (a + b));
    }
}

class B extends A {
    @Override
    public void fun(int a, int b) {
        System.out.println(a + "-" + b + "=" + (a - b));
    }
}

父类的运行结果
1+2=3
子类替代父类后的运行结果
1-2=-1
上面覆盖了父类的非抽象方法,出了问题,违反了里氏替换原则

2.子类中可以增加自己特有的方法。
3.当子类重载父类的非抽象方法时,方法的形参要比父类方法的形参更宽松,即是父类方法形参的父类或原来的类

public class Test {

    public static void main(String[] args) {
        System.out.println("父类的运行结果");
        A a = new A();
        HashMap<Object, Object> map = new HashMap<>();
        a.fun(map);

        //父类存在的地方,可以用子类替代
        //子类B替代父类A
        System.out.println("子类替代父类后的运行结果");
        B b = new B();
        b.fun(map);
    }

}

class A {
    public void fun(Map map) {
        System.out.println("父类被执行...");
    }
}

class B extends A {
    public void fun(HashMap map) {
        System.out.println("子类被执行...");
    }
}

父类的运行结果
父类被执行…
子类替代父类后的运行结果
子类被执行…

执行结果不一样,违反了里氏替换原则

4.当子类的方法实现父类的抽象方法时,即方法的返回值要比父类更严格,即是父类方法返回值的子类或原来的类
否则,编译就会报错
在这里插入图片描述
设计模式体现:策略模式,代理模式

依赖倒转原则

(Dependency Inversion Principle, DIP):抽象不应该依赖于细节,细节应当依赖于抽象。
换言之,要针对抽象(接口)编程,而不是针对实现细节编程

List list = new Vector();
变量的静态类型是List,真实类型是Vector

只要对象有抽象类型,任何地方都使用抽象类型

对象的创建,使用具体类型的构造函数,违背了开闭原则和依赖倒置原则
使用工厂模式,将这一违反原则的做法孤立到易于控制的地方

抽象类智能继承一个,接口可以实现多个。接口定义混合类型好
接口定义类型,抽象类提供默认实现,其实缺省默认模式,命名规范:Abstract+接口名

接口隔离原则

Interface Segregation Principle,ISP
使用多个专门的接口,比使用一个总接口好

包含三层含义:
一个类对另一个类的依赖应该建立在最小的接口上;
一个接口代表一个角色,不应该将不同的角色都交给一个接口,因为这样可能会形成一个臃肿的大接口;
不应该强迫客户依赖它们从来不用的方法。

迪米特法则

迪米特法则(Law of Demeter),英文简写为: LoD。
又叫作最少知识原则(Least Knowledge Principle 简写LKP),就是说一个对象应当对其他对象有尽可能少的了解,不和陌生人说话。英文

迪米特法则的初衷在于降低类之间的耦合。由于每个类尽量减少对其他类的依赖,因此,很容易使得系统的功能模块功能独立,相互之间不存在(或很少有)依赖关系。

迪米特法则不希望类之间建立直接的联系。如果真的有需要建立联系,也希望能通过它的友元类来转达。因此,应用迪米特法则有可能造成的一个后果就是:系统中存在大量的中介类,这些类之所以存在完全是为了传递类之间的相互调用关系——这在一定程度上增加了系统的复杂度。

有兴趣可以研究一下设计模式的门面模式(Facade)和中介模式(Mediator),都是迪米特法则应用的例子。

单一职能原则

single responsibilty principle, SRP

一个类应该有且只有一个变化的原因。
把职责定义为变化的原因。

当需求变化时,将通过更改职责相关的类来体现。如果一个类拥有多于一个的职责,则多个职责耦合在一起,会有多于一个原因来导致这个类发生变化。一个职责的变化可能会影响到其他的职责,另外,把多个职责耦合在一起,影响复用性。

单一职责原则的优点
(1)降低类的复杂度;
(2)提高类的可读性,提高系统的可维护性;
(3)降低变更引起的风险(降低对其他功能的影响)。

要求接口的职责单一,从而实现该接口的类的职责单一

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值