23种设计模式之Java实现

单例模式之饿汉式

class SingletonDemo1 {
    private static SingletonDemo1 instance = new SingletonDemo1() ;     //类初始化时,立即加载,天然线程安全

    private SingletonDemo1() {}     //私有化构造器

    public static SingletonDemo1 getInstance() {    //不需要同步,调用效率高
        return instance ;
    }
}

单例模式之懒汉式

class SingletonDemo2 {
    private static SingletonDemo2 instance = null ;     //类初始化时,不初始化这个对象,延迟加载,真正用的时候再创建

    private SingletonDemo2() {}     //私有化构造器

    public static synchronized SingletonDemo2 getInstance() {    //需要同步,调用效率低
        if(instance == null) {
            instance = new SingletonDemo2() ;
        }

        return instance ;
    }
}

单例模式之静态内部类实现

class SingletonDemo3 {
    //外部类初始化时,不会初始化这个静态类,延迟加载,真正用的时候再创建
    private static class SingletonClassInstance {
        //类初始化时,立即加载,天然线程安全
        private static final SingletonDemo3 instance = new SingletonDemo3() ;
    }

    private SingletonDemo3() {}     //私有化构造器

    //不需要同步,调用效率高
    public static SingletonDemo3 getInstance() {
        return SingletonClassInstance.instance ;
    }
}

单例模式之枚举实现

enum SingletonDemo4 {
    //枚举元素本身就是单例对象,由JVM保证,避免通过反射和反序列化的漏洞,但是不能延迟加载
    INSTANCE ;

    //根据需要,添加额外的操作
    public void singletonOperation() {

    }
}

单例模式总结:不需要延迟加载,枚举的方式好于饿汉式;需要延迟加载,静态内部类的方式好于懒汉式。
但是以上实现方式,除了 枚举 的方式外,其余都可以通过 反射反序列化 的方式破解。测试代码如下:

package JavaDesignPattern;

import java.io.*;
import java.lang.reflect.Constructor;

public class SingletonDemo {
    public static void main(String[] args) throws Exception {
        SingletonDemo1 s1 = SingletonDemo1.getInstance() ;
        SingletonDemo1 s2 = SingletonDemo1.getInstance() ;
        System.out.println(s1) ;
        System.out.println(s2) ;

        Class<SingletonDemo1> clazz = (Class<SingletonDemo1>)Class.forName("JavaDesignPattern.SingletonDemo1") ;
        Constructor<SingletonDemo1> c = clazz.getDeclaredConstructor(null) ;
        c.setAccessible(true) ;
        SingletonDemo1 s3 = c.newInstance() ;
        SingletonDemo1 s4 = c.newInstance() ;
        System.out.println(s3) ;
        System.out.println(s4) ;

        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("a.txt")) ;
        oos.writeObject(s1) ;
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("a.txt")) ;
        SingletonDemo1 s5 = (SingletonDemo1) ois.readObject() ;
        System.out.println(s5) ;
    }
}

输出如下:

JavaDesignPattern.SingletonDemo1@56de9984
JavaDesignPattern.SingletonDemo1@56de9984
JavaDesignPattern.SingletonDemo1@3030d5aa
JavaDesignPattern.SingletonDemo1@561ba49d
JavaDesignPattern.SingletonDemo1@29e0969b

那么问题来了,如何避免通过 反射反序列化 的方式破解呢?解决方法如下:

class SingletonDemo1 implements Serializable{
    private static SingletonDemo1 instance = new SingletonDemo1() ;     //类初始化时,立即加载,天然线程安全


    private SingletonDemo1() {     //私有化构造器
        if(instance != null) {      //阻止反射
            throw new RuntimeException() ;
        }
    }

    public static SingletonDemo1 getInstance() {    //不需要同步,调用效率高
        return instance ;
    }

    //反序列化时,如果定义了readResolve(),则直接返回此方法指定的对象,而不是单独创建新对象。
    private Object readResolve() throws ObjectStreamException {
        return instance ;
    }
}

简单工厂模式(静态工厂模式)

interface Car{
    void run() ;
}

class Audi implements Car {
    @Override
    public void run() {
        System.out.println("奥迪!") ;
    }
}

class Byd implements Car {
    @Override
    public void run() {
        System.out.println("比亚迪~~") ;
    }
}

class CarFactory1{
    public static Car createCar(String type) {
        if(type.equals("奥迪")) {
            return new Audi() ;
        }else if(type.equals("比亚迪")) {
            return new Byd() ;
        }else {
            return null ;
        }
    }
}

工厂方法模式

interface Car{
    void run() ;
}

class Audi implements Car {
    @Override
    public void run() {
        System.out.println("奥迪!") ;
    }
}

class Byd implements Car {
    @Override
    public void run() {
        System.out.println("比亚迪~~") ;
    }
}

interface CarFactory2{
    Car createCar() ;
}

class AudiFactory implements CarFactory2 {
    @Override
    public Car createCar() {
        return new Audi() ;
    }
}

class BydFactory implements CarFactory2 {
    @Override
    public Car createCar() {
        return new Byd() ;
    }
}

抽象工厂模式

interface Motor {
    void run() ;
    void start() ;
}

class LuxuruMotor implements Motor {
    @Override
    public void run() {
        System.out.println("做功快!") ;
    }

    @Override
    public void start() {
        System.out.println("启动快,可以自动启停!") ;
    }
}

class LowMotor implements Motor {
    @Override
    public void run() {
        System.out.println("做功慢!") ;
    }

    @Override
    public void start() {
        System.out.println("启动慢!") ;
    }
}


interface Seat{
    void massage() ;
}

class LuxurySeat implements Seat {
    @Override
    public void massage() {
        System.out.println("符合人体工程学,自动按摩!") ;
    }
}

class LowSeat implements Seat {
    @Override
    public void massage() {
        System.out.println("符合人体工程学,但不能自动按摩!") ;
    }
}


interface Tyre{
    void roll() ;
}

class LuxuryTyre implements Tyre {
    @Override
    public void roll() {
        System.out.println("耐磨!") ;
    }
}

class LowTyre implements Tyre {
    @Override
    public void roll() {
        System.out.println("容易磨损!") ;
    }
}


interface CarFactory3 {
    Motor createMotor () ;
    Seat createSeat() ;
    Tyre createTyre() ;
}

