设计模式

1 创建模式

1.1 工厂模式

适用场合:大量产品需要创建,且具有共同接口

1.1.1 简单工厂模式

  1. 简介:根据需要提供对象类型

  2. 示例CreateObject("Object3")

    public class SimpleObjectFactory {
        public ObjectImplement CreateObject(String type) {
            ObjectImplement object = null;
            if (type.equals("Object1")) {
                object = new Object1();
            } else if (type.equals("Object2")) {
                object = new Object2();
            } else if (type.equals("Object3")) {
                object = new Object3();
            }
            return object;
        }
    }
    
    SimpleObjectFactory simpleObjectFactory = new SimpleObjectFactory();
    ObjectImplement object = simpleObjectFactory.CreateObject("Object3");
    
  3. 问题:创建新类型需要修改原有工厂类

1.1.2 工厂方法模式

  1. 简介:通过新建工厂类拓展需求

  2. 示例

    public class Factory1 {
        public ObjectImplement createObject(String type) {
            ObjectImplement object = null;
            if (type.equals("Object1")) {
                object = new Object1();
            } else if (type.equals("Object2")) {
                object = new Object2();
            } else if (type.equals("Object3")) {
                object = new Object3();
            }
            return object;
        }
    }
    
    public class Factory2 {
        public ObjectImplement createObject(String type) {
            ObjectImplement object = null;
            if (type.equals("Object1")) {
                object = new Object1();
            } else if (type.equals("Object2")) {
                object = new Object2();
            } else if (type.equals("Object3")) {
                object = new Object3();
            }
            return object;
        }
    }
    
    public class Factory3 {
        public ObjectImplement createObject(String type) {
            ObjectImplement object = null;
            if (type.equals("Object1")) {
                object = new Object1();
            } else if (type.equals("Object2")) {
                object = new Object2();
            } else if (type.equals("Object3")) {
                object = new Object3();
            }
            return object;
        }
    }
    
    Factory1 factory1 = new Factory1();
    (factory1.createObject("Object1")).print();
    
  3. 问题:依旧需要指定工厂类,不灵活

1.1.3 抽象工厂模式

  1. 简介:根据需要提供工厂类型,并根据需要提供对象类型

  2. 示例

    public class AbstractObjectFactory {
        public Factory createFactory(String type) {
            Factory factory = null;
            if (type.equals("Factory1")) {
                factory = new Factory1();
            } else if (type.equals("Factory2")) {
                factory = new Factory2();
            } else if (type.equals("Factory3")) {
                factory = new Factory3();
            }
            return factory;
        }
    }
    
    AbstractObjectFactory abstractObjectFactory = new AbstractObjectFactory();
    Factory factory = abstractObjectFactory.createFactory("Factory1");
    

1.1.4 三种工厂模式使用选择

  1. 简单工厂:拓展需要小
  2. 工厂方法:拓展需求大
  3. 抽象工厂:产品族

1.2 单例模式

1.2.1 预加载

  1. 简介:未使用就已经被加载到内存

  2. 示例

    public class PreloadSingleton {
        private static PreloadSingleton instance = new PreloadSingleton();
    
        private PreloadSingleton() {}
    
        public static PreloadSingleton getInstance() {
            return instance;
        }
    }
    
    PreloadSingleton instance1 = PreloadSingleton.getInstance();
    PreloadSingleton instance2 = PreloadSingleton.getInstance();
    System.out.println(instance1 == instance2);
    
  3. 问题:没有使用就已经加载到了内存,会造成内存的浪费

1.2.2 懒加载

  1. 简介:使用到单例对象时才创建对象,加载到内存

  2. 示例

    public class LazyloadSingleton {
        private static LazyloadSingleton instance = null;
    
        private LazyloadSingleton() {}
    
        public static LazyloadSingleton getInstance() {
            if (instance == null) {
                instance = new LazyloadSingleton();
            }
            return instance;
        }
    }
    
    LazyloadSingleton lazyloadSingleton1 = LazyloadSingleton.getInstance();
    LazyloadSingleton lazyloadSingleton2 = LazyloadSingleton.getInstance();
    System.out.println(lazyloadSingleton1 == lazyloadSingleton2);
    
  3. 问题:创建对象分三步,线程不安全

    memory=allocate(); // 1:初始化内存空间
    ctorInstance(memory); // 2:初始化对象
    instance=memory(); // 3:设置instance指向刚分配的内存地址
    

