参考文档
- 23种设计模式全解析 - codeTao - 博客园
- 设计模式(创建型) - 八一鱼 - 博客园
- 设计模式(结构型) - 八一鱼 - 博客园
- 代理模式和装饰者模式的区别 - 夜的第八章 - 博客园
- 简说设计模式——享元模式 - JAdam - 博客园
设计模式的分类
类模式处理类与子类的关系,通过处理这些关系来建立继承,属于静态关系,在编译时候确定下来;对象模式处理对象之间的关系,运行时发生变化,属于动态关系。
创建型模式
- 工厂方法模式
- 抽象工厂模式
- 单例模式
- 建造者模式
- 原型模式
结构型模式
- 适配器模式
- 装饰器模式
- 代理模式
- 外观模式
- 桥接模式
- 组合模式
- 享元模式
行为型模式
- 策略模式
- 模板方法模式
- 观察者模式
- 迭代器模式
- 责任链模式
- 命令模式
- 备忘录模式
- 状态模式
- 访问者模式
- 中介者模式
- 解释器模式
设计模式遵守的设计原则
也是类的设计遵守的原则
单一职责原则SRP
每个类只做一件事,但该原则也不适用于聚合类。
聚合类需要优先使用对象组合,而不是类继承
里氏替换原则LSP
- 子类的对象提供了父类的所有行为,且加上子类额外的一些东西(可以是功能,也可以是属性)
当程序基于父类实现时,如果将子类替换父类而程序不需要修改,则说明符合LSP原则
子类必须能替换成它们的父类
依赖倒置原则DIP
也叫依赖反转原则。
- 高层模块不应该直接依赖低层模块,两者都应该依赖抽象层。
- 抽象不能依赖细节,细节必须依赖抽象。
接口隔离原则ISP
客户端不应该被强迫去依赖它们并不需要的接口
不满足ISP的类应该拆分成多个接口, 通过一个抽象类去实现它们,再去继承这个抽象父类。
开闭原则
对拓展开放,对修改封闭
对使用者修改关闭,对提供者拓展开放
创建型模式解析
在软件工程中,创建型模式是处理对象创建的设计模式,试图根据实际情况使用合适的方式创建对象。基本的对象创建方式可能会导致设计上的问题,或增加设计的复杂度。创建型模式通过以某种方式控制对象的创建来解决问题。
工厂方法模式(类)

创建一个工厂接口和创建多个工厂实现类
抽象工厂模式(对象)

区别:
工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。
工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。
工厂方法创建 "一种" 产品,他的着重点在于"怎么创建",也就是说如果你开发,你的大量代码很可能围绕着这种产品的构造,初始化这些细节上面。也因为如此,类似的产品之间有很多可以复用的特征,所以会和模版方法相随。 抽象工厂需要创建一些列产品,着重点在于"创建哪些"产品上,也就是说,如果你开发,你的主要任务是划分不同差异的产品线,并且尽量保持每条产品线接口一致,从而可以从同一个抽象工厂继承。
抽象工厂模式包含如下角色:
- AbstractFactory:抽象工厂
-
ConcreteFactory:具体工厂
-
AbstractProduct:抽象产品
-
Product:具体产品
单例模式(对象)
在一个JVM中,该类只有一个对象实例存在。
public class Singleton {
/* 持有私有静态实例,防止被引用,此处赋值为null,目的是实现延迟加载 */
private static Singleton instance = null;
/* 私有构造方法,防止被实例化 */
private Singleton() {
}
/* 静态工程方法,创建实例 */
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
/* 如果该对象被用于序列化,可以保证对象在序列化前后保持一致 */
public Object readResolve() {
return instance;
}
}
多线程下的优化:
public class Singleton {
/* 私有构造方法,防止被实例化 */
private Singleton() {
}
/* 此处使用一个内部类来维护单例 */
private static class SingletonFactory {
private static Singleton instance = new Singleton();
}
/* 获取实例 */
public static Singleton getInstance() {
return SingletonFactory.instance;
}
/* 如果该对象被用于序列化,可以保证对象在序列化前后保持一致 */
public Object readResolve() {
return getInstance();
}
}
原理:
JVM内部的机制能够保证当一个类被加载的时候,这个类的加载过程是线程互斥的。这样当我们第一次调用getInstance的时候,JVM能够帮我们保证instance只被创建一次,并且会保证把赋值给instance的内存初始化完毕
建造者模式(对象)