class LuxuryCarFactory implements CarFactory3 {
    @Override
    public Motor createMotor() {
        return new LuxuruMotor() ;
    }

    @Override
    public Seat createSeat() {
        return new LuxurySeat() ;
    }

    @Override
    public Tyre createTyre() {
        return new LuxuryTyre() ;
    }
}

class LowCarFactory implements CarFactory3 {
    @Override
    public Motor createMotor() {
        return new LowMotor() ;
    }

    @Override
    public Seat createSeat() {
        return new LowSeat() ;
    }

    @Override
    public Tyre createTyre() {
        return new LowTyre() ;
    }
}

测试代码如下:

package JavaDesignPattern;

public class Factory {
    public static void main(String[] args) {
        Car c1 = CarFactory1.createCar("奥迪") ;
        Car c2 = CarFactory1.createCar("比亚迪") ;

        c1.run() ;
        c2.run() ;

        Car c3 = new AudiFactory().createCar() ;
        Car c4 = new BydFactory().createCar() ;
        c3.run() ;
        c4.run() ;

        Motor e = new LuxuryCarFactory().createMotor() ;
        e.run() ;
        e.start() ;
        Seat s = new LuxuryCarFactory().createSeat() ;
        s.massage() ;
        Tyre t = new LuxuryCarFactory().createTyre() ;
        t.roll() ;
    }
}

工厂模式总结:
- 简单工厂模式又叫静态工厂模式,就是工厂类一般使用静态方法,通过接受参数的不同来返回不同的对象实例。对于新产品的增加,如果不修改已有源代码的话,是无法扩展的。虽然这违反了开闭原则(OCP),但是实际使用最多。
- 工厂方法模式:不修改已有类的前提下,通过增加新的工厂类实现扩展。
- 抽象工厂模式:不可以增加产品,只可以增加产品族。

建造者模式

class OrbitalModule {
    private String name ;

    public OrbitalModule(String name) {
        this.name = name ;
    }

    public String getName() {
        return name ;
    }

    public void setName(String name) {
        this.name = name ;
    }
}

class Engine {
    private String name ;

    public Engine(String name) {
        this.name = name ;
    }

    public String getName() {
        return name ;
    }

    public void setName(String name) {
        this.name = name ;
    }
}

class EscapeTower {
    private String name ;

    public EscapeTower(String name) {
        this.name = name ;
    }

    public String getName() {
        return name ;
    }

    public void setName(String name) {
        this.name = name ;
    }
}

class AirShip {
    private OrbitalModule orbitalModule ;
    private Engine engine ;
    private EscapeTower escapeTower ;

    public void launch() {
        System.out.println("点火发射!") ;
    }

    public OrbitalModule getOrbitalModule() {
        return orbitalModule ;
    }

    public void setOrbitalModule(OrbitalModule orbitalModule) {
        this.orbitalModule = orbitalModule ;
    }

    public Engine getEngine() {
        return engine ;
    }

    public void setEngine(Engine engine) {
        this.engine = engine ;
    }

    public EscapeTower getEscapeTower() {
        return escapeTower ;
    }

    public void setEscapeTower(EscapeTower escapeTower) {
        this.escapeTower = escapeTower ;
    }
}

interface AirShipBuilder {
    OrbitalModule buildOrbitalModule() ;
    Engine buildEngine() ;
    EscapeTower buildEscapeTower() ;
}

class NASAAirShipBuilder implements AirShipBuilder {
    @Override
    public OrbitalModule buildOrbitalModule() {
        System.out.println("NASA轨道舱") ;
        return new OrbitalModule("NASA轨道舱");
    }

    @Override
    public Engine buildEngine() {
        System.out.println("NASA引擎") ;
        return new Engine("NASA引擎");
    }

    @Override
    public EscapeTower buildEscapeTower() {
        System.out.println("NASA逃逸塔") ;
        return new EscapeTower("NASA逃逸塔") ;
    }
}


interface AirShipDirector {
    AirShip directAirShip() ;
}

class NASAAirShipDirector implements AirShipDirector {

    private AirShipBuilder builder ;

    public NASAAirShipDirector(AirShipBuilder builder) {
        this.builder = builder;
    }

    @Override
    public AirShip directAirShip() {
        AirShip ship = new AirShip() ;
        ship.setOrbitalModule(builder.buildOrbitalModule()) ;
        ship.setEngine(builder.buildEngine()) ;
        ship.setEscapeTower(builder.buildEscapeTower()) ;

        return ship ;
    }
}

测试代码如下:

package JavaDesignPattern;

public class Builder {
    public static void main(String[] args) {
        AirShip ship = new NASAAirShipDirector(new NASAAirShipBuilder()).directAirShip() ;
        System.out.println(ship.getEngine().getName()) ;
        ship.launch() ;
    }
}

建造者模式总结:实现了构建和装配的解耦。应用场景:某些对象的构建过程非常复杂。

原型模式

class Sheep implements Cloneable, Serializable{
    private Date birthday ;
    private String sname ;

    public Sheep() {}

    public Sheep(Date birthday, String sname) {
        this.birthday = birthday;
        this.sname = sname;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public String getSname() {
        return sname;
    }

    public void setSname(String sname) {
        this.sname = sname;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        Object obj = super.clone() ;  //浅复制
        return obj ;
    }
}

测试代码如下:

package JavaDesignPattern;

import java.io.Serializable;
import java.util.Date;

public class ProtoType {
    public static void main(String[] args) throws Exception {
        Date d  = new Date(1490758473000L) ;
        Sheep s1 = new Sheep(d, "多莉") ;
        Sheep s2 = (Sheep) s1.clone() ;
        System.out.println(s1.getSname()) ;
        System.out.println(s1.getBirthday()) ;
        System.out.println(s1) ;
        d.setTime(1490759999000L) ;
        System.out.println(s1.getBirthday()) ;

        System.out.println(s2.getSname()) ;
        System.out.println(s2.getBirthday()) ;
        System.out.println(s2) ;
    }
}

输出如下:

多莉
Wed Mar 29 11:34:33 CST 2017
JavaDesignPattern.Sheep@633835b4
Wed Mar 29 11:59:59 CST 2017
多莉
Wed Mar 29 11:59:59 CST 2017
JavaDesignPattern.Sheep@7f4def4f

不难发现,虽然s2是s1的克隆对象,但是它们共用了一个Date对象,这就是所谓的“浅克隆”。那么如何实现“深克隆”呢?只需要将复写的clone()方法略微修改一下即可。