1.2.3 线程安全的懒加载

  1. 简介:使用 synchronizedvolatile 保证线程安全

  2. 示例

    public class ThreadSafeLazyloadSingleton {
        private static volatile ThreadSafeLazyloadSingleton instance = null;
    
        private ThreadSafeLazyloadSingleton() {}
    
        public ThreadSafeLazyloadSingleton getInstance() {
            if (instance == null) {
                synchronized (ThreadSafeLazyloadSingleton.class) {
                    if (instance == null) {
                        instance = new ThreadSafeLazyloadSingleton();
                    }
                }
            }
            return instance;
        }
    }
    

1.3 生成器模式

  1. 简介:通过定义抽象生成器指明产品结构,通过具体实现补全产品信息,通过 Director 实现具体产品类型的创建

  2. 示例

    public abstract class ProductBuilder {
        protected Product product;
    
        public Product getProtect() {
            return product;
        }
    
        public void buildProtect() {
            product = new Product();
        }
    
        public abstract void buildComponent1();
        public abstract void buildComponent2();
        public abstract void buildComponent3();
    }
    
    public class Product1Builder extends ProductBuilder {
        @Override
        public void buildComponent1() {
            System.out.println("Component1 has been built");
        }
    
        @Override
        public void buildComponent2() {
            System.out.println("Component2 has been built");
        }
    
        @Override
        public void buildComponent3() {
            System.out.println("Component3 has been built");
        }
    }
    
    public class Director {
        private ProductBuilder productBuilder;
    
        public void setProductBuilder(ProductBuilder productBuilder) {
            this.productBuilder = productBuilder;
        }
    
        public Product getProduct() {
            return productBuilder.getProtect();
        }
    
        public void constructProduct() {
            productBuilder.buildComponent1();
            productBuilder.buildComponent2();
            productBuilder.buildComponent3();
        }
    }
    
    Director director = new Director();
    director.setProductBuilder(new Product1Builder());
    director.constructProduct();
    Product product = director.getProduct();
    
  3. 问题:不同对象需要写不同的 Builder 类,大大增加类的数量

1.4 原型模式(clone)

2 结构模式

2.1 适配器模式

2.1.1 类适配器模式

  1. 简介:继承类 1,实现接口 2 实现转换

  2. 示例

    public interface Class1 {
        public void class1Acts();
    }
    
    public class Class1Implement implements Class1 {
        @Override
        public void class1Acts() {
            System.out.println("I am Class1");
        }
    }
    
    public interface Class2 {
        public void class2Acts();
    }
    
    public class AdapterClass1ToClass2 extends Class1Implement implements Class2 {
        @Override
        public void class2Acts() {
            System.out.println("I am Class2");
        }
    }
    
    public class Class2User<T> {
        public void use(T t) {
            if (t instanceof Class2 class2) {
                System.out.println("Class2 acts");
                class2.class2Acts();
            } else {
                System.out.println("Not matched");
            }
        }
    }
    
    Class2 class2 = new AdapterClass1ToClass2();
    Class2User class2User = new Class2User();
    class2User.use(class2);
    class2User.use(new Class1Implement());
    

2.1.2 对象适配器模式

  1. 简介:不使用继承,而是使用组合

  2. 示例

    public class AdapterClass1ToClass2 implements Class2 {
        Class1 class1 = new Class1Implement();
        @Override
        public void class2Acts() {
            class1.class1Acts();
        }
    }
    

2.1.3 接口适配器模式

  1. 简介:用抽象适配器类实现类 2 接口规定的方法,然后选择性实现抽象类定义的方法

  2. 示例

    public abstract class AdapterClass1ToClass2 implements Class2 {
        Class1 class1 = new Class1Implement();
    
        @Override
        public void class2Acts() {
            class1.class1Acts();
        }
    
        @Override
        public void class2Acts2() {}
    }
    
    public class AdapterClass1ToClass2Implement extends AdapterClass1ToClass2 {
        public void class2Acts() {
            super.class2Acts();
        }
    }
    