在软件开发中,也存在大量类似汽车一样的复杂对象,它们拥有一系列成员属性,这些成员属性中有些是引用类型的成员对象。而且在这些复杂对象中,还可能存在一些限制条件,如某些属性没有赋值则复杂对象不能作为一个完整的产品使用;有些属性的赋值必须按照某个顺序,一个属性没有赋值之前,另一个属性可能无法赋值等。
建造者模式包含如下角色:
- Builder:抽象建造者
-
ConcreteBuilder:具体建造者
-
Director:指挥者
-
Product:产品角色
Director的作用:
- 隔离客户与生产过程。
- 负责控制产品的生成过程。
public class Meal {
private String food;
private String drink;
public String getFood() {
return food;
}
public void setFood(String food) {
this.food = food;
}
public String getDrink() {
return drink;
}
public void setDrink(String drink) {
this.drink = drink;
}
}
public abstract class MealBuilder {
Meal meal = new Meal();
public abstract void buildFood();
public abstract void buildDrink();
public Meal getMeal(){
return meal;
}
}
public class MealA extends MealBuilder{
public void buildDrink() {
meal.setDrink("可乐");
}
public void buildFood() {
meal.setFood("薯条");
}
}
public class KFCWaiter {
private MealBuilder mealBuilder;
public KFCWaiter(MealBuilder mealBuilder) {
this.mealBuilder = mealBuilder;
}
public Meal construct(){
//准备食物
mealBuilder.buildFood();
//准备饮料
mealBuilder.buildDrink();
//准备完毕,返回一个完整的套餐给客户
return mealBuilder.getMeal();
}
}
原型模式(对象)

有些对象是需要频繁创建的,用原型实例指定创建对象的类型,并且通过拷贝这个原型来创建新的同类型的对象,分为浅克隆和深克隆,浅克隆只复制拷贝的对象,不复制引用的对象,即成员对象不复制;深克隆,引用也同样复制。
public class Prototype implements Cloneable, Serializable {
private static final long serialVersionUID = 1L;
private String string;
private SerializableObject obj;
/* 浅复制 */
public Object clone() throws CloneNotSupportedException {
Prototype proto = (Prototype) super.clone(); /* super.clone()是浅复制 */
return proto;
}
/* 深复制 */
public Object deepClone() throws IOException, ClassNotFoundException {
/* 写入当前对象的二进制流 */
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(this);
/* 读出二进制流产生的新对象 */
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
return ois.readObject();
}
public String getString() {
return string;
}
public void setString(String string) {
this.string = string;
}
public SerializableObject getObj() {
return obj;
}
public void setObj(SerializableObject obj) {
this.obj = obj;
}
}
class SerializableObject implements Serializable {
private static final long serialVersionUID = 1L;
}
结构型模式解析
结构型模式主要用于处理类和对象的组合
适配器模式(类和对象)
将一个接口转换成客户希望的另一个接口,从而使接口不兼容的那些类可以在一起工作。
类的适配器模式
通过一个具体的类,将适配者适配到目标接口当中

public class Source {
public void method1() {
System.out.println("this is original method!");
}
}
public interface Targetable {
/* 与原类中的方法相同 */
public void method1();
/* 新类的方法 */
public void method2();
}
public class Adapter extends Source implements Targetable {
@Override
public void method2() {
System.out.println("this is the targetable method!");
}
}
public class AdapterTest {
public static void main(String[] args) {
Targetable target = new Adapter();
target.method1();
target.method2();
}
}
对象的适配器模式
一个适配器可以将多个不同的适配者适配到同一目标

public class Wrapper implements Targetable {
private Source source;
public Wrapper(Source source){
super();
this.source = source;
}
@Override
public void method2() {
System.out.println("this is the targetable method!");
}
@Override
public void method1() {
source.method1();
}
}
装饰者模式(对象)
给一个对象增加一些新的功能,而且是动态的,要求装饰对象和被装饰对象实现同一个接口,装饰对象持有被装饰对象的实例