    @Override
    protected Object clone() throws CloneNotSupportedException {
        Object obj = super.clone() ;  //浅复制

        Sheep s = (Sheep) obj ;
        s.birthday = (Date) this.birthday.clone();  //深复制

        return obj ;
    }

再次输出如下:

多莉
Wed Mar 29 11:34:33 CST 2017
JavaDesignPattern.Sheep@1c4600f0
Wed Mar 29 11:59:59 CST 2017
多莉
Wed Mar 29 11:34:33 CST 2017
JavaDesignPattern.Sheep@37e79b10

很显然,成功实现了“深克隆”。

详解Java中的clone方法 – 原型模式

此外,还可以通过序列化、反序列化的方式实现“深克隆”。测试代码如下:

package JavaDesignPattern;

import java.io.*;
import java.util.Date;

public class ProtoType {
    public static void main(String[] args) throws Exception {
        Date d  = new Date(1490758473000L) ;
        Sheep s1 = new Sheep(d, "多莉") ;
        //Sheep s2 = (Sheep) s1.clone() ;
        System.out.println(s1.getSname()) ;
        System.out.println(s1.getBirthday()) ;
        System.out.println(s1) ;

        ByteArrayOutputStream baos = new ByteArrayOutputStream() ;
        ObjectOutputStream oos = new ObjectOutputStream(baos) ;
        oos.writeObject(s1) ;
        byte[] bytes = baos.toByteArray() ; //序列化为一个数组

        ByteArrayInputStream bais = new ByteArrayInputStream(bytes) ;
        ObjectInputStream ois = new ObjectInputStream(bais) ;
        Sheep s2 = (Sheep) ois.readObject();    //反序列化

        d.setTime(1490759999000L) ;
        System.out.println(s1.getBirthday()) ;

        System.out.println(s2.getSname()) ;
        System.out.println(s2.getBirthday()) ;
        System.out.println(s2) ;
    }
}

输出如下:

多莉
Wed Mar 29 11:34:33 CST 2017
JavaDesignPattern.Sheep@559a6cd4
Wed Mar 29 11:59:59 CST 2017
多莉
Wed Mar 29 11:34:33 CST 2017
JavaDesignPattern.Sheep@5b611c24

从结果来看,成功实现了“深克隆”。

原型模式总结:通过new产生一个对象需要非常繁琐的数据准备或访问权限,则可以使用原型模式。原型模式很少单独出现,一般和工厂方法模式一起出现,通过clone的方法创建一个对象,然后由工厂方法提供给调用者。

=====================================================================

至此,创建型模式完结。单例模式、工厂模式、建造者模式、原型模式都属于创建型模式——关注对象的创建过程。

=====================================================================

适配器模式

//被改造者
class Adaptee {
    public void request() {
        System.out.println("可以完成客户需要的功能") ;
    }
}

interface Target {
    void handleRequest() ;
}

//对象适配器,采用组合的方式来处理
class MyAdapter implements Target {

    private Adaptee adaptee ;

    public MyAdapter(Adaptee adaptee) {
        this.adaptee = adaptee;
    }

    @Override
    public void handleRequest() {
        adaptee.request() ;
    }
}

测试代码如下:

package JavaDesignPattern;

public class Adapter {
    public static void main(String[] args) {
        Adaptee a = new Adaptee() ;
        Target t = new MyAdapter(a) ;
        t.handleRequest() ;
    }
}

适配器模式总结:通过包装一个需要适配的对象,把原接口转换成目标接口。

代理模式

interface Star {
    void confer() ;
    void signContract() ;
    void bookTicket() ;
    void sing() ;
    void collectMoney() ;
}

class RealStar implements Star {
    public RealStar() {}

    @Override
    public void confer() {
        System.out.println("RealStar().confer()") ;
    }

    @Override
    public void signContract() {
        System.out.println("RealStar().signContract()") ;
    }

    @Override
    public void bookTicket() {
        System.out.println("RealStar().bookTicket()") ;
    }

    @Override
    public void sing() {
        System.out.println("RealStar()--我的热情好像一把火!") ;
    }

    @Override
    public void collectMoney() {
        System.out.println("RealStar().collectMoney()") ;
    }
}

//静态代理
class ProxyStar implements Star {
    private Star star ;

    public ProxyStar(Star star) {
        this.star = star;
    }

    @Override
    public void confer() {
        System.out.println("ProxyStar().confer()") ;
    }

    @Override
    public void signContract() {
        System.out.println("ProxyStar().signContract()") ;
    }

    @Override
    public void bookTicket() {
        System.out.println("ProxyStar().bookTicket()") ;
    }

    @Override
    public void sing() {
        star.sing() ;
    }

    @Override
    public void collectMoney() {
        System.out.println("ProxyStar().collectMoney()") ;
    }
}

//动态代理,开发中常见
class StarHandler implements InvocationHandler {
    private Star star ;

    public StarHandler(Star star) {
        this.star = star;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        System.out.print("######\t") ;
        method.invoke(star, args) ;

        return null;
    }
}

测试代码如下:

package JavaDesignPattern;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class Proxy {
    public static void main(String[] args) {
        Star real = new RealStar() ;
        Star sProxy = new ProxyStar(real) ;
        sProxy.confer();
        sProxy.signContract();
        sProxy.bookTicket();
        sProxy.sing();
        sProxy.collectMoney();

        StarHandler handler = new StarHandler(real) ;
        Star dProxy = (Star) java.lang.reflect.Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{Star.class}, handler) ;
        dProxy.confer();
        dProxy.signContract();
        dProxy.bookTicket();
        dProxy.sing();
        dProxy.collectMoney();
    }
}

输出如下:

ProxyStar().confer()
ProxyStar().signContract()
ProxyStar().bookTicket()
RealStar()--我的热情好像一把火!
ProxyStar().collectMoney()
######  RealStar().confer()
######  RealStar().signContract()
######  RealStar().bookTicket()
######  RealStar()--我的热情好像一把火!
######  RealStar().collectMoney()

