设计模式六大原则
1、单一职责原则(Single Responsibility Principle)
定义 : 应该有且只有一个原因引起类的变化
注意 : 这里的类不光指类,也适用于方法和接口,比如我们常说的一个方法实现一个功能
2、里氏代换原则(Liskov Substitution Principle)
定义 : 只要父类出现的地方子类就一定可以出现,而且替换为子类也不会出现任何异常或错误,使用者不需要知道是父类还是子类.但是返回来就不行了,有子类出现的地方,不一定能使用父类
使用规范 :子类必须完全实现父类的方法,如果子类无法完全实现父类的方法,则建议断开父子继承关系,采用依赖 聚集 | 组合 等关系来代替。
子类可以有自己的个性,覆盖或实现父类的方法时,输入参数可以被放大,比如父类中有一个方法的输入参数是 HashMap,子类的参数可以是 Map 类型,这样父类就可以被子类替换,如果反过来,则违背了里氏替换原则,所以子类中方法的前置条件必须与父类的被覆写的方法的前置条件相同或者更宽松
覆写或实现父类的方法时,输出结果可以被缩小,也就是说如果父类方法返回的类型 T,子类的相同方法
(重载或覆写)的返回值类型 S,S 和 T 要么同类型,要么 S 是 T 的子类;跟上面的道理一样
注意 : 采用里氏替换原则时,尽量避免子类的"个性",一旦子类有了"个性",子类和父类的关系就会变得不好调和
3、依赖倒置原则(Dependence Inversion Principle)
定义 : 依赖倒置原则包含三个含义
- 高层模块不应该依赖低层模块,两者都应该依赖其抽象
- 抽象不应该依赖细节
- 细节应该依赖抽象
高层模块和低层模块比较好理解,每一个逻辑都是由原子逻辑组成的,不可分割的原子逻辑是低层模块,原子逻辑再组装就是高层模块;
抽象指的是接口或者抽象类,两者都不能直接实例化;
细节就是实现类,实现接口或继承抽象类而产生的类就是细节,其特点是可以被实例化;
依赖倒置原则在 Java 中的实现是表现是:
模块间的依赖通过抽象发生,实现类之间不发生直接的依赖关系,其依赖关系是通过接口或抽象类产生
的;
接口或抽象类不依赖于实现类实现类依赖接口或抽象类。这也是面向接口编程的精髓之一
遵循的规则 :
- 每个类尽量都有接口或抽象类,或者两者都有
- 变量的表面类型尽量是接口或者抽象类
- 任何类都不应该从具体类派生
- 尽量不要覆写基类的方法,如果基类是一个抽象类,而且这个方法已经实现了,子类尽量不要覆写
结合里氏替换原则使用
接口负责定义 public 属性和方法,并且声明与其他对象的依赖关系,抽象类负责公共构造部分的实现,实
现类准确的实现业务逻辑
4、接口隔离原则(Interface Segregation Principle)
我们先来看接口的定义 :
实例接口 : 在 Java 中声明一个类,然后用 new 关键字产生一个实例,它是对一类事物的描述,可以看成是一个接口
类接口 : 使用 interface 定义的接口
隔离的的理解 :
客户端不应该依赖它不需要的接口
类之间的依赖关系应该建立在最小的接口上
概括 : 建立单一接口,不要建立臃肿庞大的接口,也就是接口尽量细化,接口中的方法尽量少,这个是开闭原则的基础,具体内容:针对接口编程,依赖于抽象而不依赖于具体。
接口隔离原则的约束条件 :接口要高内聚,意思就是提高接口,类,模块的处理能力,减少对外的交互,再具体一点就是在接口中尽量减少对外的 public 方法,通过业务逻辑压缩接口中的 public 方法,定制服务,就是单独为一个个体提供优良的服务,比如我们写用户模块的时候,需要给用户提供查询信息,
修改密码,注册用户等信息,当管理员执行相同操作的时候,一般人会复用这些方法,
然后在这个的基础上再增加管理员自己的方法,这种设计方法肯定是有问题的,这样设计,当你修改了普通用户调用的接口实现时,管理员的实现也会发生不可预测的改变,我们应该为管理员单独写一个接口
接口设计是有限度的,接口的设计粒度越小,系统越灵活,这是肯定的,但灵活的同时带来的问题是 结构
复杂化,开发难度增加, 可维护性降低
一个接口只服务于一个子模块或业务逻辑
已经被污染了的接口,尽量去修改 ,若修改的风险较大,则采用适配器模式进行转化处理
了解环境,拒绝盲从,不要一味的去套设计模式,有的时候不用比用了更好,也不要去照搬别人的设计方
法,他的方法到你这不一定效果就好,毕竟业务逻辑不一样
5、迪米特法则(Demeter Principle)
定义 : 迪米特法则也叫最少知识原则,含义是 一个对象应该对其他对象有最少的了解,这个应该很好理解,就是降低各模块之间的耦合
6、开闭原则(Open Close Principle)
定义 : 一个软件实体如类,模块和函数应该对扩展开放,对修改关闭,开闭原则也是其他五个原则的基石
总结
- 单一职责原则告诉我们实现类要职责单一;
- 里氏替换原则告诉我们不要破坏继承关系;
- 依赖倒置原则告诉我们要面向接口编程;
- 接口隔离原则告诉我们在设计接口的时候要精简单一;
- 迪米特法则告诉我们要降低耦合
- 开闭原则告诉我们要对扩展开发,对修改关闭;
对这六个原则的遵守并不是是和否的问题,而是多和少的问题,也就是说,我们一般不会说有没有遵守,而是说遵守程度达到多少,任何事过犹不及,设计模式六个设计原则也是一样,制定这六个原则并不是一味的要求我们去遵守他们,而是根据实际情况灵活运用,
单例模式
单例模式可以分为懒汉式和饿汉式:
- 懒汉式单例模式:在类加载时不初始化。
- 饿汉式单例模式:在类加载时就完成了初始化,所以类加载比较慢,但获取对象的速度快。
第一种(懒汉,线程不安全):
public class SingletonDemo1 {
private static SingletonDemo1 instance;
private SingletonDemo1(){}
public static SingletonDemo1 getInstance(){
if (instance == null) {
instance = new SingletonDemo1();
}
return instance;
}
}
这种写法lazy loading很明显,但是致命的是在多线程不能正常工作。
第二种(懒汉,线程安全):
public class SingletonDemo2 {
private static Sing