2.2 装饰器模式

  1. 简介:被装饰者与装饰者继承于同一个超类

  2. 示例

    public abstract class Product {
        private int number = 0;
        private String description = "";
    
        public void addNumber() {
            number += 1;
        }
    
        public void setDescription(String description) {
            this.description = description;
        }
    
        public String getDescription() {
            return description;
        }
    }
    
    public class Product1 extends Product {
        public Product1() {
            super.setDescription("Product1\n");
            super.addNumber();
        }
    }
    
    public class Decorator extends Product {
        private Product product;
        private String description = "";
    
        public Decorator(Product product) {
            this.product = product;
        }
    
        public void setDescription(String description) {
            this.description = description;
        }
    
        public String getDescription() {
            return product.getDescription() + description;
        }
    }
    
    public class Component1 extends Decorator {
        public Component1(Product product) {
            super(product);
            super.setDescription("Component1\n");
        }
    }
    
    DecoratorPattern.Product result = new Product1();
    result = new Component1(result);
    result = new Component2(result);
    result = new Component3(result);
    System.out.println(result.getDescription());
    

2.3 代理模式

2.3.1 静态代理

  1. 简介:作为中介调用服务端 API

  2. 示例

    public interface Service {
        void serve();
    }
    
    public class ServiceImplement implements Service {
        @Override
        public void serve() {
            System.out.println("Provide service");
        }
    }
    
    public class ServiceProxy implements Service {
        private Service service;
    
        public ServiceProxy(final Service service) {
            this.service = service;
        }
    
        @Override
        public void serve() {
            System.out.println("Before providing service");
            service.serve();
            System.out.println("After providing service");
        }
    }
    
    (new ProxyPattern.Static.ServiceProxy(new ServiceImplement())).serve();
    
  3. 问题:代理对象与目标对象要实现相同接口,每个服务都要创建代理类,工作量太大

2.3.2 动态代理

  1. 简介:使用 Proxy.newProxyInstance 生成代理对象,通过实现 InvocationHandler 拦截代理方法调用

  2. 示例

    public class DynamicProxyHandler implements InvocationHandler {
        private Object object;
        public DynamicProxyHandler(final Object object) {
            this.object = object;
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("Before providing service");
            Object result = method.invoke(object, args);
            System.out.println("After providing service");
            return result;
        }
    }
    
    Service serviceProxy = (Service) Proxy.newProxyInstance(
            Service.class.getClassLoader(),
            new Class[]{Service.class},
            new DynamicProxyHandler(new ServiceImplement())
    );
    serviceProxy.serve();
    
  3. 问题:需要使用被代理对象的接口,无法仅支持 interface 代理

2.4 外观模式

  1. 简介:用户只需与系统交互,系统与子系统交互,可以松散耦合,简单易用

  2. 示例

    public class Product {
        private Component1 component1;
        private Component2 component2;
        private Component3 component3;
    
        public Product() {
            component1 = new Component1();
            component2 = new Component2();
            component3 = new Component3();
        }
    
        public void start() {
            component1.start();
            component2.start();
            component3.start();
        }
    
        public void stop() {
            component1.stop();
            component2.stop();
            component3.stop();
        }
    }
    
    Product product = new Product();
    product.start();
    product.stop();
    

2.5 桥接模式

  1. 简介:一个类存在两个独立变化的维度,并都需要进行拓展。使用聚合替代继承,不会在需要增加时造成类的大量创建

  2. 示例

    public interface Software {
        void run();
    }
    
    public abstract class Phone {
        protected Software software;
    
        public void setSoftware(Software software) {
            this.software = software;
        }
    
        public abstract void run();
    }
    
    AppStore appStore = new AppStore();
    Phone oppo = new Oppo();
    oppo.setSoftware(appStore);
    oppo.run();
    
    Phone vivo = new Vivo();
    vivo.setSoftware(appStore);
    vivo.run();
    
  3. 问题:增加系统的理解与设计难度