代理模式总结:可以详细控制访问某类或者某个对象的方法,在调用这个方法前做前置处理,调用这个方法后做后置处理。通过代理,控制对 对象 的访问。

桥接模式

interface Brand {
    void sale() ;
}

class Dell implements Brand {
    @Override
    public void sale() {
        System.out.println("销售Dell") ;
    }
}

class MacBook implements Brand {
    @Override
    public void sale() {
        System.out.println("销售MacBook") ;
    }
}


class Computer {
    protected Brand brand ;

    public Computer(Brand brand) {
        this.brand = brand;
    }

    public void sale() {
        brand.sale() ;
    }
}

class Desktop extends Computer {
    public Desktop(Brand brand) {
        super(brand);
    }

    @Override
    public void sale() {
        super.sale();
        System.out.println("台式机") ;
    }
}

class Laptop extends Computer {
    public Laptop(Brand brand) {
        super(brand);
    }

    @Override
    public void sale() {
        super.sale();
        System.out.println("笔记本") ;
    }
}

测试代码如下:

package JavaDesignPattern;

public class Bridge {
    public static void main(String[] args) {
        Computer c1 = new Laptop(new MacBook()) ;
        c1.sale() ;
        Computer c2 = new Desktop(new Dell()) ;
        c2.sale() ;
    }
}

输出如下:

销售MacBook
笔记本
销售Dell
台式机

桥接模式总结:处理多层继承结构,多维度变化的场景,将各个维度设计成独立的继承结构,使各个维度可以独立的扩展,在抽象层建立关联。

组合模式

interface AbstractFile {
    void killVirus() ;
}

class ImageFile implements AbstractFile {
    private String name ;

    public ImageFile(String name) {
        this.name = name;
    }

    @Override
    public void killVirus() {
        System.out.println("正在查杀图片文件:\t"+name) ;
    }
}

class TextFile implements AbstractFile {
    private String name ;

    public TextFile(String name) {
        this.name = name;
    }

    @Override
    public void killVirus() {
        System.out.println("正在查杀文本文件:\t"+name) ;
    }
}

class VedioFile implements AbstractFile {
    private String name ;

    public VedioFile(String name) {
        this.name = name;
    }

    @Override
    public void killVirus() {
        System.out.println("正在查杀视频文件:\t"+name) ;
    }
}

class Folder implements AbstractFile {
    private String name ;
    private java.util.List<AbstractFile> list = new ArrayList<>() ;

    public Folder(String name) {
        this.name = name;
    }

    public void add(AbstractFile file) {
        list.add(file) ;
    }

    public void remove(AbstractFile file) {
        list.remove(file) ;
    }

    public AbstractFile getIndex(int index) {
        return list.get(index) ;
    }

    @Override
    public void killVirus() {
        System.out.println("正在进入文件夹:\t"+name+"\t查杀") ;
        for(AbstractFile file : list) {
            file.killVirus() ;
        }
    }
}

测试代码如下:

package JavaDesignPattern;

import java.util.ArrayList;

/**
 * Created by YZX on 2017/3/31.
 */

public class Composite {
    public static void main(String[] args) {
        AbstractFile f2, f3, f4, f5, f7, f8, f9, f10 ;
        Folder f1 = new Folder("我的文档") ;
        f2 = new ImageFile("QQ头像") ;
        f3 = new ImageFile("人人头像") ;
        f4 = new TextFile("HelloWorld.java") ;
        f5 = new TextFile("HelloSpark.scala") ;
        f1.add(f2);
        f1.add(f3);
        f1.add(f4);
        f1.add(f5);

        Folder f6 = new Folder("我的电影") ;
        f7 = new VedioFile("射雕英雄") ;
        f8 = new VedioFile("神雕侠侣") ;
        f9 = new VedioFile("倚天屠龙") ;
        f10 = new VedioFile("鹿鼎记") ;
        f6.add(f7);
        f6.add(f8);
        f6.add(f9);
        f6.add(f10);

        f1.add(f6) ;

        f1.killVirus() ;
    }
}

输出如下:

正在进入文件夹:    我的文档    查杀
正在查杀图片文件:   QQ头像
正在查杀图片文件:   人人头像
正在查杀文本文件:   HelloWorld.java
正在查杀文本文件:   HelloSpark.scala
正在进入文件夹:    我的电影    查杀
正在查杀视频文件:   射雕英雄
正在查杀视频文件:   神雕侠侣
正在查杀视频文件:   倚天屠龙
正在查杀视频文件:   鹿鼎记

组合模式总结:为部分和整体的树形关系提供了完美的解决方案,从而可以使用统一的方式处理部分对象和整体对象。其中,使用了递归调用的机制对整个树形结构进行处理。

装饰模式

interface ICar {
    void move() ;
}

//具体构建角色(真实对象)
class ConcreteCar implements ICar {

    public ConcreteCar() {}

    @Override
    public void move() {
        System.out.println("陆地巡洋舰") ;
    }
}

//Decorator装饰角色
class SuperCar implements ICar {
    private ICar icar ;

    public SuperCar(ICar icar) {
        this.icar = icar;
    }

    @Override
    public void move() {
        icar.move() ;
    }
}

//ConcreteDecorator具体装饰角色
class FlyCar extends SuperCar {
    public FlyCar(ICar icar) {
        super(icar);
    }

    private void fly() {
        System.out.println("天上飞") ;
    }

    @Override
    public void move() {
        super.move();
        fly();
    }
}

//ConcreteDecorator具体装饰角色
class WaterCar extends SuperCar {
    public WaterCar(ICar icar) {
        super(icar);
    }

    private void swim() {
        System.out.println("水上漂") ;
    }

    @Override
    public void move() {
        super.move();
        swim();
    }
}

//ConcreteDecorator具体装饰角色
class AICar extends SuperCar {
    public AICar(ICar icar) {
        super(icar);
    }

    private void autoMove() {
        System.out.println("自动驾驶") ;
    }

    @Override
    public void move() {
        super.move();
        autoMove();
    }
}

测试代码如下:

package JavaDesignPattern;