//Sourceable
public interface Sourceable {
public void method();
}
//Source
public class Source implements Sourceable {
@Override
public void method() {
System.out.println("the original method!");
}
}
//Decorator
public class Decorator implements Sourceable {
private Sourceable source;
public Decorator(Sourceable source){
super();
this.source = source;
}
@Override
public void method() {
System.out.println("before decorator!");
source.method();
System.out.println("after decorator!");
}
}
代理模式(对象)
多一个代理类出来,替原对象进行一些操作

public interface Sourceable {
public void method();
}
public class Source implements Sourceable {
@Override
public void method() {
System.out.println("the original method!");
}
}
public class Proxy implements Sourceable {
private Source source;
public Proxy(){
super();
this.source = new Source();
}
@Override
public void method() {
before();
source.method();
atfer();
}
private void atfer() {
System.out.println("after proxy!");
}
private void before() {
System.out.println("before proxy!");
}
}
装饰者模式和代理模式的区别:
装饰器模式关注于在一个对象上动态的添加方法,然而代理模式关注于控制对对象的访问。换句话说,用代理模式,代理类(proxy class)可以对它的客户隐藏一个对象的具体信息。因此,当使用代理模式的时候,我们常常在一个代理类中创建一个对象的实例。并且,当我们使用装饰器模式的时候,我们通常的做法是将原始对象作为一个参数传给装饰者的构造器。
## 外观模式(对象)
定义一个高层接口,为子系统中的一组接口提供一个一致的外观,从而简化了该子系统的使用

外观模式包含如下角色:
- Facade: 外观角色
-
SubSystem:子系统角色
//CPU
public class CPU {
public void startup(){
System.out.println("cpu startup!");
}
public void shutdown(){
System.out.println("cpu shutdown!");
}
}
//Memory
public class Memory {
public void startup(){
System.out.println("memory startup!");
}
public void shutdown(){
System.out.println("memory shutdown!");
}
}
//Disk
public class Disk {
public void startup(){
System.out.println("disk startup!");
}
public void shutdown(){
System.out.println("disk shutdown!");
}
}
//Facade
public class Computer {
private CPU cpu;
private Memory memory;
private Disk disk;
public Computer(){
cpu = new CPU();
memory = new Memory();
disk = new Disk();
}
public void startup(){
System.out.println("start the computer!");
cpu.startup();
memory.startup();
disk.startup();
System.out.println("start computer finished!");
}
public void shutdown(){
System.out.println("begin to close the computer!");
cpu.shutdown();
memory.shutdown();
disk.shutdown();
System.out.println("computer closed!");
}
}
桥接模式(对象)
把事物和其具体实现分开,使他们可以各自独立的变化。
将抽象化与实现化解耦,使得二者可以独立变化

public interface Sourceable {
public void method();
}
public class SourceSub1 implements Sourceable {
@Override
public void method() {
System.out.println("this is the first sub!");
}
}
public class SourceSub2 implements Sourceable {
@Override
public void method() {
System.out.println("this is the second sub!");
}
}
public abstract class Bridge {
private Sourceable source;
public void method(){
source.method();
}
public Sourceable getSource() {
return source;
}
public void setSource(Sourceable source) {
this.source = source;
}
}
public class MyBridge extends Bridge {
public void method(){
getSource().method();
}
}

组合模式(对象)
将多个对象组合在一起进行操作,常用于表示树形结构中,例如二叉树,树等。

