设计模式的六大原则
- 程序员应尽量遵守这六条软件设计原则,这六条原则可以帮助我们提高软件系统的可维护性和可复用性,增加软件的可拓展性和灵活性。
- 六大原则的英文首字母拼在一起是SOLID(稳定的),所以也称为SOLID原则
六大设计原则介绍
单一职责原则
一个类只负责一个功能领域中的相应职责,就一个类而言,应该只有一个引起它变化的原因
是实现高内聚,低耦合的指导方针。
- 高内聚:尽可能类的每一个成员方法只完成一件事(尽可能不代表必须),模块内部代码相互之间联系越强内聚就越高
- 低耦合:减少类内部,一个成员内部调用另外一个成员方法。
开闭原则
对扩展开放,对修改关闭。在程序需要进行扩展的时候,不能去修改原有代码,实现一个热插拔的效果
里氏替换原则
- 任何一个父类可以出现的地方,子类一定可以出现。
- 在程序中尽量使用父类类型来对对象进行定义,而在运行时再确定子类类型。用子类对象来替换父类对象
比如多态。
依赖倒转原则
- 高层模块不应该依赖低层模块,二者都应该依赖其抽象
- 针对于接口编程,依赖抽象而不应该依赖具体
下面举例可以很好的体现
public class DependencyInversion {
public static void main(String[] args) {
Person person = new Person();
person.receive(new Email());
}
}
class Email {
public String getInfo(){
return "电子邮件信息: hello,world";
}
}
/**
* 1.优点:调用方式简单
* 2.存在问题:如果我们获取的对象是 微信,短信等等,则新增类,同时 Person 也要增加相应的接收方法
* 3.解决方法:引入一个抽象的接口 IReceiver, 表示接收者, 这样 Person 类与接口 IReceiver 发生依赖
* 因为 Email, WeiXin 等等属于接收的范围,他们各自实现 IReceiver 接口, 这样我们就符号依赖倒转原则
*/
class Person {
//********这个依赖的的是email具体类
public void receive(Email email){
System.out.println(email.getInfo());
}
}
通过依赖倒转后
public class DependencyInversion {
public static void main(String[] args) {
Person person = new Person();
person.receive(new Email());
person.receive(new WX());
}
}
interface IReceive {
String getInfo();
}
class Email implements IReceive{
public String getInfo(){
return "电子邮件信息: hello,world";
}
}
//添加微信类
class WX implements IReceive{
public String getInfo(){
return "微信信息: hello,world";
}
}
class Person {
//********这个依赖的的是receive接口,针对于接口我们无限拓展
public void receive(IReceive iReceive){
System.out.println(iReceive.getInfo());
}
}
接口隔离原则
- 客户端不应该依赖那些不需要的接口
- 一个类对另一个类的依赖应该建立在最小的接口上
概括的说就是:建立单一接口,不要建立臃肿庞大的接口。(接口尽量细化,同时接口中的方法尽量少。
具体看代码
//接口
interface Interface1 {
void operation1();
void operation2();
void operation3();
void operation4();
void operation5();
}
class B implements Interface1 {
public void operation1() {
System.out.println("B 实现了 operation1");
}
public void operation2() {
System.out.println("B 实现了 operation2");
}
public void operation3() {
System.out.println("B 实现了 operation3");
}
public void operation4() {
System.out.println("B 实现了 operation4");
}
public void operation5() {
System.out.println("B 实现了 operation5");
}
}
//接口编程 A依赖Interface
class A { //A 类通过接口Interface1 依赖(使用) B类,但是只会用到1,2,3方法
public void depend1(Interface1 i) {
i.operation1();
}
public void depend2(Interface1 i) {
i.operation2();
}
public void depend3(Interface1 i) {
i.operation3();
}
}
//主方法
public static void main(String[] args) {
// TODO Auto-generated method stub
// 其实A只要用到接口类中1,2,3方法。但是因为接口庞大,导致实现类B必须实现4,5方法
A a = new A();
a.depend1(new B()); // A类通过接口去依赖B类
a.depend2(new B());
a.depend3(new B());
}
迪米特法则
- 最少知道原则,一个实体类应该尽量少的与其他实体类发生相互作用
- 类之间的耦合度越低,越有利于复用
- 通过引入一个合理的第三者来降低耦合度(例如引入中间件)
举例:
Boss想从TeamLeader那里知道现有课程的总数。它们之间的调用关系应该为Boss—>TeamLeader—>Course。Boss与Course并无直接联系,所以在Boss类的方法中不应该出现Course类。
设计模式简介
- 由来:是软件开发人员在软件开发过程中⾯临的一般问题的解决方案。这些解决方案是众多软件开发⼈员经过相当⻓长的⼀段时间的试验和错误总结出来的(是前辈们的经验)
- 好处:为了重⽤用代码、让代码更容易被他⼈理解、保证代码可靠性
- 坏处:对不熟悉设计模式的同学,看起来更绕更难理解(可能对新人来讲,明明两行代码可以解决的事情,前辈大佬写了一大堆)
常见的设计模式分类
- 创建型模式
- 将系统所需要的用到的具体类封装起来,在内部实现这些具体类的创建和结合,并对外隐藏这个过程细节。外部无法直接访问这个对象的创建和组合过程。使用者只需要关心何时、何地、由谁、怎样创建这个对象。
常用:工厂模式、抽象⼯厂模式、单例模式、建造者模式 不常用:原型模式
- 结构型模式
- 结构型模式描述如何将类或对象按某种布局组成更大的结构。它分为类结构型模式和对象结构型模式,前者采用继承机制来组织接口和类,后者釆用组合或聚合来组合对象。
常用:适配器模式、桥接模式、装饰器模式、代理模式 不常用:组合模式、外观模式、享元模式
- 行为型模式
- 行为型模式用于描述程序在运行时复杂的流程控制,即描述多个类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务,它涉及算法与对象间职责的分配。
常用:责任链模式、迭代器模式、观察者模式、状态模式、策略模式、模板模式 不常用:备忘录模式、命令模式 ⼏乎不用:访问者模式、中介者模式、解释器模式