public class Decorator {
    public static void main(String[] args) {
        ConcreteCar car = new ConcreteCar() ;
        car.move();
        System.out.println("------------------------") ;
        new FlyCar(car).move();
        System.out.println("------------------------") ;
        new WaterCar(car).move();
        System.out.println("------------------------") ;
        new AICar(car).move();
        System.out.println("------------------------") ;
        new AICar(new WaterCar(new FlyCar(car))).move() ;
    }
}

输出如下:

陆地巡洋舰
------------------------
陆地巡洋舰
天上飞
------------------------
陆地巡洋舰
水上漂
------------------------
陆地巡洋舰
自动驾驶
------------------------
陆地巡洋舰
天上飞
水上漂
自动驾驶

装饰模式总结:装饰模式是一种用于代替继承的技术,不需要通过继承增加子类就能扩展对象的新功能(动态地为一个对象增加功能)。使用对象的 关联关系 代替继承关系,更加灵活,同时避免类型体系的快速膨胀。

外观模式

class FacadeRegister {
    public FacadeRegister() {}

    public void register() {
        new 海淀工商局().checkName();
        new 海淀税务局().taxCertificate();
        new 中国招商银行().openAccount();
        new 海淀质检局().orgCodeCertificate();
    }
}


interface 工商局 {
    void checkName() ;
}

class 海淀工商局 implements 工商局 {
    public 海淀工商局() {}

    @Override
    public void checkName() {
        System.out.println("公司名是否存在冲突") ;
    }
}

interface 税务局 {
    void taxCertificate() ;
}

class 海淀税务局 implements 税务局 {
    public 海淀税务局() {}

    @Override
    public void taxCertificate() {
        System.out.println("在海淀税务局办理税务登记证") ;
    }
}

interface 银行 {
    void openAccount() ;
}

class 中国招商银行 implements 银行 {
    public 中国招商银行() {}

    @Override
    public void openAccount() {
        System.out.println("在中国招商银行开户") ;
    }
}

interface 质检局 {
    void orgCodeCertificate() ;
}

class 海淀质检局 implements 质检局 {
    public 海淀质检局() {}

    @Override
    public void orgCodeCertificate() {
        System.out.println("在海淀质检局办理组织机构代码证") ;
    }
}

测试代码如下:

package JavaDesignPattern;

public class Facade {
    public static void main(String[] args) {
//        工商局 a = new 海淀工商局() ;
//        a.checkName();
//        税务局 b = new 海淀税务局() ;
//        b.taxCertificate();
//        银行 c = new 中国招商银行() ;
//        c.openAccount();
//        质检局 d = new 海淀质检局() ;
//        d.orgCodeCertificate();
        new FacadeRegister().register();
    }
}

外观模式总结:封装子系统的复杂性,为子系统提供统一的入口,便于客户端调用。

享元模式

//外部状态,非共享享元类
class Coordinate {
    private int x, y ;

    public Coordinate(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }
}

//享元类
interface ChessFlyWeight {
    void setColor(String color) ;
    String getColor() ;
    void disPlay(Coordinate c) ;
}

class ConcreteChess implements ChessFlyWeight {
    //为内部状态提供成元变量进行存储
    private String color ;

    public ConcreteChess(String color) {
        this.color = color;
    }

    @Override
    public void setColor(String color) {
        this.color = color ;
    }

    @Override
    public String getColor() {
        return color ;
    }

    @Override
    public void disPlay(Coordinate c) {
        System.out.println("棋子位置:\t[ "+c.getX()+" , "+c.getY()+" ]\t棋子颜色:\t"+color) ;
    }
}

class ChessFlyWeightFactory {
    //享元池
    private static java.util.HashMap<String, ChessFlyWeight> map = new java.util.HashMap<>() ;

    public static ChessFlyWeight getChess(String color) {
        if(map.get(color) != null) {
            return map.get(color) ;
        }else {
            ChessFlyWeight cfw = new ConcreteChess(color) ;
            map.put(color, cfw) ;
            return cfw ;
        }
    }
}

测试代码如下:

package JavaDesignPattern;

public class FlyWeight {
    public static void main(String[] args) {
        ChessFlyWeight chess1 = ChessFlyWeightFactory.getChess("black") ;
        ChessFlyWeight chess2 = ChessFlyWeightFactory.getChess("black") ;
        System.out.println(chess1) ;
        System.out.println(chess2) ;
        chess1.disPlay(new Coordinate(10, 10));
        chess2.disPlay(new Coordinate(15, 15));

        ChessFlyWeight chess3 = ChessFlyWeightFactory.getChess("white") ;
        ChessFlyWeight chess4 = ChessFlyWeightFactory.getChess("white") ;
        System.out.println(chess3) ;
        System.out.println(chess4) ;
        chess3.disPlay(new Coordinate(20, 20));
        chess4.disPlay(new Coordinate(25, 25));
    }
}

输出如下:

JavaDesignPattern.ConcreteChess@55fa12f6
JavaDesignPattern.ConcreteChess@55fa12f6
棋子位置:   [ 10 , 10 ] 棋子颜色:   black
棋子位置:   [ 15 , 15 ] 棋子颜色:   black
JavaDesignPattern.ConcreteChess@1f4790be
JavaDesignPattern.ConcreteChess@1f4790be
棋子位置:   [ 20 , 20 ] 棋子颜色:   white
棋子位置:   [ 25 , 25 ] 棋子颜色:   white

享元模式总结:相似或者相同对象内存中只存一份,极大减少内存中对象的数量,提高系统性能。外部状态相对独立,不影响内部状态。

=====================================================================

**至此,结构型模式完结。适配模式、代理模式、桥接模式、组合模式、装饰模式、外观模式
、享元模式都属于结构型模式——关注对象和类的组织。**

=====================================================================

责任链模式

//请假的基本信息
class LeaveRequest {
    private String name ;
    private int days ;
    private String reason ;

    public LeaveRequest(String name, int days, String reason) {
        this.name = name;
        this.days = days;
        this.reason = reason;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getDays() {
        return days;
    }

    public void setDays(int days) {
        this.days = days;
    }

    public String getReason() {
        return reason;
    }

    public void setReason(String reason) {
        this.reason = reason;
    }
}

abstract class Leader {
    protected String name ;
    protected Leader leader ;   //责任链上的后继对象

    public Leader(String name) {
        this.name = name;
    }

    public void setLeader(Leader leader) {
        this.leader = leader;
    }