2.6 组合模式

  1. 简介:部分-整体模式。通过将树形节点中的中间节点与叶子节点实现同一接口来统一调用,不用区分对待。

  2. 示例

    public interface Component {
        void add(Component component);
        void remove(Component component);
        Component getChild(int i);
        void operation();
    }
    
    public class Leaf implements Component {
        private String name;
    
        public Leaf(String name) {
            this.name = name;
        }
    
        @Override
        public void add(Component component) {}
    
        @Override
        public void remove(Component component) {}
    
        @Override
        public Component getChild(int i) {
            return null;
        }
    
        @Override
        public void operation() {
            System.out.println("<Leaf>: " + name);
        }
    }
    
    public class Composite implements Component {
        private ArrayList<Component> children = new ArrayList<>();
    
        @Override
        public void add(Component component) {
            children.add(component);
        }
    
        @Override
        public void remove(Component component) {
            children.remove(component);
        }
    
        @Override
        public Component getChild(int i) {
            return children.get(i);
        }
    
        @Override
        public void operation() {
            for (Component object : children) {
                object.operation();
            }
        }
    }
    
    Composite root = new Composite();
    Leaf floor11 = new Leaf("(1, 1)");
    Composite floor12 = new Composite();
    Leaf floor13 = new Leaf("(1, 3)");
    root.add(floor11);
    root.add(floor12);
    root.add(floor13);
    
    Leaf floor21 = new Leaf("(2, 1)");
    floor12.add(floor21);
    
    root.operation();
    

2.7 享元模式

  1. 简介:内部状态相同的元素不重复创建,共享同一对象,可以节省内存占用

  2. 示例

    public class FlyweightFactory {
        private Map<String, Flyweight> flyweightMap = new HashMap<>();
    
        public Flyweight getFlyweight(String str) {
            Flyweight flyweight = flyweightMap.get(str);
            if (flyweight == null) {
                flyweight = new FlyweightImpl(str);
                flyweightMap.put(str, flyweight);
            }
            return flyweight;
        }
    
        public int getFlyweightMapSize() {
            return flyweightMap.size();
        }
    }
    
    FlyweightFactory flyweightFactory = new FlyweightFactory();
    Flyweight flyweight1 = flyweightFactory.getFlyweight("A");
    Flyweight flyweight2 = flyweightFactory.getFlyweight("B");
    Flyweight flyweight3 = flyweightFactory.getFlyweight("A");
    flyweight1.print();
    flyweight2.print();
    flyweight3.print();
    System.out.println(flyweightFactory.getFlyweightMapSize());
    

3 关系模式

3.1 策略模式

  1. 简介:通过实现同一接口,可以动态更换策略

  2. 示例

    public interface Strategy {
        int calc(int num1, int num2);
    }
    
    public class AddStrategy implements Strategy {
        @Override
        public int calc(int num1, int num2) {
            return num1 + num2;
        }
    }
    
    public class SubStrategy implements Strategy {
        @Override
        public int calc(int num1, int num2) {
            return num1 - num2;
        }
    }
    
    public class Environment {
        private Strategy strategy;
    
        public Environment(Strategy strategy) {
            this.strategy = strategy;
        }
    
        public int calculate(int a, int b) {
            return strategy.calc(a, b);
        }
    }
    
    Environment environment = new Environment(new AddStrategy());
    int result = environment.calculate(20, 5);
    System.out.println(result);
    
    Environment environment1 = new Environment(new SubStrategy());
    int result1 = environment1.calculate(20, 5);
    System.out.println(result1);
    
  3. 问题:策略类增多,且需要对外暴露

3.2 模板模式

  1. 简介:抽象模板定义步骤,实现模板时可根据需要自定义步骤内容

  2. 示例

    public abstract class TotalProcess {
        protected void process() {
            process1();
            process2();
            process3();
        }
    
        abstract void process1();
        abstract void process2();
        abstract void process3();
    }
    
    public class Activity1 extends TotalProcess {
        @Override
        public void process1() {
            System.out.println("Activity1 process1");
        }
    
        @Override
        public void process2() {
            System.out.println("Activity1 process2");
        }
    
        @Override
        public void process3() {
            System.out.println("Activity1 process3");
        }
    }
    
    TotalProcess activity1 = new Activity1();
    activity1.process();
    
    TotalProcess activity2 = new Activity2();
    activity2.process();
    
  3. 问题:每个不同的实现都需要定义一个子类,类的个数增加很快

