Java 中一般认为有23 种设计模式,我们不需要所有的都会,但是其中常用的几种设计模式应该去掌握。
下面列出了所有的设计模式。需要掌握的设计模式我单独列出来了,当然能掌握的越多越好。
总体来说设计模式分为三大类:
创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。
总结:每一种设计模式,代码去理解实现方式,根据结构图记忆理解。本文部分没有给出具体代码,结合代码更容易理解,可以在码云下载代码使用,本文适合有一定的理解之后翻看
码云代码:https://gitee.com/huopusa/arithmetic.git
一、 工厂方法模式 和 抽象工厂模式 :
主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的,定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类当创建一个具体的对象而又不希望指定具体的类时可以使用工厂模式
1、工厂模式可以分为三类:
1)简单工厂模式(Simple Factory)
2)工厂方法模式(Factory Method)
3)抽象工厂模式(Abstract Factory)
2、区别
工厂方法模式:
一个抽象产品类,可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类只能创建一个具体产品类的实例。
抽象工厂模式:
多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类可以创建多个具体产品类的实例。
区别:
工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。
工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。
3、工厂方法模式的优点:
工厂方法模式与抽象工厂模式对比:
(1)良好的封装性,代码结构清晰。一个对象创建是有条件约束的,如一个调用者需要一个具体的产品对象,只要知道这个产品的类名(或约束字符串)就可以了,不用知道创建对象的艰辛过程,降低模块间的耦合。
(2)工厂方法模式的扩展性非常优秀。在增加产品类的情况下,只要适当地修改具体的工厂类或扩展一个工厂类,就可以完成“拥抱变化”。
(3)屏蔽产品类。这一特点非常重要,产品类的实现如何变化,调用者都不需要关心,它只需要关心产品的接口,只要接口保持不变,系统中的上层模块就不要发生变化。因为产品类的实例化工作是由工厂类负责的,一个产品对象抽象工厂模式的优缺点:
● 封装性。
每个产品的实现类不是高层模块要关心的,它要关心的是什么?是接口,是抽象,它不关心对象是如何创建出来,这由谁负责呢?工厂类,只要知道工厂类是谁,我就能创建出一个需要的对象,省时省力,优秀设计就应该如此。
● 产品族内的约束为非公开状态。
缺点: 抽象工厂模式的最大缺点就是产品族扩展非常困难,为什么这么说呢?我们以通用代码为例,如果要增加一个产品C,也就是说产品家族由原来的2个增加到3个,看看我们的程序有多大改动吧!抽象类AbstractCreator要增加一个方法createProductC(),然后两个实现类都要修改,想想看,这严重违反了开闭原则,而且我们一直说明抽象类和接口是一个契约。改变契约,所有与契约有关系的代码都要修改,那么这段代码叫什么?叫“有毒代码”,——只要与这段代码有关系,就可能产生侵害的危险!
工厂方法模式 抽象工厂模式
针对的是一个产品等级结构 针对的是面向多个产品等级结构
一个抽象产品类 多个抽象产品类
可以派生出多个具体产品类 每个抽象产品类可以派生出多个具体产品类
一个抽象工厂类,可以派生出多个具体工厂类 一个抽象工厂类,可以派生出多个具体工厂类每个具体工厂类只能创建一个具体产品类的实例 每个具体工厂类可以创建多个具体产品类的实例
三、单例模式
https://blog.youkuaiyun.com/weixin_39076716/article/details/80095307
四、建造者模式 Builder
是什么:
建造者模式:是将一个复杂的对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
工厂类模式提供的是创建单个类的模式,而建造者模式则是将各种产品集中起来进行管理,用来创建复合对象,所谓复合对象就是指某个类具有不同的属性,其实建造者模式就是前面抽象工厂模式和最后的Test结合起来得到的。
结构模型
- 建造者模式 通常包括下几个角色:
- builder(抽象建造者):给出一个抽象结论,以规范产品对象的各个组成成分的建造。这个接口规定要实现复杂对象的那些部分的创建,并不涉及具体的对象部件的创建。
- ConcreteBuilder(具体建造者):实现Builder接口,针对不同的商业逻辑,具体化复杂对象的各部分的创建。在构造过程完成后,提供产品的实例。
- Director(指导者):调用具体建造者来创建复杂对象的各个部分,在指导者中不涉及具体产品的信息,只负责保证对象各部分完整创建或按某种顺序创建。
- Product(产品类):要创建的复杂对象。
适用场景
- 需要生产的产品对象有复杂的内部结构。 需要生产的产品对象的属性相互依赖,建造者模式可以强迫生成顺序。
在对象创建过程中会使用到系统中的一些其它对象,这些对象在产品对象的创建过程中不易得到。
优点
- 使用建造者模式可以使客户端不必知道产品内部的组成细节。(封装性) 具体的建造者之间是相互独立的,对系统的扩展非常有利。(扩展性)
由于具体的建造者是独立的,因此可以对建造过程逐步细化,而不对其他模块产生任何影响
与抽象工厂的区别:
- 在建造者模式里,有个指导者,由指导者来管理建造者,用户是与指导者联系的,指导者联系建造者最后得到产品。即建造模式可以强制实行一种分步骤进行的构造过程。工厂模式是将对象的全部创建过程封装在工厂类中,由工厂类想客户端提供最终的产品。而在建造者模式中,建造者类一般只提供产品类中各个组件的建造,而将具体建造过程交付给指导者,由指导者负责将各个组件按照特定的规则组建为产品,然后将组建好的产品交付给客户端
代码
1. builder(抽象建造者)
/**
* 建造者模式-抽象建造者
*/
public interface ICarBuilder {
void buildWheel();
void buildSkeleton();
void buildEngine();
Car buildCar();
}
2. ConcreteBuilder(具体建造者)
/**
* 建造者模式-具体建造者
*/
public class ConcreteBuilder implements ICarBuilder {
Car car;
public ConcreteBuilder(Car car) {
this.car = car;
}
@Override
public void buildWheel() {
car.setWheel("轮子");
}
@Override
public void buildSkeleton() {
car.setSkeleton("车身结构");
}
@Override
public void buildEngine() {
car.setEngine("发动机");
}
@Override
public Car buildCar() {
return this.car;
}
}
3. Director(指导者)
/**
* 建造者模式-指导者
*/
public class CarDirector {
public Car constructCar(ICarBuilder builder){
builder.buildEngine();
builder.buildSkeleton();
builder.buildWheel();
return builder.buildCar();
}
}
4. Product(产品类)
/**
* 建造者模式-产品类
*/
public class Car {
private String wheel;
private String skeleton; //骨架
private String engine;
// 省略get和set方法
}
5、测试类
/**
* 测试代码
*/
public class MainTest {
public static void main(String[] args) {
// 建造一个指导者
CarDirector director = new CarDirector();
Car car = director.constructCar(new ConcreteBuilder(new Car()));
System.out.println(car.getWheel());
System.out.println(car.getEngine());
System.out.println(car.getSkeleton());
}
}
转自:https://blog.youkuaiyun.com/u013256816/article/details/50978024
五、原型模式 Prototype
- 原型模式:原型模式就是从一个对象再创建另外一个可定制的对象,而且不需要知道任何创建的细节。
- 使用场景:原型模式适用场景:如果某个对象new的过程中很耗时,则可以考虑使用原型模式。
- 使用方式:需要实现Cloneable接口
UML类图
这种模式比较简单,未写代码,参考一下博文
https://www.cnblogs.com/cxxjohnson/p/6403949.html
小结:后续会更新 结构型模式和行为型模式,熟练这些模式会对看代码和写代码有一个比较高的提高,关键是可以拿来应付面试