public class TreeNode {
private String name;
private TreeNode parent;
private Vector<TreeNode> children = new Vector<TreeNode>();
public TreeNode(String name){
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public TreeNode getParent() {
return parent;
}
public void setParent(TreeNode parent) {
this.parent = parent;
}
//添加孩子节点
public void add(TreeNode node){
children.add(node);
}
//删除孩子节点
public void remove(TreeNode node){
children.remove(node);
}
//取得孩子节点
public Enumeration<TreeNode> getChildren(){
return children.elements();
}
}
public class Tree {
TreeNode root = null;
public Tree(String name) {
root = new TreeNode(name);
}
public static void main(String[] args) {
Tree tree = new Tree("A");
TreeNode nodeB = new TreeNode("B");
TreeNode nodeC = new TreeNode("C");
nodeB.add(nodeC);
tree.root.add(nodeB);
System.out.println("build the tree finished!");
}
}
享元模式(对象)
实现对象的共享,即共享池,当系统中对象多的时候可以减少内存的开销,通常与工厂模式一起使用。

其中,Flyweight是抽象享元角色。它是产品的抽象类,同时定义出对象的外部状态和内部状态的接口或实现;ConcreteFlyweight是具体享元角色,是具体的产品类,实现抽象角色定义的业务;UnsharedConcreteFlyweight是不可共享的享元角色,一般不会出现在享元工厂中;FlyweightFactory是享元工厂,它用于构造一个池容器,同时提供从池中获得对象的方法。
public abstract class Flyweight {
//内部状态
public String intrinsic;
//外部状态
protected final String extrinsic;
//要求享元角色必须接受外部状态
public Flyweight(String extrinsic) {
this.extrinsic = extrinsic;
}
//定义业务操作
public abstract void operate(int extrinsic);
public String getIntrinsic() {
return intrinsic;
}
public void setIntrinsic(String intrinsic) {
this.intrinsic = intrinsic;
}
}
public class ConcreteFlyweight extends Flyweight {
//接受外部状态
public ConcreteFlyweight(String extrinsic) {
super(extrinsic);
}
//根据外部状态进行逻辑处理
@Override
public void operate(int extrinsic) {
System.out.println("具体Flyweight:" + extrinsic);
}
}
public class UnsharedConcreteFlyweight extends Flyweight {
public UnsharedConcreteFlyweight(String extrinsic) {
super(extrinsic);
}
@Override
public void operate(int extrinsic) {
System.out.println("不共享的具体Flyweight:" + extrinsic);
}
}
public class FlyweightFactory {
//定义一个池容器
private static HashMap<String, Flyweight> pool = new HashMap<>();
//享元工厂
public static Flyweight getFlyweight(String extrinsic) {
Flyweight flyweight = null;
if(pool.containsKey(extrinsic)) { //池中有该对象
flyweight = pool.get(extrinsic);
System.out.print("已有 " + extrinsic + " 直接从池中取---->");
} else {
//根据外部状态创建享元对象
flyweight = new ConcreteFlyweight(extrinsic);
//放入池中
pool.put(extrinsic, flyweight);
System.out.print("创建 " + extrinsic + " 并从池中取出---->");
}
return flyweight;
}
}
行为型模式解析
行为型模式主要用于描述类或对象的交互以及职责分配
解释器模式(类)
- 主要应用在OOP开发中的编译器的开发中
给定一种语言,定义它的文法表示,并定义一个解释器,该解释器用来根据文法表示来解释语言中的句子

模板方法模式(类)
定义一个操作中的算法骨架,而将一些步骤延迟到子类中,使得子类可以不改变一个算法的结构即可重新定义算法中某些特定步骤

策略模式(对象)
定义一系列算法,把它们一个个封装起来,并且使它们之间可相互替换,从而让算法可以独立于使用它的用户而变化

观察者模式(对象)
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动更新

public interface Observer {
public void update();
}
public class Observer1 implements Observer {
@Override
public void update() {
System.out.println("observer1 has received!");
}
}
public class Observer2 implements Observer {
@Override
public void update() {
System.out.println("observer2 has received!");
}
}
public interface Subject {
/*增加观察者*/
public void add(Observer observer);
/*删除观察者*/
public void del(Observer observer);
/*通知所有的观察者*/
public void notifyObservers();
/*自身的操作*/
public void operation();
}
public abstract class AbstractSubject implements Subject {
private Vector<Observer> vector = new Vector<Observer>();
@Override
public void add(Observer observer) {
vector.add(observer);
}
@Override
public void del(Observer observer) {
vector.remove(observer);
}
//提醒应当在抽象类中就实现
@Override
public void notifyObservers() {
Enumeration<Observer> enumo = vector.elements();
while(enumo.hasMoreElements()){
enumo.nextElement().update();
}
}
}
public class MySubject extends AbstractSubject {
@Override
public void operation() {
System.out.println("update self!");
notifyObservers();
}
}
迭代器模式(对象)
提供一种方法来顺序访问一个聚合对象中的各个元素,而不需要暴露该对象的内部表示。

责任链模式(对象)
有多个对象,每个对象持有对下一个对象的引用,这样就会形成一条链,请求在这条链上传递,直到某一对象决定处理该请求。但是发出者并不清楚到底最终那个对象会处理该请求

public interface Handler {
public void operator();
}
public abstract class AbstractHandler {
private Handler handler;
public Handler getHandler() {
return handler;
}
public void setHandler(Handler handler) {
this.handler = handler;
}
}
public class MyHandler extends AbstractHandler implements Handler {
private String name;
public MyHandler(String name) {
this.name = name;
}
@Override
public void operator() {
System.out.println(name+"deal!");
if(getHandler()!=null){
getHandler().operator();
}
}
}
命令模式(对象)
将一个请求封装为一个对象,从而可用不同的请求对客户进行参数化,将请求排队或记录请求日志,支持可撤销的操作

public interface Command {
public void exe();
}
public class MyCommand implements Command {
private Receiver receiver;
public MyCommand(Receiver receiver) {
this.receiver = receiver;
}
@Override
public void exe() {
receiver.action();
}
}
public class Receiver {
public void action(){
System.out.println("command received!");
}
}
public class Invoker {
private Command command;
public Invoker(Command command) {
this.command = command;
}
public void action(){
command.exe();
}
}
备忘录模式(对象)
在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,从而可以在以后将该对象恢复到原先保存的状态

public class Original {
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public Original(String value) {
this.value = value;
}
public Memento createMemento(){
return new Memento(value);
}
public void restoreMemento(Memento memento){
this.value = memento.getValue();
}
}
public class Memento {
private String value;
public Memento(String value) {
this.value = value;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
public class Storage {
private Memento memento;
public Storage(Memento memento) {
this.memento = memento;
}
public Memento getMemento() {
return memento;
}
public void setMemento(Memento memento) {
this.memento = memento;
}
}
状态模式(对象)
允许一个对象在其内部状态改变时能够改变它的行为

public class State {
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public void method1(){
System.out.println("execute the first opt!");
}
public void method2(){
System.out.println("execute the second opt!");
}
}
public class Context {
private State state;
public Context(State state) {
this.state = state;
}
public State getState() {
return state;
}
public void setState(State state) {
this.state = state;
}
public void method() {
if (state.getValue().equals("state1")) {
state.method1();
} else if (state.getValue().equals("state2")) {
state.method2();
}
}
}
访问者模式(对象)
表示一个作用于某对象结构中的各元素的操作,使得在不改变各元素的类的前提下定义作用于这些元素的新操作
适用于:给一个类添加新功能,但为了兼容性考虑或其他原因不想破坏这个类

public interface Visitor {
public void visit(Subject sub);
}
public class MyVisitor implements Visitor {
@Override
public void visit(Subject sub) {
System.out.println("visit the subject:"+sub.getSubject());
}
}
public interface Subject {
public void accept(Visitor visitor);
public String getSubject();
}
public class MySubject implements Subject {
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
@Override
public String getSubject() {
return "love";
}
}
中介者模式(对象)
用一个中介对象来封装一系列的对象交互。它使各对象不需要显示地相互调用,从而达到低耦合,还可以独立地改变对象间的交互

public interface Mediator {
public void createMediator();
public void workAll();
}
public class MyMediator implements Mediator {
private User user1;
private User user2;
public User getUser1() {
return user1;
}
public User getUser2() {
return user2;
}
@Override
public void createMediator() {
user1 = new User1(this);
user2 = new User2(this);
}
@Override
public void workAll() {
user1.work();
user2.work();
}
}
public abstract class User {
private Mediator mediator;
public Mediator getMediator(){
return mediator;
}
public User(Mediator mediator) {
this.mediator = mediator;
}
public abstract void work();
}
public class User1 extends User {
public User1(Mediator mediator){
super(mediator);
}
@Override
public void work() {
System.out.println("user1 exe!");
}
}
public class User2 extends User {
public User2(Mediator mediator){
super(mediator);
}
@Override
public void work() {
System.out.println("user2 exe!");
}
}
public class Test {
public static void main(String[] args) {
Mediator mediator = new MyMediator();
mediator.createMediator();
mediator.workAll();
}
}
原创文章,作者:彭晨涛,如若转载,请注明出处:https://www.codetool.top/article/23%e7%a7%8d%e8%ae%be%e8%ae%a1%e6%a8%a1%e5%bc%8f%e5%bd%92%e7%ba%b3/