3.3 观察者模式

  1. 简介:被观察者发生改变时通知所有的观察者

  2. 示例

    public interface Subject {
        void registerObserver(Observer observer);
        void removeObserver(Observer observer);
        void notifyObserver();
    }
    
    public interface Observer {
        void update(String message);
    }
    
    public class AppServer implements Subject {
        private List<Observer> list;
        private String message;
    
        public AppServer() {
            list = new ArrayList<>();
        }
    
        @Override
        public void registerObserver(Observer observer) {
            list.add(observer);
        }
    
        @Override
        public void removeObserver(Observer observer) {
            if (!list.isEmpty()) {
                list.remove(observer);
            }
        }
    
        @Override
        public void notifyObserver() {
            for (Observer observer : list) {
                observer.update(message);
            }
        }
    
        public void setInformation(String str) {
            this.message = str;
            System.out.println("APP is updating");
            notifyObserver();
        }
    }
    
    public class User implements Observer {
        private String name;
        private String message;
    
        public User(String name) {
            this.name = name;
        }
    
        @Override
        public void update(String message) {
            this.message = message;
            read();
        }
    
        public void read() {
            System.out.println(name + " : " + message);
        }
    }
    
    AppServer appServer = new AppServer();
    
    Observer user1 = new User("User1");
    Observer user2 = new User("User2");
    Observer user3 = new User("User3");
    
    appServer.registerObserver(user1);
    appServer.registerObserver(user2);
    appServer.registerObserver(user3);
    appServer.setInformation("haha");
    
    appServer.removeObserver(user1);
    appServer.setInformation("hihi");
    

3.4 迭代器模式

  1. 简介:通过实现同一迭代器接口来方便迭代不同对象

  2. 示例

    public interface Iterator {
        boolean hasNext();
        Object next();
    }
    
    public class Menu {
        private ArrayList<MenuItem> menuItems;
    
        public Menu() {
            menuItems = new ArrayList<>();
    
            addItem("item1");
            addItem("item2");
            addItem("item3");
        }
    
        void addItem(String name) {
            menuItems.add(new MenuItem(name));
        }
    
        public Iterator getIterator() {
            return new MenuIterator();
        }
    
        class MenuIterator implements Iterator {
            private int position = 0;
    
            public MenuIterator() {
                position = 0;
            }
    
            @Override
            public boolean hasNext() {
                if (position < menuItems.size()) {
                    return true;
                }
                return false;
            }
    
            @Override
            public Object next() {
                MenuItem menuItem = menuItems.get(position);
                position++;
                return menuItem;
            }
        }
    }
    
    public class MenuUser {
        private ArrayList<Iterator> iterators = new ArrayList<>();
    
        public MenuUser() {}
    
        public void addIterator(Iterator iterator) {
            iterators.add(iterator);
        }
    
        public void printMenu() {
            Iterator iterator;
            MenuItem menuItem;
            for (int i = 0, len = iterators.size(); i < len; i++) {
                iterator = iterators.get(i);
                while (iterator.hasNext()) {
                    menuItem = (MenuItem) iterator.next();
                    System.out.println(menuItem.getName());
                }
            }
        }
    }
    
    MenuUser menuUser = new MenuUser();
    Menu menu1 = new Menu();
    Menu menu2 = new Menu();
    Menu menu3 = new Menu();
    menuUser.addIterator(menu1.getIterator());
    menuUser.addIterator(menu2.getIterator());
    menuUser.addIterator(menu3.getIterator());
    menuUser.printMenu();
    
  3. 问题:增加新类需要增加新的迭代器

3.5 责任链模式

  1. 简介:向责任链发起请求,请求顺着责任链流动,在某一层得到处理

  2. 示例

    public abstract class Approver {
        Approver successor;
        String name;
    
        public Approver(String name) {
            this.name = name;
        }
    
        public abstract void processRequest(PurchaseRequest request);
        public void setSuccessor(Approver successor) {
            this.successor = successor;
        }
    }
    
    public class Approver1 extends Approver {
        public Approver1(String name) {
            super(name);
        }
    
        @Override
        public void processRequest(PurchaseRequest request) {
            if (false) {
    
            } else {
                successor.processRequest(request);
            }
        }
    }
    
    public class Approver2 extends Approver {
        public Approver2(String name) {
            super(name);
        }
    
        @Override
        public void processRequest(PurchaseRequest request) {
            if (true) {
                System.out.println("Approver2 is processing");
            } else {
                successor.processRequest(request);
            }
        }
    }
    
    public class Client {
        public Client() {}
    
        public PurchaseRequest sendRequest() {
            return new PurchaseRequest();
        }
    }
    
    Client client = new Client();
    Approver approver1 = new Approver1("Approver1");
    Approver approver2 = new Approver2("Approver2");
    
    approver1.setSuccessor(approver2);
    approver2.setSuccessor(approver1);
    
    approver1.processRequest(client.sendRequest());
    