    public abstract void handleRequest(LeaveRequest request) ;
}

class Director extends Leader {
    public Director(String name) {
        super(name);
    }

    @Override
    public void handleRequest(LeaveRequest request) {
        if(request.getDays() < 3) {
            System.out.println(request.getName()+"\t请假\t"+request.getDays()+"\t天,原因:\t"+request.getReason()+"。\t审批人:\t"+this.name+"\t主任") ;
        }else {
            if(this.leader != null) {
                this.leader.handleRequest(request) ;
            }
        }
    }
}

class Manager extends Leader {
    public Manager(String name) {
        super(name);
    }

    @Override
    public void handleRequest(LeaveRequest request) {
        if(request.getDays() < 10) {
            System.out.println(request.getName()+"\t请假\t"+request.getDays()+"\t天,原因:\t"+request.getReason()+"。\t审批人:\t"+this.name+"\t经理") ;
        }else {
            if(this.leader != null) {
                this.leader.handleRequest(request) ;
            }
        }
    }
}

class GeneralManager extends Leader {
    public GeneralManager(String name) {
        super(name);
    }

    @Override
    public void handleRequest(LeaveRequest request) {
        if(request.getDays() < 30) {
            System.out.println(request.getName()+"\t请假\t"+request.getDays()+"\t天,原因:\t"+request.getReason()+"。\t审批人:\t"+this.name+"\t总经理") ;
        }else {
            System.out.println("批准\t"+request.getName()+"\t辞职。\t审批人:\t"+this.name+"\t总经理") ;
        }
    }
}

测试代码如下:

package JavaDesignPattern;

public class ChainOfResponsibility {
    public static void main(String[] args) {
        Leader a = new Director("张") ;
        Leader b = new Manager("李") ;
        Leader c = new GeneralManager("王") ;
        a.setLeader(b);
        b.setLeader(c);

        LeaveRequest request1 = new LeaveRequest("Tom", 2, "看病") ;
        a.handleRequest(request1);

        LeaveRequest request2 = new LeaveRequest("John", 10, "结婚") ;
        a.handleRequest(request2);

        LeaveRequest request3 = new LeaveRequest("Carlo", 30, "旅游") ;
        a.handleRequest(request3);
    }
}

输出如下:

Tom 请假  2   天,原因:   看病。 审批人:    张   主任
John    请假  10  天,原因:   结婚。 审批人:    王   总经理
批准  Carlo   辞职。 审批人:    王   总经理

责任链模式总结:将能够处理同一类请求的对象连成一条链,所提交的请求沿着链传递,链上的对象逐个判断是否有能力处理该要求,如果能责处理,否则传递给链上的下一个对象。

迭代器模式

interface MyIterator {
    Object first() ;
    Object next() ;
    boolean isFirst() ;
    boolean hasNext() ;
    boolean isLast() ;
}

class ConcreteMyAggregate {
    private List<Object> list = new ArrayList<>() ;

    public ConcreteMyAggregate() {}

    public List<Object> getList() {
        return list;
    }

    public void setList(List<Object> list) {
        this.list = list;
    }

    public void addObject(Object object) {
        list.add(object) ;
    }

    public void removeObject(Object object) {
        list.remove(object) ;
    }

    //内部类可以直接使用外部类的属性
    private class ConcreIterator implements MyIterator {
        private int cursor ;

        @Override
        public Object first() {
            return list.get(0) ;
        }

        @Override
        public Object next() {
            return list.get(cursor++) ;
        }

        @Override
        public boolean isFirst() {
            return cursor == 0 ;
        }

        @Override
        public boolean hasNext() {
            return cursor <= (list.size()-1) ;
        }

        @Override
        public boolean isLast() {
            return cursor == (list.size()-1) ;
        }
    }

    //获得迭代器
    public MyIterator createIterator() {
        return new ConcreIterator() ;
    }
}

测试代码如下:

package JavaDesignPattern;

import java.util.ArrayList;
import java.util.List;

public class IteratorPattern {
    public static void main(String[] args) {
        ConcreteMyAggregate cma = new ConcreteMyAggregate() ;
        cma.addObject("bb");
        cma.addObject("hh");
        cma.addObject("jj");

        MyIterator iter = cma.createIterator() ;
        while(iter.hasNext()) {
            System.out.println(iter.next()) ;
        }
    }
}

输出如下:

bb
hh
jj

迭代器模式总结:提供一种遍历聚合对象的方式,又称为游标(cursor)模式。

中介者模式

interface Mediator {
    void register(String name, Department d) ;
    void command(String name) ;
}

interface Department {
    void selfAction() ;
    void outAction() ;
}

class DevelopDepartment implements Department {
    private Mediator m ;

    public DevelopDepartment(Mediator m) {
        this.m = m ;
        m.register("DevelopDepartment", this) ;
    }

    @Override
    public void selfAction() {
        System.out.println("专心研发项目") ;
    }

    @Override
    public void outAction() {
        System.out.println("汇报工作:发工资、申请资金支持") ;
        m.command("FinacialDepartment") ;
    }
}

class FinacialDepartment implements Department {
    private Mediator m ;

    public FinacialDepartment(Mediator m) {
        this.m = m ;
        m.register("FinacialDepartment", this) ;
    }

    @Override
    public void selfAction() {
        System.out.println("数钱") ;
    }

    @Override
    public void outAction() {
        System.out.println("汇报工作:没钱了、钱太多怎么花?") ;
    }
}

class MarketDepartment implements Department {
    private Mediator m ;

    public MarketDepartment(Mediator m) {
        this.m = m ;
        m.register("MarketDepartment", this) ;
    }

    @Override
    public void selfAction() {
        System.out.println("出去拉项目") ;
    }

    @Override
    public void outAction() {
        System.out.println("汇报工作:项目进度、申请资金支持") ;
        m.command("FinacialDepartment");
    }
}

class President implements Mediator {
    private Map<String, Department> map = new HashMap<>() ;

    @Override
    public void register(String name, Department d) {
        map.put(name, d) ;
    }

    @Override
    public void command(String name) {
        map.get(name).selfAction() ;
    }
}

测试代码如下:

package JavaDesignPattern;

import java.util.HashMap;
import java.util.Map;

public class MediatorPattern {
    public static void main(String[] args) {
        Mediator m = new President() ;

        MarketDepartment market = new MarketDepartment(m) ;
        DevelopDepartment develop = new DevelopDepartment(m) ;
        FinacialDepartment finacial = new FinacialDepartment(m) ;

        market.selfAction();
        market.outAction();
    }
}

输出如下:

出去拉项目
汇报工作:项目进度、申请资金支持
数钱

中介者模式总结:解耦多个同事对象之间的交互关系。每个对象都持有中介者对象的引用,只跟中介者对象打交道,通过中介者对象统一管理这些交互关系。

命令模式

//真正的命令执行者
class Receiver {
    public void action() {
        System.out.println("Receiver.action()") ;
    }
}

interface Command {
    void execute() ;
}

class ConcreteCommand implements Command {
    private Receiver receiver ;

    public ConcreteCommand(Receiver receiver) {
        this.receiver = receiver;
    }

    @Override
    public void execute() {
        //命令真正执行前后,做相关的处理。
        receiver.action();
    }
}

//发起者
class Invoker {
    //也可以通过List<Command>容纳很多命令对象进行命令批处理。数据库底层的事务管理就是类似的结构
    private Command command ;

    public Invoker(Command command) {
        this.command = command;
    }

    //业务方法,用于调用命令类的方法
    public void call() {
        command.execute();
    }
}

测试代码如下:

package JavaDesignPattern;

public class CommandPattern {
    public static void main(String[] args) {
        Command c = new ConcreteCommand(new Receiver()) ;
        Invoker invoker = new Invoker(c) ;
        invoker.call();
    }
}

命令模式总结:将一个请求封装为一个对象,对请求排队或者记录请求日志,以及支持可撤销的操作,也被称为事务模式。

解释器模式

访问者模式

策略模式

interface Strategy {
    double getPrice(double standardPrice) ;
}

class NewCustomerFewStrategy implements Strategy {
    public NewCustomerFewStrategy() {}

    @Override
    public double getPrice(double standardPrice) {
        System.out.println("普通客户小批量不打折") ;
        return standardPrice ;
    }
}

class NewCustomerManyStrategy implements Strategy {
    public NewCustomerManyStrategy() {}

    @Override
    public double getPrice(double standardPrice) {
        System.out.println("普通客户大批量打9折") ;
        return standardPrice*0.9 ;
    }
}

class OldCustomerFewStrategy implements Strategy {
    public OldCustomerFewStrategy() {}

    @Override
    public double getPrice(double standardPrice) {
        System.out.println("老客户大批量打85折") ;
        return standardPrice*0.85 ;
    }
}

class OldCustomerManyStrategy implements Strategy {
    public OldCustomerManyStrategy() {}

    @Override
    public double getPrice(double standardPrice) {
        System.out.println("老客户大批量打8折") ;
        return standardPrice*0.8 ;
    }
}

//负责和具体的策略交互
class Context {
    private Strategy strategy ;

    public Context(Strategy strategy) {
        this.strategy = strategy;
    }

    public void setStrategy(Strategy strategy) {
        this.strategy = strategy;
    }

    public void printPrice(double standardPrice) {
        System.out.println("报价:\t"+strategy.getPrice(standardPrice)) ;
    }
}

测试代码如下:

package JavaDesignPattern;

public class StrategyPattern {
    public static void main(String[] args) {
        new Context(new NewCustomerFewStrategy()).printPrice(3998);
        new Context(new NewCustomerManyStrategy()).printPrice(3998);
        new Context(new OldCustomerFewStrategy()).printPrice(3998);
        new Context(new OldCustomerManyStrategy()).printPrice(3998);
    }
}

输出如下:

普通客户小批量不打折
报价: 3998.0
普通客户大批量打9折
报价: 3598.2000000000003
老客户大批量打85折
报价: 3398.2999999999997
老客户大批量打8折
报价: 3198.4

策略模式总结:策略模式对应于解决某一个问题的算法族,容许用户从该算法族中任选一个算法解决某一个问题,同时可以方便的更换算法或者增加新的算法。本质:分离算法,选择实现。

模版方法模式

abstract class BankTemplateMethod {
    public final void takeNumber() {
        System.out.println("取号排队") ;
    }

    public abstract void transact() ;

    public final void  evaluate() {
        System.out.println("反馈评分") ;
    }

    public final void process() {
        this.takeNumber();
        this.transact();
        this.evaluate();
    }
}

class DrawMoney extends BankTemplateMethod {
    @Override
    public void transact() {
        System.out.println("我要理财") ;
    }
}

测试代码如下:

package JavaDesignPattern;

public class TemplateMethod {
    public static void main(String[] args) {
        BankTemplateMethod btm1 = new DrawMoney() ;
        btm1.process();

        //匿名内部类
        BankTemplateMethod btm2 = new BankTemplateMethod() {
            @Override
            public void transact() {
                System.out.println("我要办储蓄卡") ;
            }
        };
        btm2.process();
    }
}

输出如下:

取号排队
我要理财
反馈评分
取号排队
我要办储蓄卡
反馈评分

模版方法模式总结:处理某个流程的代码都已经具备,但是其中某个节点的代码暂时不能确定,将这个节点的代码实现转移给子类完成。

状态模式

interface State {
    void handle() ;
}

class FreeState implements State {
    public FreeState() {}

    @Override
    public void handle() {
        System.out.println("房间空闲") ;
    }
}

class BookedState implements State {
    public BookedState() {}

    @Override
    public void handle() {
        System.out.println("房间已被预定") ;
    }
}

class CheckedInState implements State {
    public CheckedInState() {}

    @Override
    public void handle() {
        System.out.println("房间已入住") ;
    }
}

class StateContext {
    private State state ;

    public StateContext() {}

    public void setState(State state) {
        this.state = state ;
        state.handle() ;
    }
}

测试代码如下:

package JavaDesignPattern;

public class StatePattern {
    public static void main(String[] args) {
        StateContext sc = new StateContext() ;

        sc.setState(new FreeState());
        sc.setState(new BookedState());
        sc.setState(new CheckedInState());
    }
}

输出如下:

房间空闲
房间已被预定
房间已入住

状态模式总结:用于解决系统中复杂对象的状态转换以及不同状态下行为的封装问题。例如:线程对象各状态之间的切换。

观察者模式

interface Observer {
    void update(Subject subject) ;
}

class ObserverA implements Observer {
    //myState需要跟目标对象的state值保持一致
    private int myState ;