3.6 命令模式

  1. 简介:通过实现同一命令接口,可以使用不同命令对对象进行控制

  2. 示例

    public interface Command {
        void execute();
        void undo();
    }
    
    public class Command1 implements Command {
        private Object object;
    
        public Command1(Object object) {
            this.object = object;
        }
    
        @Override
        public void execute() {
            object.acts1();
        }
    
        @Override
        public void undo() {
            object.acts2();
        }
    }
    
    public class Command2 implements Command {
        private Object object;
    
        public Command2(Object object) {
            this.object = object;
        }
    
        @Override
        public void execute() {
            object.acts2();
        }
    
        @Override
        public void undo() {
            object.acts1();
        }
    }
    
    public class Control {
        public void commandExecute(Command command) {
            command.execute();
        }
    
        public void commandUndo(Command command) {
            command.undo();
        }
    }
    
    Control control = new Control();
    Object object = new Object();
    control.commandExecute(new Command1(object));
    control.commandExecute(new Command2(object));
    control.commandUndo(new Command1(object));
    control.commandUndo(new Command2(object));
    

3.7 状态模式

  1. 简介:将状态转移的判断分支抽象成状态,通过实现同一接口完成状态的同一管理,迁移

  2. 示例

    public interface State {
        void stop();
        void move();
    }
    
    public class PlaceA implements State {
        private Player context;
    
        public PlaceA(Player context) {
            this.context = context;
        }
    
        @Override
        public void move() {
            System.out.println("A->B");
            context.setDirection("AB");
            context.setState(context.onMove);
        }
    
        @Override
        public void stop() {
            System.out.println("In place A");
        }
    }
    
    public class PlaceB implements State {
        private Player context;
    
        public PlaceB(Player context) {
            this.context = context;
        }
    
        @Override
        public void move() {
            System.out.println("B->A");
            context.setDirection("BA");
            context.setState(context.onMove);
        }
    
        @Override
        public void stop() {
            System.out.println("In place B");
        }
    }
    
    public class Player {
        State placeA;
        State placeB;
        State onMove;
        private State state;
        private String direction;
    
        public Player() {
            direction = "AB";
            placeA = new PlaceA(this);
            placeB = new PlaceB(this);
            onMove = new OnMove(this);
            this.state = placeA;
        }
    
        public void move() {
            System.out.println("Begin: move");
            state.move();
        }
    
        public void stop() {
            System.out.println("Stop: move");
            state.stop();
        }
    
        public State getState() {
            return state;
        }
    
        public void setState(State state) {
            this.state = state;
        }
    
        public void setDirection(String direction) {
            this.direction = direction;
        }
    
        public String getDirection() {
            return direction;
        }
    }
    
    Player player = new Player();
    player.move();
    player.move();
    player.move();
    
  3. 问题:增加类和对象的数量

3.8 备忘录模式

  1. 简介:快照模式。支持记录对象的某个时刻下的完整状态,并快速返回该状态

  2. 示例

    public interface Memento {
        String getState();
    }
    
    public class MementoImpl implements Memento {
        private String state;
    
        public MementoImpl(String state) {
            this.state = state;
        }
    
        @Override
        public String getState() {
            return state;
        }
    }
    
    public class CareTaker {
        private List<Memento> memotoList = new ArrayList<>();
    
        public void add(Memento memento) {
            memotoList.add(memento);
        }
    
        public Memento get(int index) {
            return memotoList.get(index);
        }
    }
    
    public class Originator {
        private String state;
    
        public String getState() {
            return state;
        }
    
        public void setState(String state) {
            this.state = state;
        }
    
        public Memento saveToMemento() {
            return new MementoImpl(state);
        }
    
        public String getStateFromMemento(Memento memento) {
            return ((Memento) memento).getState();
        }
    }
    
    CareTaker careTaker = new CareTaker();
    Originator originator = new Originator();
    originator.setState("a");
    System.out.println(originator.getState());
    careTaker.add(originator.saveToMemento());
    originator.setState("b");
    System.out.println(originator.getState());
    careTaker.add(originator.saveToMemento());
    System.out.println(originator.getStateFromMemento(careTaker.get(0)));
    System.out.println(originator.getStateFromMemento(careTaker.get(1)));
    
  3. 问题:资源消耗大