    public int getMyState() {
        return myState;
    }

    public void setMyState(int myState) {
        this.myState = myState;
    }

    @Override
    public void update(Subject subject) {
        myState = ((ConcreteSubjectA) subject).getState() ;
    }
}

/*--------------------------------------------------------------------*/
class ObserverB implements java.util.Observer {
    private int myState ;

    public int getMyState() {
        return myState;
    }

    public void setMyState(int myState) {
        this.myState = myState;
    }

    @Override
    public void update(java.util.Observable o, Object arg) {
        myState = ((ConcreteSubjectB)o).getState() ;
    }
}
/*--------------------------------------------------------------------*/

class Subject {
    private List<Observer> list = new ArrayList<Observer>() ;

    public void addObserver(Observer observer) {
        list.add(observer) ;
    }

    public void removeObserver(Observer observer) {
        list.remove(observer) ;
    }

    public void notifyAllObserver() {
        for(Observer obs : list) {
            obs.update(this) ;
        }
    }
}

class ConcreteSubjectA extends Subject {
    private int state ;

    public int getState() {
        return state;
    }

    public void setState(int state) {
        this.state = state;
        this.notifyAllObserver();
    }
}

/*--------------------------------------------------------------------*/
class ConcreteSubjectB extends java.util.Observable {
    private int state ;

    public int getState() {
        return state;
    }

    public void setState(int state) {
        this.state = state;
        //目标对象已经做了更改
        setChanged();
        //通知所有的观察者
        notifyObservers(this.state);
    }
}
/*--------------------------------------------------------------------*/

测试代码如下:

package JavaDesignPattern;

import java.util.ArrayList;
import java.util.List;

public class ObserverPattern {
    public static void main(String[] args) {
        ConcreteSubjectA csa = new ConcreteSubjectA() ;
        ObserverA a1 = new ObserverA() ;
        ObserverA a2 = new ObserverA() ;
        ObserverA a3 = new ObserverA() ;
        csa.addObserver(a1);
        csa.addObserver(a2);
        csa.addObserver(a3);
        csa.setState(3998);
        System.out.println(csa.getClass().getName()+"\t"+a1.getMyState()) ;
        System.out.println(csa.getClass().getName()+"\t"+a2.getMyState()) ;
        System.out.println(csa.getClass().getName()+"\t"+a3.getMyState()) ;


        ConcreteSubjectB csb = new ConcreteSubjectB() ;
        ObserverB b1 = new ObserverB() ;
        ObserverB b2 = new ObserverB() ;
        ObserverB b3 = new ObserverB() ;
        csb.addObserver(b1);
        csb.addObserver(b2);
        csb.addObserver(b3);
        csb.setState(1998);
        System.out.println(csb.getClass().getName()+"\t"+b1.getMyState()) ;
        System.out.println(csb.getClass().getName()+"\t"+b2.getMyState()) ;
        System.out.println(csb.getClass().getName()+"\t"+b3.getMyState()) ;
    }
}

输出如下:

JavaDesignPattern.ConcreteSubjectA  3998
JavaDesignPattern.ConcreteSubjectA  3998
JavaDesignPattern.ConcreteSubjectA  3998
JavaDesignPattern.ConcreteSubjectB  1998
JavaDesignPattern.ConcreteSubjectB  1998
JavaDesignPattern.ConcreteSubjectB  1998

观察者模式总结:观察者模式主要用于1:N的通知。当一个目标对象的状态发生改变时,它需要及时告知一系列观察者对象,令其作出响应。典型应用场景:广播机制。

备忘录模式

//源发器类
class Emp {
    private String name ;
    private int age ;
    private double salary ;

    public Emp(String name, int age, double salary) {
        this.name = name;
        this.age = age;
        this.salary = salary;
    }

    //进行备忘操作,并且返回备忘录对像
    public EmpMemento memento() {
        return new EmpMemento(this) ;
    }

    //进行数据恢复,恢复成指定备忘录的值
    public void recovery(EmpMemento em) {
        this.name = em.getName() ;
        this.age = em.getAge() ;
        this.salary = em.getSalary() ;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }
}

//备忘录类
class EmpMemento {
    private String name ;
    private int age ;
    private double salary ;

    public EmpMemento(Emp e) {
        this.name = e.getName() ;
        this.age = e.getAge() ;
        this.salary = e.getSalary() ;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }
}

//负责人类
class CareTaker {
    private EmpMemento em ;

    //private Stack<EmpMemento> stack = new Stack<>() ;     //设置多个备忘点

    public EmpMemento getEm() {
        return em;
    }

    public void setEm(EmpMemento em) {
        this.em = em;
    }
}

测试代码如下:

package JavaDesignPattern;

public class MementoPattern {
    public static void main(String[] args) {
        CareTaker ct = new CareTaker() ;
        Emp emp = new Emp("Madara", 26, 12000) ;
        System.out.println("第1次:\t"+emp.getName()+"----"+emp.getAge()+"----"+emp.getSalary()) ;
        ct.setEm(emp.memento());

        emp.setName("Uchiha");
        emp.setAge(35);
        emp.setSalary(50000);
        System.out.println("第2次:\t"+emp.getName()+"----"+emp.getAge()+"----"+emp.getSalary()) ;

        emp.recovery(ct.getEm());
        System.out.println("第3次:\t"+emp.getName()+"----"+emp.getAge()+"----"+emp.getSalary()) ;
    }
}

输出如下:

第1次:    Madara----26----12000.0
第2次:    Uchiha----35----50000.0
第3次:    Madara----26----12000.0

备忘录模式总结:保存某个对象内部状态的拷贝,这样以后就可以将该对象恢复到原先的状态。应用场景:普通软件中的撤销操作,数据库中事务的回滚操作。

=====================================================================

至此,行为型模式完结。行为型模式——关注系统中对象之间的相互交互,研究系统运行时对象之间的相互通信和协作,进一步明确对象的职责,共有11种模式。

=====================================================================

猜你喜欢

转载自blog.csdn.net/yitengtongweishi/article/details/75117101