3.9 访问者模式

  1. 简介:将数据结构中的各元素的操作分离出来封装成单独的类,可以为元素增加多种访问方式

  2. 示例

    public interface Visitor {
        abstract void visit(Element element);
    }
    
    public class ConcreteVisitor implements Visitor {
        private String name;
    
        public ConcreteVisitor(String name) {
            this.name = name;
        }
    
        @Override
        public void visit(Element element) {
            ConcreteElement concreteElement = (ConcreteElement) element;
            System.out.println(name + " is visiting " + concreteElement.getName());
        }
    }
    
    public interface Element {
        abstract void accept(Visitor visitor);
    }
    
    public class ConcreteElement implements Element {
        private String name;
    
        public ConcreteElement(String name) {
            this.name = name;
        }
    
        @Override
        public void accept(Visitor visitor) {
            visitor.visit(this);
        }
    
        public String getName() {
            return name;
        }
    }
    
    public class ObjectStructure {
        private HashMap<String, ConcreteElement> elements;
    
        public ObjectStructure() {
            elements = new HashMap<>();
        }
    
        public void attach(ConcreteElement element) {
            elements.put(element.getName(), element);
        }
    
        public void detach(ConcreteElement element) {
            elements.remove(element);
        }
    
        public ConcreteElement getElement(String name) {
            return elements.get(name);
        }
    
        public void accept(Visitor visitor) {
            for (ConcreteElement element : elements.values()) {
                element.accept(visitor);
            }
        }
    }
    
    ObjectStructure objectStructure = new ObjectStructure();
    objectStructure.attach(new ConcreteElement("e1"));
    objectStructure.attach(new ConcreteElement("e2"));
    objectStructure.attach(new ConcreteElement("e3"));
    objectStructure.accept(new ConcreteVisitor("v1"));
    objectStructure.accept(new ConcreteVisitor("v2"));
    objectStructure.accept(new ConcreteVisitor("v3"));
    
  3. 问题:增加元素需要在每一个访问者类中增加对应操作,违反“开闭原则”

3.10 中介者模式

  1. 简介:由中介者管理对象之间的通信,使一对多关系简化为一对一的关系

  2. 示例

    public interface Mediator {
        void register(Object object);
        void relay(String from, String to, String ad);
    }
    
    public class ConcreteMediator implements Mediator {
        private List<Object> objects = new ArrayList<>();
    
        @Override
        public void register(Object object) {
            if (!objects.contains(object)) {
                objects.add(object);
                object.setMediator(this);
            }
        }
    
        @Override
        public void relay(String from, String to, String ad) {
            for (Object object : objects) {
                String name = object.getName();
                if (name.equals(to)) {
                    object.receive(from, ad);
                }
            }
        }
    }
    
    public abstract class Object {
        protected Mediator mediator;
        protected String name;
    
        public Object(String name) {
            this.name = name;
        }
    
        public void setMediator(Mediator mediator) {
            this.mediator = mediator;
        }
    
        public String getName() {
            return name;
        }
    
        public abstract void send(String to, String ad);
        public abstract void receive(String from, String ad);
    }
    
    public class ConcreteObject extends Object {
        public ConcreteObject(String name) {
            super(name);
        }
    
        @Override
        public void send(String to, String ad) {
            mediator.relay(name, to, ad);
        }
    
        @Override
        public void receive(String from, String ad) {
            System.out.println(name + " has received message " + ad + " from " + from);
        }
    }
    
    ConcreteObject o1 = new ConcreteObject("o1");
    ConcreteObject o2 = new ConcreteObject("o2");
    ConcreteObject o3 = new ConcreteObject("o3");
    Mediator mediator = new ConcreteMediator();
    mediator.register(o1);
    mediator.register(o2);
    mediator.register(o3);
    o1.send("o2", "hello");
    o2.send("o3", "hi");
    
  3. 问题:当对象类太多时,中介者变得复杂,系统难以维护

目录

ConnectC Is All You Need.