{"id":19864210,"url":"https://github.com/youlookwhat/designpattern","last_synced_at":"2025-04-13T01:59:12.646Z","repository":{"id":37390712,"uuid":"71557631","full_name":"youlookwhat/DesignPattern","owner":"youlookwhat","description":"📚 Java 23种设计模式全归纳","archived":false,"fork":false,"pushed_at":"2022-08-06T13:17:59.000Z","size":4512,"stargazers_count":4905,"open_issues_count":6,"forks_count":1441,"subscribers_count":71,"default_branch":"master","last_synced_at":"2025-04-13T01:58:44.792Z","etag":null,"topics":["designpattern","designpatterns","java"],"latest_commit_sha":null,"homepage":"https://youlookwhat.github.io/DesignPattern","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/youlookwhat.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-10-21T10:59:32.000Z","updated_at":"2025-04-12T13:05:27.000Z","dependencies_parsed_at":"2022-07-09T10:31:19.254Z","dependency_job_id":null,"html_url":"https://github.com/youlookwhat/DesignPattern","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/youlookwhat%2FDesignPattern","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/youlookwhat%2FDesignPattern/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/youlookwhat%2FDesignPattern/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/youlookwhat%2FDesignPattern/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/youlookwhat","download_url":"https://codeload.github.com/youlookwhat/DesignPattern/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248654047,"owners_count":21140235,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["designpattern","designpatterns","java"],"created_at":"2024-11-12T15:17:48.859Z","updated_at":"2025-04-13T01:59:12.620Z","avatar_url":"https://github.com/youlookwhat.png","language":"Java","readme":"# DesignPattern\n设计模式（Design pattern）是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。\n\n设计模式分为三种类型，共23种：\n\n - **创建型模式**：[单例模式](https://github.com/youlookwhat/DesignPattern#3-单例设计模式)、[抽象工厂模式](https://github.com/youlookwhat/DesignPattern#2-工厂模式)、[建造者模式](https://github.com/youlookwhat/DesignPattern#11-建造者模式)、[工厂模式](https://github.com/youlookwhat/DesignPattern#2-工厂模式)、[原型模式](https://github.com/youlookwhat/DesignPattern#12-原型模式)。\n - **结构型模式**：[适配器模式](https://github.com/youlookwhat/DesignPattern#5-适配器模式)、[桥接模式](https://github.com/youlookwhat/DesignPattern#15-桥接模式)、[装饰模式](https://github.com/youlookwhat/DesignPattern#7-装饰者模式)、[组合模式](https://github.com/youlookwhat/DesignPattern#16-组合模式)、[外观模式](https://github.com/youlookwhat/DesignPattern#8-外观模式)、[享元模式](https://github.com/youlookwhat/DesignPattern#13-享元模式)、[代理模式](https://github.com/youlookwhat/DesignPattern#14-代理模式)。\n - **行为型模式**：[模版方法模式](https://github.com/youlookwhat/DesignPattern#9-模板方法模式)、[命令模式](https://github.com/youlookwhat/DesignPattern#6-命令模式)、[迭代器模式](https://github.com/youlookwhat/DesignPattern#17-迭代器模式)、[观察者模式](https://github.com/youlookwhat/DesignPattern#1-观察者模式)、[中介者模式](https://github.com/youlookwhat/DesignPattern#18-中介者模式)、[备忘录模式](https://github.com/youlookwhat/DesignPattern#19-备忘录模式)、[解释器模式](https://github.com/youlookwhat/DesignPattern#20-解释器模式)、[状态模式](https://github.com/youlookwhat/DesignPattern#10-状态模式)、[策略模式](https://github.com/youlookwhat/DesignPattern#4-策略模式)、[责任链模式](https://github.com/youlookwhat/DesignPattern#21-责任链模式)、[访问者模式](https://github.com/youlookwhat/DesignPattern#22-访问者模式)。\n\n\u003e 参照Hongyang、菜鸟教程等处文章所写。如有错误欢迎指正，如有侵权，请联系我删除。\n\n----\n\n\n## Blog Catalogue：\n\n - 1.[ 设计模式 观察者模式(Observer Pattern) 以微信公众服务为例](http://blog.csdn.net/lmj623565791/article/details/24179699)\n\n - 2.[ 设计模式 工厂模式(Factory Pattern) 从卖肉夹馍说起](http://blog.csdn.net/lmj623565791/article/details/24460585)\n\n - 3.[ 设计模式 单例设计模式(Singleton Pattern) 完全解析](http://blog.csdn.net/dmk877/article/details/50311791)\n\n - 4.[ 设计模式 策略模式(Strategy Pattern) 以角色游戏为背景](http://blog.csdn.net/lmj623565791/article/details/24116745)\n\n - 5.[ 设计模式 适配器模式(Adapter Pattern) 以手机充电器为例](http://blog.csdn.net/lmj623565791/article/details/25833393)\n\n - 6.[ 设计模式 命令模式(Command Pattern) 管理智能家电](http://blog.csdn.net/lmj623565791/article/details/24602057)\n\n - 7.[ 设计模式 装饰者模式(Decorator Pattern) 带你重回传奇世界](http://blog.csdn.net/lmj623565791/article/details/24269409)\n\n - 8.[ 设计模式 外观模式(Facade Pattern) 一键电影模式](http://blog.csdn.net/lmj623565791/article/details/25837275)\n\n - 9.[ 设计模式 模版方法模式(Template Method Pattern) 展现程序员的一天](http://blog.csdn.net/lmj623565791/article/details/26276093)\n\n - 10.[ 设计模式 状态模式(State Pattern) 以自动售货机为例](http://blog.csdn.net/lmj623565791/article/details/26350617)\n \n - 11.[ 设计模式 建造者模式(Builder Pattern) 以造汽车买汽车为例](https://wiki.jikexueyuan.com/project/java-design-pattern/builder-pattern.html)\n\n - 12.[ 设计模式 原型模式(Prototype Pattern) 以获取多种形状为例](https://www.runoob.com/design-pattern/prototype-pattern.html)\n\n - 13.[ 设计模式 享元模式(Flyweight Pattern) 以随机获取多种形状为例](https://www.runoob.com/design-pattern/flyweight-pattern.html)\n\n - 14.[ 设计模式 代理模式(Proxy Pattern) 以获取磁盘中的图片为例](https://www.runoob.com/design-pattern/proxy-pattern.html)\n\n - 15.[ 设计模式 桥接模式(Bridge Pattern) 以画不同颜色的圆为例](https://www.runoob.com/design-pattern/bridge-pattern.html)\n\n - 16.[ 设计模式 组合模式(Composite Pattern) 以创建和打印员工的层次结构为例](https://www.runoob.com/design-pattern/composite-pattern.html)\n\n - 17.[ 设计模式 迭代器模式(Iterator Pattern) 以使用迭代器打印名字为例](https://www.runoob.com/design-pattern/iterator-pattern.html)\n\n - 18.[ 设计模式 中介者模式(Mediator Pattern) 以公共聊天室为例](https://www.runoob.com/design-pattern/mediator-pattern.html)\n\n - 19.[ 设计模式 备忘录模式(Memento Pattern) 以使用备忘录为例](https://www.runoob.com/design-pattern/memento-pattern.html)\n\n - 20.[ 设计模式 解释器模式(Interpreter Pattern) 以解释一句话为例](https://www.runoob.com/design-pattern/interpreter-pattern.html)\n\n - 21.[ 设计模式 责任链模式(Chain of Responsibility Pattern) 以Android Studio中打印日志为例](https://www.runoob.com/design-pattern/chain-of-responsibility-pattern.html)\n\n - 22.[ 设计模式 访问者模式(Visitor Pattern) 以显示计算机的组成部分为例](https://www.runoob.com/design-pattern/visitor-pattern.html)\n\n\n## Source Code\n\u003e - [Observer](https://github.com/youlookwhat/DesignPattern/tree/master/app/src/main/java/com/example/jingbin/designpattern/observer)\n\u003e - [Factory](https://github.com/youlookwhat/DesignPattern/tree/master/app/src/main/java/com/example/jingbin/designpattern/factory)\n\u003e - [Singleton](https://github.com/youlookwhat/DesignPattern/tree/master/app/src/main/java/com/example/jingbin/designpattern/singleton)\n\u003e - [Strategy](https://github.com/youlookwhat/DesignPattern/tree/master/app/src/main/java/com/example/jingbin/designpattern/strategy)\n\u003e - [Adapter](https://github.com/youlookwhat/DesignPattern/tree/master/app/src/main/java/com/example/jingbin/designpattern/adapter)\n\u003e - [Command](https://github.com/youlookwhat/DesignPattern/tree/master/app/src/main/java/com/example/jingbin/designpattern/command)\n\u003e - [Decorator](https://github.com/youlookwhat/DesignPattern/tree/master/app/src/main/java/com/example/jingbin/designpattern/decorator)\n\u003e - [Facade](https://github.com/youlookwhat/DesignPattern/tree/master/app/src/main/java/com/example/jingbin/designpattern/facade)\n\u003e - [Template Method](https://github.com/youlookwhat/DesignPattern/tree/master/app/src/main/java/com/example/jingbin/designpattern/templatemethod)\n\u003e - [State](https://github.com/youlookwhat/DesignPattern/tree/master/app/src/main/java/com/example/jingbin/designpattern/state)\n\u003e - [Builder](https://github.com/youlookwhat/DesignPattern/tree/master/app/src/main/java/com/example/jingbin/designpattern/builder)\n\u003e - [Prototype](https://github.com/youlookwhat/DesignPattern/tree/master/app/src/main/java/com/example/jingbin/designpattern/prototype)\n\u003e - [Flyweight](https://github.com/youlookwhat/DesignPattern/tree/master/app/src/main/java/com/example/jingbin/designpattern/flyweight)\n\u003e - [Proxy](https://github.com/youlookwhat/DesignPattern/tree/master/app/src/main/java/com/example/jingbin/designpattern/proxy)\n\u003e - [Bridge](https://github.com/youlookwhat/DesignPattern/tree/master/app/src/main/java/com/example/jingbin/designpattern/bridge)\n\u003e - [Composite](https://github.com/youlookwhat/DesignPattern/tree/master/app/src/main/java/com/example/jingbin/designpattern/composite)\n\u003e - [Iterator](https://github.com/youlookwhat/DesignPattern/tree/master/app/src/main/java/com/example/jingbin/designpattern/iterator)\n\u003e - [Mediator](https://github.com/youlookwhat/DesignPattern/tree/master/app/src/main/java/com/example/jingbin/designpattern/mediator)\n\u003e - [Memento](https://github.com/youlookwhat/DesignPattern/tree/master/app/src/main/java/com/example/jingbin/designpattern/memento)\n\u003e - [Chain of Responsibility](https://github.com/youlookwhat/DesignPattern/tree/master/app/src/main/java/com/example/jingbin/designpattern/chainofresponsibility)\n\u003e - [Visitor](https://github.com/youlookwhat/DesignPattern/tree/master/app/src/main/java/com/example/jingbin/designpattern/visitor)\n\n## Project Picture\n\n![](https://raw.githubusercontent.com/youlookwhat/DesignPattern/master/image/ds1.png)\n![](https://raw.githubusercontent.com/youlookwhat/DesignPattern/master/image/ds2.png)\n\n## Pattern Analysis\n### 1. 观察者模式\n \u003e  定义了对象之间的一对多的依赖，这样一来，当一个对象改变时，它的所有的依赖者都会收到通知并自动更新。\n\n - 对于JDK或者Andorid中都有很多地方实现了观察者模式，比如XXXView.addXXXListenter ， 当然了 XXXView.setOnXXXListener不一定是观察者模式，因为观察者模式是一种一对多的关系，对于setXXXListener是1对1的关系，应该叫回调。\n\n - 专题接口：[Subject.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/observer/interfaces/Subject.java) ;  \n\n\t```java\n\t/**\n\t * 注册一个观察者\n\t */\n\tpublic void registerObserver(Observer observer);\n\t\n\t/**\n\t * 移除一个观察者\n\t */\n\tpublic void removeObserver(Observer observer);\n\t\n\t/**\n\t * 通知所有观察者\n\t */\n\tpublic void notifyObservers();\n\t```\n \n - 3D服务号的实现类：[ObjectFor3D.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/observer/classs/ObjectFor3D.java)\n\n\t```java\n\t@Override\n    public void registerObserver(Observer observer) {\n        observers.add(observer);\n    }\n    @Override\n    public void removeObserver(Observer observer) {\n        int index = observers.indexOf(observer);\n        if (index \u003e= 0) {\n            observers.remove(index);\n        }\n    }\n    @Override\n    public void notifyObservers() {\n        for (Observer observer : observers) {\n            observer.update(msg);\n        }\n    }\n    /**\n     * 主题更新信息\n     */\n    public void setMsg(String msg) {\n        this.msg = msg;\n        notifyObservers();\n    }\n\t```\n \n - 所有观察者需要实现此接口:[Observer.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/observer/interfaces/Observer.java)\n\n\t```java\n\t public ObserverUser1(Subject subject) {\n        subject.registerObserver(this);\n    }\n    @Override\n    public void update(String msg) {\n        Log.e(\"-----ObserverUser1 \", \"得到 3D 号码:\" + msg + \", 我要记下来。\");\n    }\n\t```\n\n- 最后测试：[ObserverActivity.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/observer/ObserverActivity.java)\n\t\n\t```java\n\t// 创建服务号\n    objectFor3D = new ObjectFor3D();\n    // 创建两个订阅者\n    observerUser1 = new ObserverUser1(objectFor3D);\n    observerUser2 = new ObserverUser2(objectFor3D);\n    // 两个观察者,发送两条信息\n    objectFor3D.setMsg(\"201610121 的3D号为:127\");\n    objectFor3D.setMsg(\"20161022 的3D号为:000\");\n\t```\n\t\n\n### 2. 工厂模式\n简单列一下这个模式的家族：\n\n- **1、静态工厂模式**\n\n\t- 这个最常见了，项目中的辅助类，TextUtil.isEmpty等，类+静态方法。\n\n- **2、简单工厂模式（店里买肉夹馍）**\n\t- 定义：通过专门定义一个类来负责创建其他类的实例，被创建的实例通常都具有共同的父类。\n\t- 根据类型直接创建肉夹馍：[SimpleRoujiaMoFactory.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/factory/jdgc/SimpleRoujiaMoFactory.java)\n\t\n\t```java\n\tpublic RoujiaMo creatRoujiaMo(String type) {\n        RoujiaMo roujiaMo = null;\n        switch (type) {\n            case \"Suan\":\n                roujiaMo = new ZSuanRoujiaMo();\n                break;\n            case \"La\":\n                roujiaMo = new ZLaRoujiaMo();\n                break;\n            case \"Tian\":\n                roujiaMo = new ZTianRoujiaMo();\n                break;\n            default:// 默认为酸肉夹馍\n                roujiaMo = new ZSuanRoujiaMo();\n                break;\n        }\n        return roujiaMo;\n    }\n\t```\n\n- **3、工厂方法模式（开分店）**\n\t-  定义：定义一个创建对象的接口，但由子类决定要实例化的类是哪一个。工厂方法模式把类实例化的过程推迟到子类。\n\t-  对比定义：\n  \t - 1、定义了创建对象的一个接口：public abstract RouJiaMo sellRoujiaMo(String type);\n \t - 2、由子类决定实例化的类，可以看到我们的馍是子类生成的。\n - 提供创建肉夹馍店抽象方法：[RoujiaMoStore.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/factory/gcff/RoujiaMoStore.java)\n\n\t ```java\n \tpublic abstract RoujiaMo sellRoujiaMo(String type);\n\t ```\n \n - 具体实现抽象方法：[XianRoujiaMoStore.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/factory/gcff/XianRoujiaMoStore.java)\n - 分店依旧使用简单工厂模式：[XianSimpleRoujiaMoFactory.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/factory/gcff/XianSimpleRoujiaMoFactory.java)\n\n- **4、抽象工厂模式（使用官方提供的原料）**\n\t - 定义：提供一个接口，用于创建相关的或依赖对象的家族，而不需要明确指定具体类。\n\t - 对比定义：\n\t \t- 1、提供一个接口：public interface RouJiaMoYLFactroy\n\t \t- 2、用于创建相关的或依赖对象的家族 public Meat createMeat();public YuanLiao createYuanliao();我们接口用于创建一系列的原材料。\n\t - 创建用于提供原料的接口工厂：[RoujiaMoYLFactory.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/factory/cxgc/RoujiaMoYLFactory.java)\n\t - 各自分店实现接口，完成原料提供：[XianRoujiaMoYLFoctory.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/factory/cxgc/XianRoujiaMoYLFoctory.java)\n\t - 准备时，使用官方的原料：[RoujiaMo.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/factory/cxgc/RoujiaMo.java)\n\t \n\t ```java\n\t /**\n     * 准备工作\n     */\n    public void prepare(RoujiaMoYLFactory roujiaMoYLFactory) {\n        \tMeet meet = roujiaMoYLFactory.creatMeet();\n        \tYuanLiao yuanLiao = roujiaMoYLFactory.creatYuanLiao();\n        \tLog.e(\"---RoujiaMo:\", \"使用官方的原料 ---\" + name + \": 揉面-剁肉-完成准备工作 yuanLiao:\"+meet+\"yuanLiao:\"+yuanLiao);\n    }\n\t ```\n\n### 3. 单例设计模式\n\u003e 单例模式主要是为了避免因为创建了多个实例造成资源的浪费，且多个实例由于多次调用容易导致结果出现错误，而**使用单例模式能够保证整个应用中有且只有一个实例**。\n \n - 定义：只需要三步就可以保证对象的唯一性\n   - (1) 不允许其他程序用new对象\n   - (2) 在该类中创建对象\n   - (3) 对外提供一个可以让其他程序获取该对象的方法\n - 对比定义：\n   - (1) 私有化该类的构造函数\n   - (2) 通过new在本类中创建一个本类对象\n   - (3) 定义一个公有的方法，将在该类中所创建的对象返回\n\n- 饿汉式[可用]：[SingletonEHan.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/singleton/ehan/SingletonEHan.java)\n- 含懒汉式[双重校验锁 推荐用]：[SingletonLanHan.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/singleton/lanhan/SingletonLanHan.java)\n\n ```java\n\t private SingletonLanHan() {}\n\t private static SingletonLanHan singletonLanHanFour;\n\t public static SingletonLanHan getSingletonLanHanFour() {\n\t\t    if (singletonLanHanFour == null) {\n\t\t\tsynchronized (SingletonLanHan.class) {\n\t\t\t    if (singletonLanHanFour == null) {\n\t\t\t\tsingletonLanHanFour = new SingletonLanHan();\n\t\t\t    }\n\t\t\t}\n\t\t    }\n\t\t    return singletonLanHanFour;\n\t}\n    \n ```\n\n- 内部类[推荐用]：[SingletonIn.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/singleton/inclass/SingletonIn.java)\n- 枚举[推荐用]：[SingletonEnum.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/singleton/enums/SingletonEnum.java)\n\n\n### 4. 策略模式\n\u003e 策略模式：定义了算法族，分别封装起来，让它们之间可相互替换，此模式让算法的变化独立于使用算法的客户。\n\n - 以创建游戏角色为例子：\n \t - 最初的游戏角色的父类：[Role.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/strategy/old/Role.java)\n \t - 发现有重复代码后，重构后的父类：[Role.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/strategy/better/Role.java)\n - 总结：\n\t - 1、封装变化（把可能变化的代码封装起来）\n\t - 2、多用组合，少用继承（我们使用组合的方式，为客户设置了算法）\n\t - 3、针对接口编程，不针对实现（对于Role类的设计完全的针对角色，和技能的实现没有关系）\n - 最后测试：创建角色：\n \n ```java\n RoleA roleA = new RoleA(\"---A\");\n roleA.setiDisplayBehavior(new DisplayYZ())\n       .setiAttackBehavior(new AttackXL())\n       .setiDefendBehavior(new DefendTMS())\n       .setiRunBehavior(new RunJCTQ());\n roleA.display();// 样子\n roleA.attack();// 攻击\n roleA.run();// 逃跑\n roleA.defend();// 防御\n ```\n\n### 5. 适配器模式\n\u003e 定义：将一个类的接口转换成客户期望的另一个接口，适配器让原本接口不兼容的类可以相互合作。这个定义还好，说适配器的功能就是把一个接口转成另一个接口。\n\n - 以充电器为实例: 手机充电器一般都是5V左右吧，咱天朝的家用交流电压220V，所以手机充电需要一个适配器（降压器）\n - 一部手机: [Mobile.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/adapter/Mobile.java)\n - 手机依赖一个提供5V电压的接口: [V5Power.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/adapter/V5Power.java)\n - 我们拥有的是220V家用交流电: [V220Power.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/adapter/V220Power.java)\n - **适配器，完成220V转5V的作用**：[V5PowerAdapter.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/adapter/V5PowerAdapter.java)\n - 最后测试：给手机冲个电：\n\n\t```java\n\tMobile mobile = new Mobile();\n   V5Power v5Power = new V5PowerAdapter(new V200Power());\n   mobile.inputPower(v5Power);\n\t```\n\n### 6. 命令模式\n\u003e 定义：将“请求”封装成对象，以便使用不同的请求、队列或者日志来参数化其他对象。命令模式也支持可撤销的操作。(简化: 将请求封装成对象，将动作请求者和动作执行者解耦。)\n\n - 需求：最近智能家电很火热，假设现在有电视、电脑、电灯等家电，现在需要你做个遥控器控制所有家电的开关，要求做到每个按钮对应的功能供用户个性化，对于新买入家电要有非常强的扩展性。\n - 1、家电的API：[Door.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/command/Door.java)\n - 2、把命令封装成类： \n \t- 统一的命令接口：[Command.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/command/Command.java)\n \t- 家电实现该接口：[DoorOpenCommand.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/command/DoorOpenCommand.java)\n - 3、遥控器：[ControlPanel.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/command/ControlPanel.java)\n - 4、定义一个命令，可以干一系列的事情：[QuickCommand.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/command/QuickCommand.java)\n  \n  ```java\n  QuickCommand quickCloseCommand = new QuickCommand(new Command[]{new LightOffCommand(light), new ComputerOffCommand(computer), new DoorCloseCommand(door)});\n  controlPanel.setCommands(6, quickOpenCommand);\n  controlPanel.keyPressed(6);\n  ```\n  \n - 5、遥控器面板执行：[CommandActivity.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/command/CommandActivity.java)\n \n ```java\n controlPanel.setCommands(0, new DoorOpenCommand(door));// 开门\n controlPanel.keyPressed(0);\n ```\n\n### 7. 装饰者模式\n\u003e 装饰者模式：若要扩展功能，装饰者提供了比集成更有弹性的替代方案，动态地将责任附加到对象上。\n\n - 先简单描述下装饰者模式发挥作用的地方，当我们设计好了一个类，我们需要给这个类添加一些辅助的功能，并且不希望改变这个类的代码，这时候就是装饰者模式大展雄威的时候了。这里还体现了一个**原则：类应该对扩展开放，对修改关闭。**\n \n - 需求：设计游戏的装备系统，基本要求，要可以计算出每种装备在镶嵌了各种宝石后的攻击力和描述：\n - 1、装备的超类：[IEquip.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/decorator/IEquip.java)\n - 2、各个装备的实现类：\n   - eg：**武器**的实现类: [ArmEquip.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/decorator/equip/ArmEquip.java)\n\n- 3、装饰品的超类（装饰品也属于装备）：[IEquipDecorator.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/decorator/gem/IEuipDecorator.java)\n- 4、装饰品的实现类：\n  - eg：**蓝宝石**的实现类(可累加): [BlueGemDecorator.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/decorator/gem/BlueGemDecorator.java)\n\n- 5、最后测试：计算攻击力和查看描述：\n\n\t```java\n\tLog.e(\"---\", \"一个镶嵌2颗红宝石,1颗蓝宝石的靴子: \");\n    IEquip iEquip = new RedGemDecorator(new RedGemDecorator(new BlueGemDecorator(new ShoeEquip())));\n    Log.e(\"---\", \"攻击力:\" + iEquip.caculateAttack());\n    Log.e(\"---\", \"描述语:\" + iEquip.description());\n\t```\n\n### 8. 外观模式\n\u003e 定义：提供一个统一的接口，用来访问子系统中的一群接口，外观定义了一个高层的接口，让子系统更容易使用。**其实就是为了方便客户的使用，把一群操作，封装成一个方法。**\n\n - 需求：我比较喜欢看电影，于是买了投影仪、电脑、音响、设计了房间的灯光、买了爆米花机，然后我想看电影的时候，我需要一键观影和一键关闭。\n - 每个设备类的开关等操作：\n  - eg: 爆米花机：[PopcornPopper.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/facade/device/PopcornPopper.java)\n - 电影院类：[HomeTheaterFacade.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/facade/theater/HomeTheaterFacade.java)\n \t\n\t```java\n\t/**\n     * 一键观影\n     */\n    public void watchMovie() {\n        computer.on();\n        light.down();\n        popcornPopper.on();\n        popcornPopper.makePopcorn();\n        projector.on();\n        projector.open();\n        player.on();\n        player.make3DListener();\n    }\n\t```\n\n- 最后测试：一键观影：\n\n\t```java\n\tnew HomeTheaterFacade(computer, light, player, popcornPopper, projector).watchMovie();\n\t```\n\n### 9. 模板方法模式\n\u003e 定义：定义了一个算法的骨架，而将一些步骤延迟到子类中，模版方法使得子类可以在不改变算法结构的情况下，重新定义算法的步骤。\n\n- 需求：简单描述一下：本公司有程序猿、测试、HR、项目经理等人，下面使用模版方法模式，记录下所有人员的上班情况\n- 模板方法模式中的三类角色\n - 1、具体方法(Concrete Method)\n - 2、抽象方法(Abstract Method)\n - 3、钩子方法(Hook Method)\n- 工人的超类：[Worker.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/templatemethod/Worker.java)\n\n\t```java\n\t// 具体方法\n    public final void workOneDay() {\n        Log.e(\"workOneDay\", \"-----------------work start----------------\");\n        enterCompany();\n        work();\n        exitCompany();\n        Log.e(\"workOneDay\", \"-----------------work end----------------\");\n    }\n    // 工作  抽象方法\n    public abstract void work();\n    // 钩子方法\n    public boolean isNeedPrintDate() {\n        return false;\n    }\n    private void exitCompany() {\n        if (isNeedPrintDate()) {\n            Log.e(\"exitCompany\", \"---\" + new Date().toLocaleString() + \"---\u003e\");\n        }\n        Log.e(\"exitCompany\", name + \"---离开公司\");\n    }\n\t```\n- 程序员实现类（可得知时间）：[ITWorker.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/templatemethod/worker/ITWorker.java)\n\t\n\t```java\n\t/**\n     * 重写父类的此方法,使可以查看离开公司时间\n     */\n    @Override\n    public boolean isNeedPrintDate() {\n        return true;\n    }\n\t```\n- 最后测试：\n\t- 查看所有人员的工作情况：\n\t\n\t\t```java\n\t\tQAWorker qaWorker = new QAWorker(\"测试人员\");\n\t    qaWorker();\n\t    HRWorker hrWorker = new HRWorker(\"莉莉姐\");\n\t    hrWorker.workOneDay();\n\t    ...\n\t\t```\n\t- 查看程序猿离开公司的时间:\n\t\t\n\t\t```java\n\t\tITWorker itWorker = new ITWorker(\"jingbin\");\n       itWorker.workOneDay();\n\t\t```\n\n### 10. 状态模式\n\u003e 定义：允许对象在内部状态改变时改变它的行为，对象看起来好像修改了它的类。\n\n - 定义又开始模糊了，理一下，当对象的内部状态改变时，它的行为跟随状态的改变而改变了，看起来好像重新初始化了一个类似的。\n\n - 需求：以自动售货机为例（有已投币、未投币等状态和投币、退币等方法）\n - 最初实现待改进的售货机：[VendingMachine.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/state/old/VendingMachine.java)\n - 改进后的售货机（更具有延展性）:[VendingMachineBetter.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/state/better/VendingMachineBetter.java)\n\n\t```java\n\t// 放钱\n    public void insertMoney() {\n        currentState.insertMoney();\n    }\n    // 退钱\n    public void backMoney() {\n        currentState.backMoney();\n    }\n    // 转动曲柄\n    public void turnCrank() {\n        currentState.turnCrank();\n        if (currentState == soldState || currentState == winnerState) {\n            currentState.dispense();//两种情况会出货\n        }\n    }\n    // 出商品\n    public void dispense() {\n        Log.e(\"VendingMachineBetter\", \"---发出一件商品\");\n        if (count \u003e 0) {\n            count--;\n        }\n    }\n    // 设置对应状态\n    public void setState(State state) {\n        this.currentState = state;\n    }\n\t```\n\n\n - 状态的接口：[State.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/state/better/State.java)\n - 对应状态的接口实现类：\n \t- eg: 中奖状态：[WinnerState.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/state/better/WinnerState.java)\n \t- eg: 售卖状态：[SoldState.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/state/better/SoldState.java)\n \t\t\n- 改进后的售货机测试：\n\t\n\t```java\n\t// 初始化售货机,且里面有3个商品\n   VendingMachineBetter machineBetter = new VendingMachineBetter(3);\n   machineBetter.insertMoney();\n   machineBetter.turnCrank();\n\t```\n\n\n### 11. 建造者模式\n\u003e 建造模式是对象的创建模式。建造模式可以将一个产品的内部表象（internal representation）与产品的生产过程分割开来，从而可以使一个建造过程生成具有不同的内部表象的产品对象。\n\n - 需求：用户去汽车店购买汽车。\n - 分析：汽车店根据每个用户的需求提取对应汽车\n - 建造者超类：[Builder](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/builder/Builder.java)\n\n\t```java\n\tpublic abstract class Builder {\n\t\n\t    public abstract void setPart(String name, String type);\n\t\n\t    public abstract Product getProduct();\n\t}\n\t```\n \n- 建造者对应实现类：[ConcreteBuilder](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/builder/ConcreteBuilder.java)\n\n\t```java\n\tpublic class ConcreteBuilder extends Builder {\n\n\t    private Product product = new Product();\n\t\n\t    @Override\n\t    public void setPart(String name, String type) {\n\t        product.setName(name);\n\t        product.setType(type);\n\t    }\n\t\n\t    @Override\n\t    public Product getProduct() {\n\t        return product;\n\t    }\n\t}\n\t```\n\n- 店长[Director](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/builder/Director.java)取汽车：\n\n\t```java\n\t// 店长\n\tDirector director = new Director();\n\t// 得到宝马汽车，内部实现提取宝马汽车的详情操作\n\tProduct product = director.getBProduct();\n\t// 展示汽车信息\n\tproduct.showProduct();\n\t```\n\n### 12. 原型模式\n\u003e 原型模式是用于创建重复的对象，同时又能保证性能。这种类型的设计模式属于创建型模式，它提供了一种创建对象的最佳方式。\n\n这种模式是实现了一个原型接口，该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时，则采用这种模式。例如，一个对象需要在一个高代价的数据库操作之后被创建。我们可以缓存该对象，在下一个请求时返回它的克隆，在需要的时候更新数据库，以此来减少数据库调用。\n\n以获取多种形状为例，共分四步：\n\n- 1、创建一个实现了 Cloneable 接口的抽象类。[Shape](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/prototype/Shape.java)（implements Cloneable）\n\n\t```java\n\tpublic abstract class Shape implements Cloneable {\n\t\n\t    private String id;\n\t    protected String type;\n\t\n\t    public abstract void draw();\n\t\n\t    public String getId() {\n\t        return id;\n\t    }\n\t\n\t    public void setId(String id) {\n\t        this.id = id;\n\t    }\n\t\n\t    @Override\n\t    public Object clone() {\n\t        Object object = null;\n\t        try {\n\t            object = super.clone();\n\t        } catch (CloneNotSupportedException e) {\n\t            Log.e(\"--\", e.getMessage());\n\t        }\n\t        return object;\n\t    }\n\t}\n\t```\n\n- 2、创建扩展了上面抽象类的实体类。[Circle](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/prototype/shapeimpl/Circle.java)、[Rectangle](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/prototype/shapeimpl/Rectangle.java)、[Square](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/prototype/shapeimpl/Square.java)\n\n\t```java\n\tpublic class Circle extends Shape {\n\t\n\t    public Circle() {\n\t        type = \"Circle\";\n\t    }\n\t\n\t    @Override\n\t    public void draw() {\n\t        Log.e(\"---\", \"Inside Circle::draw() method.\");\n\t    }\n\t    \n\t}\n\t```\n\n- 3、创建一个类，从数据库获取实体类，并把它们存储在一个 Hashtable 中。[ShapeCache](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/prototype/ShapeCache.java)\n\n\t```java\n\tpublic class ShapeCache {\n\t\n\t    private static Hashtable\u003cString, Shape\u003e shapeMap = new Hashtable\u003cString, Shape\u003e();\n\t\n\t    public static Shape getShape(String shapeId) {\n\t        Shape shapeCache = shapeMap.get(shapeId);\n\t        return (Shape) shapeCache.clone();\n\t    }\n\t\n\t    // 对每种形状都运行数据库查询，并创建该形状\n\t    // shapeMap.put(shapeKey, shape);\n\t    // 例如，我们要添加三种形状\n\t    public static void loadCache() {\n\t        Circle circle = new Circle();\n\t        circle.setId(\"1\");\n\t        shapeMap.put(circle.getId(), circle);\n\t\n\t        Rectangle rectangle = new Rectangle();\n\t        rectangle.setId(\"2\");\n\t        shapeMap.put(rectangle.getId(), rectangle);\n\t\n\t        Square square = new Square();\n\t        square.setId(\"3\");\n\t        shapeMap.put(square.getId(), square);\n\t    }\n\t}\n\t```\n\n- 4、使用 ShapeCache 类来获取存储在 Hashtable 中的形状的克隆。\n\n\t```java\n\t// 使用 ShapeCache 类来获取存储在 Hashtable 中的形状的克隆。\n   ShapeCache.loadCache();\n   Shape shapeCache1 = ShapeCache.getShape(\"1\");\n   Shape shapeCache2 = ShapeCache.getShape(\"2\");\n   Shape shapeCache3 = ShapeCache.getShape(\"3\");\n\t```\n\n### 13. 享元模式\n\u003e 主要用于减少创建对象的数量，以减少内存占用和提高性能。这种类型的设计模式属于结构型模式，它提供了减少对象数量从而改善应用所需的对象结构的方式。\n\n享元模式尝试重用现有的同类对象，如果未找到匹配的对象，则创建新对象。我们将通过创建 5 个对象来画出 20 个分布于不同位置的圆来演示这种模式。由于只有 5 种可用的颜色，所以 color 属性被用来检查现有的 Circle 对象。 \n\n - **主要解决**：在有大量对象时，有可能会造成内存溢出，我们把其中共同的部分抽象出来，如果有相同的业务请求，直接返回在内存中已有的对象，避免重新创建。\n\n以随机获取多种形状为例，共分四步：\n\n - 1、创建一个接口。\n\n\t```java\n\tpublic interface Shape {\n\t    void draw();\n\t}\n\t```\n\n - 2、创建实现接口的实体类。\n\n\t```java\n\tpublic class Circle implements Shape {\n\t\n\t    private String color;\n\t    private int x;\n\t    private int y;\n\t    private int radius;\n\t\n\t    public Circle(String color) {\n\t        this.color = color;\n\t    }\n\t\n\t    public void setX(int x) {\n\t        this.x = x;\n\t    }\n\t\n\t    public void setY(int y) {\n\t        this.y = y;\n\t    }\n\t\n\t    public void setRadius(int radius) {\n\t        this.radius = radius;\n\t    }\n\t\n\t    @Override\n\t    public void draw() {\n\t        Log.e(\"---\", \"Circle: Draw() [Color : \" + color\n\t                + \", x : \" + x + \", y :\" + y + \", radius :\" + radius);\n\t    }\n\t}\n\t```\n\n\n - 3、创建一个工厂，生成基于给定信息的实体类的对象。\n\n\t```java\n\tpublic class ShapeFactory {\n\t\n\t    private static final HashMap\u003cString, Shape\u003e circleMap = new HashMap\u003cString, Shape\u003e();\n\t\n\t    public static Shape getShape(String color) {\n\t        Shape shape = circleMap.get(color);\n\t        if (shape == null) {\n\t            shape = new Circle(color);\n\t            circleMap.put(color, shape);\n\t            Log.e(\"getShape\", \"Creating circle of color : \" + color);\n\t        }\n\t        return shape;\n\t    }\n\t\n\t}\n\t```\n\n\n - 4、使用该工厂，通过传递颜色信息来获取实体类的对象。\n\n\t```java\n    for (int i = 0; i \u003c 20; i++) {\n        Circle circle = (Circle) ShapeFactory.getShape(getRandomColor());\n        circle.setX(getRandomX());\n        circle.setY(getRandomY());\n        circle.setRadius(100);\n        circle.draw();\n    }\n\t```\n\n### 14. 代理模式\n\u003e 一个类代表另一个类的功能。在代理模式中，我们创建具有现有对象的对象，以便向外界提供功能接口。可以理解为内存中没有这个对象就创建，有就直接返回这个对象。\n\n - **主要解决**：在直接访问对象时带来的问题，比如说：要访问的对象在远程的机器上。在面向对象系统中，有些对象由于某些原因（比如对象创建开销很大，或者某些操作需要安全控制，或者需要进程外的访问），直接访问会给使用者或者系统结构带来很多麻烦，我们可以在访问此对象时加上一个对此对象的访问层。\n\n以获取磁盘中的图片为例，总共分三步：\n\n - 1、创建一个接口。\n\n\t```java\n\tpublic interface Image {\n\t   void display();\n\t}\n\t```\n\n - 2、创建实现接口的实体类 RealImage。对应代理类：ProxyImage。\n\n\t```java\n\tpublic class RealImage implements Image {\n\t\n\t    private String fileName;\n\t\n\t    public RealImage(String fileName) {\n\t        this.fileName = fileName;\n\t        loadFromDisk(fileName);\n\t    }\n\t\n\t    private void loadFromDisk(String fileName) {\n\t        Log.e(\"RealImage\", \"loading \" + fileName);\n\t    }\n\t\n\t    @Override\n\t    public void display() {\n\t        Log.e(\"RealImage\", \"Displaying \" + fileName);\n\t    }\n\t}\n\t```\n\n\t```java\n\tpublic class ProxyImage implements Image {\n\t\n\t    private String fileName;\n\t    private RealImage realImage;\n\t\n\t    public ProxyImage(String fileName) {\n\t        this.fileName = fileName;\n\t    }\n\t\n\t    @Override\n\t    public void display() {\n\t        if (realImage == null) {\n\t            realImage = new RealImage(fileName);\n\t        }\n\t        realImage.display();\n\t    }\n\t}\n\t```\n\n - 3、当被请求时，使用 ProxyImage 来获取 RealImage 类的对象。\n\n\t```java\n\tImage image = new ProxyImage(\"test_10mb.png\");\n\t// 第一次是new的，图像从磁盘加载\n   image.display();\n   // 第二次取缓存，图像不需要从磁盘加载\n   image.display();\n\t```\n\n### 15. 桥接模式\n\u003e 桥接（Bridge）是用于把抽象化与实现化解耦，使得二者可以独立变化。这种类型的设计模式属于结构型模式，它通过提供抽象化和实现化之间的桥接结构，来实现二者的解耦。\n\n - **主要解决**：在有多种可能会变化的情况下，用继承会造成类爆炸问题，扩展起来不灵活。\n\n以画不同颜色的圆为例，实现共分五步：\n\n - 1、创建桥接实现接口。\n\n\t```java\n\tpublic interface DrawAPI {\n\t    void drawCircle(int radius, int x, int y);\n\t}\n\t```\n\n - 2、创建实现了 DrawAPI 接口的实体桥接实现类。[RedCircle](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/bridge/RedCircle.java)、[GreenCircle](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/bridge/GreenCircle.java)\n\n\t```java\n\tpublic class RedCircle implements DrawAPI {\n\t\n\t    @Override\n\t    public void drawCircle(int radius, int x, int y) {\n\t        Log.e(\"---\", \"Drawing Circle[ color: red, radius: \"\n\t                + radius + \", x: \" + x + \", \" + y + \"]\");\n\t    }\n\t}\n\t```\n\n - 3、使用 DrawAPI 接口创建抽象类 [Shape](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/bridge/Shape.java)。\n\n\t```java\n\tpublic abstract class Shape {\n\t\n\t    protected DrawAPI drawAPI;\n\t\n\t    protected Shape(DrawAPI drawAPI) {\n\t        this.drawAPI = drawAPI;\n\t    }\n\t\n\t    public abstract void draw();\n\t}\n\t```\n\n - 4、创建实现了 Shape 接口的实体类。\n\n\t```java\n\tpublic class Circle extends Shape {\n\t\n\t    private int x, y, radius;\n\t\n\t    protected Circle(int x, int y, int radius, DrawAPI drawAPI) {\n\t        super(drawAPI);\n\t        this.x = x;\n\t        this.y = y;\n\t        this.radius = radius;\n\t    }\n\t\n\t    @Override\n\t    public void draw() {\n\t        drawAPI.drawCircle(radius, x, y);\n\t    }\n\t}\n\t```\n\n - 5、使用 Shape 和 DrawAPI 类画出不同颜色的圆。\n\n\t```java\n    // 画红圆\n    Circle circle = new Circle(10, 10, 100, new RedCircle());s\n    circle.draw();\n    // 画绿圆\n    Circle circle2 = new Circle(20, 20, 100, new GreenCircle());\n    circle2.draw();\n\t```\n\n### 16. 组合模式\n\u003e 又叫部分整体模式，是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象，用来表示部分以及整体层次。这种类型的设计模式属于结构型模式，它创建了对象组的树形结构。\n\n - **主要解决**：它在我们树型结构的问题中，模糊了简单元素和复杂元素的概念，客户程序可以像处理简单元素一样来处理复杂元素，从而使得客户程序与复杂元素的内部结构解耦。\n\n以创建和打印员工的层次结构为例，最小单元示例：\n\n - 1、创建 Employee 类，该类带有 Employee 对象的列表。\n\n\t```java\n\tpublic class Employee {\n\t\n\t    private String name;\n\t    // 部门\n\t    private String dept;\n\t    // 工资\n\t    private int salary;\n\t    // 员工 list\n\t    private List\u003cEmployee\u003e subordinates;\n\t\n\t    public Employee(String name, String dept, int salary) {\n\t        this.name = name;\n\t        this.dept = dept;\n\t        this.salary = salary;\n\t        this.subordinates = new ArrayList\u003cEmployee\u003e();\n\t    }\n\t\n\t    public void add(Employee e) {\n\t        subordinates.add(e);\n\t    }\n\t\n\t    public void remove(Employee e) {\n\t        subordinates.remove(e);\n\t    }\n\t\n\t    public List\u003cEmployee\u003e getSubordinates() {\n\t        return subordinates;\n\t    }\n\t\n\t    @Override\n\t    public String toString() {\n\t        return \"Employee{\" +\n\t                \"name='\" + name + '\\'' +\n\t                \", dept='\" + dept + '\\'' +\n\t                \", salary=\" + salary +\n\t                \", subordinates=\" + subordinates +\n\t                '}';\n\t    }\n\t}\n\t```\n\n - 2.使用 Employee 类来创建和打印员工的层次结构。\n\n\t```java\n    final Employee ceo = new Employee(\"John\", \"CEO\", 30000);\n\n    Employee headSales = new Employee(\"Robert\", \"Head sales\", 20000);\n\n    Employee headMarketing = new Employee(\"Michel\", \"Head Marketing\", 20000);\n\n    Employee clerk1 = new Employee(\"Laura\", \"Marketing\", 10000);\n    Employee clerk2 = new Employee(\"Bob\", \"Marketing\", 10000);\n\n    Employee salesExecutive1 = new Employee(\"Richard\", \"Sales\", 10000);\n    Employee salesExecutive2 = new Employee(\"Rob\", \"Sales\", 10000);\n\n    ceo.add(headSales);\n    ceo.add(headMarketing);\n\n    headSales.add(salesExecutive1);\n    headSales.add(salesExecutive2);\n\n    headMarketing.add(clerk1);\n    headMarketing.add(clerk2);\n    \n    Log.e(\"---\", ceo.toString());\n    \n    // 打印\n    /*\n     * Employee{name='John', dept='CEO', salary=30000,\n     * subordinates=[Employee{name='Robert', dept='Head sales', salary=20000,\n     * subordinates=[\n     * Employee{name='Richard', dept='Sales', salary=10000, subordinates=[]},\n     * Employee{name='Rob', dept='Sales', salary=10000, subordinates=[]}]},\n     * Employee{name='Michel', dept='Head Marketing', salary=20000,\n     * subordinates=[Employee{name='Laura', dept='Marketing', salary=10000, subordinates=[]},\n     * Employee{name='Bob', dept='Marketing', salary=10000, subordinates=[]}]}]}\n     */\n\t```\n\n### 17. 迭代器模式\n\u003e  Java 和 .Net 编程环境中非常常用的设计模式。这种模式用于顺序访问集合对象的元素，不需要知道集合对象的底层表示。迭代器模式属于行为型模式。\n\n - **主要解决**：不同的方式来遍历整个整合对象。\n\n以使用迭代器打印名字为例，总共分三步：\n \n - 1、创建接口:\n\n\t```java\n\tpublic interface Iterator {\n\t\n\t    public boolean hasNext();\n\t\n\t    public Object next();\n\t}\n\t```\n\n\t```java\n\tpublic interface Container {\n\t    public Iterator getIterator();\n\t}\n\t```\n\n- 2、创建实现了 Container 接口的实体类。该类有实现了 Iterator 接口的内部类 NameIterator。\n\n\t```java\n\tpublic class NameRepository implements Container {\n\t\n\t    private String names[] = {\"John\", \"jingbin\", \"youlookwhat\", \"lookthis\"};\n\t\n\t    @Override\n\t    public Iterator getIterator() {\n\t        return new NameIterator();\n\t    }\n\t\n\t    private class NameIterator implements Iterator {\n\t\n\t        int index;\n\t\n\t        @Override\n\t        public boolean hasNext() {\n\t            if (index \u003c names.length) {\n\t                return true;\n\t            }\n\t            return false;\n\t        }\n\t\n\t        @Override\n\t        public Object next() {\n\t            if (hasNext()) {\n\t                return names[index++];\n\t            }\n\t            return null;\n\t        }\n\t    }\n\t\n\t}\n\t```\n\n- 3、使用 NameRepository 来获取迭代器，并打印名字。\n\n\t```java\n    NameRepository nameRepository = new NameRepository();\n    for (Iterator iterator = nameRepository.getIterator(); iterator.hasNext(); ) {\n        String name = (String) iterator.next();\n        Log.e(\"---\", name);\n        /*\n         * /---: John\n         * /---: jingbin\n         * /---: youlookwhat\n         * /---: lookthis\n         */\n    }\n\t```\n\n### 18. 中介者模式\n\u003e 用来降低多个对象和类之间的通信复杂性。这种模式提供了一个中介类，该类通常处理不同类之间的通信，并支持松耦合，使代码易于维护。中介者模式属于行为型模式。\n\n - **主要解决**：对象与对象之间存在大量的关联关系，这样势必会导致系统的结构变得很复杂，同时若一个对象发生改变，我们也需要跟踪与之相关联的对象，同时做出相应的处理。\n\n以公共聊天室为例，最小单元示例步骤：\n\n - 1、创建中介类。\n\n\t```java\n\tpublic class CharRoom {\n\t    public static void showMessage(User user, String message) {\n\t        Log.e(\"---\", new Date().toString()\n\t                + \" [\" + user.getName() + \"] : \" + message);\n\t    }\n\t}\n\t```\n\n - 2、创建 user 类。\n\n\t```java\n\tpublic class User {\n\t    private String name;\n\t\n\t    public User(String name) {\n\t        this.name = name;\n\t    }\n\t\n\t    public String getName() {\n\t        return name;\n\t    }\n\t\n\t    public void setName(String name) {\n\t        this.name = name;\n\t    }\n\t\n\t    public void sendMessage(String message) {\n\t    \t  // 使用中介类\n\t        CharRoom.showMessage(this, message);\n\t    }\n\t}\n\t```\n\n - 3、使用 User 对象来显示他们之间的通信。\n\n\t```java\n        User jingbin = new User(\"jingbin\");\n        jingbin.sendMessage(\"Hi~ youlookwhat!\");\n        //---: Sun Feb 02 08:11:47 GMT+00:00 2020 [jingbin] : Hi~ youlookwhat!\n        \n        User jingbin = new User(\"youlookwhat\");\n        jingbin.sendMessage(\"Hi~ jingbin!\");\n        //---: Sun Feb 02 08:11:49 GMT+00:00 2020 [youlookwhat] : Hi~ jingbin!\n\t```\n\n### 19. 备忘录模式\n\u003e 保存一个对象的某个状态，以便在适当的时候恢复对象。备忘录模式属于行为型模式。\n\n- **主要解决**：所谓备忘录模式就是在不破坏封装的前提下，捕获一个对象的内部状态，并在该对象之外保存这个状态，这样可以在以后将对象恢复到原先保存的状态。\n\n以使用备忘录为例，最小单元步骤：\n\n - 1、创建 备忘录 Memento 类。\n\n\t```java\n\tpublic class Memento {\n\t\n\t\tprivate String state;\n\t\t\n\t\tpublic Memento(String state) {\n\t\t    this.state = state;\n\t\t}\n\t\t\n\t\tpublic String getState() {\n\t\t    return state;\n\t\t}\n\t\t\n\t\tpublic void setState(String state) {\n\t\t    this.state = state;\n\t\t}\n\t}\n\t```\n\n - 2、创建 Originator 类。\n\n\t```java\n\tpublic class Originator {\n\t\n\t    private String state;\n\t\n\t    public String getState() {\n\t        return state;\n\t    }\n\t\n\t    public void setState(String state) {\n\t        this.state = state;\n\t    }\n\t\n\t    public Memento setSateToMemento() {\n\t        return new Memento(state);\n\t    }\n\t\n\t    public String getStateFromMemento(Memento memento) {\n\t        return memento.getState();\n\t    }\n\t}\n\t```\n\n - 3、创建 CareTaker 类。\n\n\t```java\n\tpublic class CareTaker {\n\t\n\t    private List\u003cMemento\u003e mementoList = new ArrayList\u003cMemento\u003e();\n\t\n\t    public void add(Memento memento) {\n\t        mementoList.add(memento);\n\t    }\n\t\n\t    public Memento get(int index) {\n\t        return mementoList.get(index);\n\t    }\n\t}\n\t```\n \n - 4、使用 CareTaker 和 Originator 对象。\n\n\t```java\n   // 管理者\n    CareTaker careTaker = new CareTaker();\n\n    Originator originator = new Originator();\n    originator.setState(\"State #1\");\n    originator.setState(\"State #2\");\n\n    // 保存状态\n    careTaker.add(originator.setSateToMemento());\n\n    originator.setState(\"State #3\");\n\n    // 保存状态\n    careTaker.add(originator.setSateToMemento());\n\n    originator.setState(\"State #4\");\n\n    Log.e(\"---\", \"Current State: \" + originator.getState());\n    // 得到保存的状态\n    String fromMemento1 = originator.getStateFromMemento(careTaker.get(0));\n    Log.e(\"---\", \"First Saved State: \" + fromMemento1);\n    String fromMemento2 = originator.getStateFromMemento(careTaker.get(1));\n    Log.e(\"---\", \"Second Saved State: \" + fromMemento2);\n\n    /*\n     * /---: Current State: State #4\n     * /---: First Saved State: State #2\n     * /---: Second Saved State: State #3\n     */\n\t```\n\n### 20. 解释器模式\n\u003e 提供了评估语言的语法或表达式的方式，它属于行为型模式。这种模式实现了一个表达式接口，该接口解释一个特定的上下文。这种模式被用在 SQL 解析、符号处理引擎等。\n\n - **主要解决**：对于一些固定文法构建一个解释句子的解释器。\n\n以解释一句话为例，最小单元步骤：\n\n - 1、创建一个表达式接口 Expression。\n\n\t```java\n\tpublic interface Expression {\n\t    public boolean interpreter(String content);\n\t}\n\t```\n\n - 2、创建实现了上述接口的实体类。TerminalExpression、OrExpression、AndExpression。\n\n\t```java\n\tpublic class TerminalExpression implements Expression {\n\t\n\t\tprivate String data;\n\t\t\n\t\tpublic TerminalExpression(String data) {\n\t\t    this.data = data;\n\t\t}\n\t\t\n\t\t@Override\n\t\tpublic boolean interpreter(String content) {\n\t\t   // 是包含判断\n\t\t    return content.contains(data);\n\t\t}\n\t}\n\t```\n\n\t```java\n\tpublic class OrExpression implements Expression {\n\t\n\t    private Expression expression1;\n\t    private Expression expression2;\n\t\n\t    public OrExpression(Expression expression1, Expression expression2) {\n\t        this.expression1 = expression1;\n\t        this.expression2 = expression2;\n\t    }\n\t\n\t    @Override\n\t    public boolean interpreter(String content) {\n\t        return expression1.interpreter(content) || expression2.interpreter(content);\n\t    }\n\t}\n\t```\n\n\t```java\n\tpublic class AndExpression implements Expression {\n\t\n\t    private Expression expression1;\n\t    private Expression expression2;\n\t\n\t    public AndExpression(Expression expression1, Expression expression2) {\n\t        this.expression1 = expression1;\n\t        this.expression2 = expression2;\n\t    }\n\t\n\t    @Override\n\t    public boolean interpreter(String content) {\n\t        return expression1.interpreter(content) \u0026\u0026 expression2.interpreter(content);\n\t    }\n\t}\n\t```\n\n - 3、使用 Expression 类来创建规则，并解析它们。\n\n\t```java\n    /**\n     * 规则：jingbin 和 youlookwhat 是男性\n     */\n    public static Expression getMaleExpression() {\n        TerminalExpression jingbin = new TerminalExpression(\"jingbin\");\n        TerminalExpression youlookwhat = new TerminalExpression(\"youlookwhat\");\n        return new OrExpression(jingbin, youlookwhat);\n    }\n\n    /**\n     * 规则：Julie 是一个已婚的女性\n     */\n    public static Expression getMarriedWomanExpression() {\n        TerminalExpression julie = new TerminalExpression(\"Julie\");\n        TerminalExpression married = new TerminalExpression(\"Married\");\n        return new AndExpression(julie, married);\n    }\n\n\tExpression maleExpression = getMaleExpression();\n\t// jingbin is male: true\n\tLog.e(\"---\", \"jingbin is male: \" + maleExpression.interpreter(\"jingbin\"));\n\n    Expression womanExpression = getMarriedWomanExpression();\n    // Julie is married woman: true\n    Log.e(\"---\", \"Julie is married woman: \" + womanExpression.interpreter(\"Married Julie\"));\n\n\t```\n\n\n### 21. 责任链模式\n\u003e 责任链模式（Chain of Responsibility Pattern）为请求创建了一个接收者对象的链。这种模式给予请求的类型，对请求的发送者和接收者进行解耦。这种类型的设计模式属于行为型模式。**在这种模式中，通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求，那么它会把相同的请求传给下一个接收者，依此类推。**\n\n - **主要解决**：职责链上的处理者负责处理请求，客户只需要将请求发送到职责链上即可，无须关心请求的处理细节和请求的传递，所以职责链将请求的发送者和请求的处理者解耦了。\n\n以Android Studio中打印日志为例，最小单元步骤：\n\n - 1、创建抽象的记录器类 AbstractLogger。\n\n\t```java\n\tpublic abstract class AbstractLogger {\n\t\n\t    public static int INFO = 1;\n\t    public static int DEBUG = 2;\n\t    public static int ERROR = 3;\n\t\n\t    protected int level;\n\t\n\t    // 责任链中的下一个元素\n\t    protected AbstractLogger nextLogger;\n\t\n\t    public void setNextLogger(AbstractLogger nextLogger) {\n\t        this.nextLogger = nextLogger;\n\t    }\n\t\n\t    public void logMessage(int level, String message) {\n\t        if (this.level \u003c= level) {\n\t            write(message);\n\t        }\n\t        // 递归效果，不断调用下一级 logMessage\n\t        if (nextLogger != null) {\n\t            nextLogger.logMessage(level, message);\n\t        }\n\t    }\n\t\n\t    protected abstract void write(String message);\n\t}\n\t```\n\n- 2、创建扩展了该记录器类的实体类。\n\n\t```java\n\tpublic class ConsoleLogger extends AbstractLogger {\n\t\n\t    public ConsoleLogger(int level) {\n\t        this.level = level;\n\t    }\n\t\n\t    @Override\n\t    protected void write(String message) {\n\t        Log.e(\"---\", \"Standard Console::Logger  \" + message);\n\t    }\n\t}\n\t```\n\n\t```java\n\tpublic class FileLogger extends AbstractLogger {\n\t\n\t    public FileLogger(int level) {\n\t        this.level = level;\n\t    }\n\t\n\t    @Override\n\t    protected void write(String message) {\n\t        Log.e(\"---\", \"File::Logger  \" + message);\n\t    }\n\t}\n\t```\n\n\t```java\n\tpublic class ErrorLogger extends AbstractLogger {\n\t\n\t    public ErrorLogger(int level) {\n\t        this.level = level;\n\t    }\n\t\n\t    @Override\n\t    protected void write(String message) {\n\t        Log.e(\"---\", \"Error Console::Logger  \" + message);\n\t    }\n\t}\n\t```\n\n- 3、创建不同类型的记录器。赋予它们不同的错误级别，并在每个记录器中设置下一个记录器。每个记录器中的下一个记录器代表的是链的一部分。\n\n\t```java\n\tpublic static AbstractLogger getChainOfLoggers() {\n        ErrorLogger errorLogger = new ErrorLogger(AbstractLogger.ERROR);\n        FileLogger fileLogger = new FileLogger(AbstractLogger.DEBUG);\n        ConsoleLogger consoleLogger = new ConsoleLogger(AbstractLogger.INFO);\n        errorLogger.setNextLogger(fileLogger);\n        fileLogger.setNextLogger(consoleLogger);\n        return errorLogger;\n\t}\n\t\n\tAbstractLogger logger = getChainOfLoggers();\n\t\n    // ---: Standard Console::Logger  this is an information.\n    logger.logMessage(AbstractLogger.INFO, \"this is an information.\");\n    \n    // ---: File::Logger  this is a debug level information.\n    // ---: Standard Console::Logger  this is a debug level information.\n    logger.logMessage(AbstractLogger.DEBUG, \"this is a debug level information.\");\n\n    // ---: Error Console::Logger  this is a error level information.\n    // ---: File::Logger  this is a error level information.\n    // ---: Standard Console::Logger  this is a error level information.\n    logger.logMessage(AbstractLogger.ERROR, \"this is a error level information.\");\n\n\t```\n\n### 22. 访问者模式\n\u003e 在访问者模式中，我们使用了一个访问者类，它改变了元素类的执行算法。通过这种方式，元素的执行算法可以随着访问者改变而改变。这种类型的设计模式属于行为型模式。根据模式，元素对象已接受访问者对象，这样访问者对象就可以处理元素对象上的操作。\n\n - **主要解决**：稳定的数据结构和易变的操作耦合问题。\n\n以显示计算机的组成部分为例，主要分五步实现：\n\n - 1、定义一个表示元素的接口。\n\n\t```java\n\tpublic interface ComputerPart {\n\t    public void accept(ComputerPartVisitor computerPartVisitor);\n\t}\n\t```\n\n - 2、创建扩展了上述类的实体类。[Keyboard](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/visitor/impl/Keyboard.java)、[Monitor](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/visitor/impl/Monitor.java)、[Mouse](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/visitor/impl/Mouse.java)、[Computer](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/visitor/impl/Computer.java)\n\n\t```java\n\tpublic class Computer implements ComputerPart {\n\t\n\t    private ComputerPart[] parts;\n\t\n\t    public Computer() {\n\t        this.parts = new ComputerPart[]{new Mouse(), new Keyboard(), new Monitor()};\n\t    }\n\t\n\t    @Override\n\t    public void accept(ComputerPartVisitor computerPartVisitor) {\n\t        for (ComputerPart part : parts) {\n\t            part.accept(computerPartVisitor);\n\t        }\n\t        computerPartVisitor.visit(this);\n\t    }\n\t}\n\t```\n\n\t```java\n\tpublic class Mouse implements ComputerPart {\n\t    @Override\n\t    public void accept(ComputerPartVisitor computerPartVisitor) {\n\t        computerPartVisitor.visit(this);\n\t    }\n\t}\n\t```\n\n - 3、定义一个表示访问者的接口。\n\n\t```java\n\tpublic interface ComputerPartVisitor {\n\t\n\t    public void visit(Computer computer);\n\t\n\t    public void visit(Mouse mouse);\n\t\n\t    public void visit(Keyboard keyboard);\n\t\n\t    public void visit(Monitor monitor);\n\t}\n\t```\n\n - 4、创建实现了上述类的实体访问者。\n\n\t```java\n\tpublic class ComputerPartDisplayVisitor implements ComputerPartVisitor {\n\t\n\t    @Override\n\t    public void visit(Computer computer) {\n\t        Log.e(\"---\", \"Displaying Computer.\");\n\t    }\n\t\n\t    @Override\n\t    public void visit(Mouse mouse) {\n\t        Log.e(\"---\", \"Displaying Mouse.\");\n\t    }\n\t\n\t    @Override\n\t    public void visit(Keyboard keyboard) {\n\t        Log.e(\"---\", \"Displaying Keyboard.\");\n\t    }\n\t\n\t    @Override\n\t    public void visit(Monitor monitor) {\n\t        Log.e(\"---\", \"Displaying Monitor.\");\n\t    }\n\t}\n\t```\n\n - 5、使用 ComputerPartDisplayVisitor 来显示 Computer 的组成部分。\n\n\t```java\n        ComputerPart computer = new Computer();\n        computer.accept(new ComputerPartDisplayVisitor());\n        /*\n\t     *打印：\n\t     *---: Displaying Mouse.\n\t     *---: Displaying Keyboard.\n\t     *---: Displaying Monitor.\n\t     *---: Displaying Computer.\n\t     */\n\t```\n\n\n## Download\n - [DesignPattern.apk](https://download.csdn.net/download/jingbin_/12146492)\n\n## Reference \n - [CSDN：张鸿洋](http://blog.csdn.net/lmj623565791/article/category/2206597)\n - [CSDN：dmk877](http://blog.csdn.net/dmk877/article/details/50311791)\n - [菜鸟教程：设计模式](https://www.runoob.com/design-pattern/design-pattern-intro.html)\n\n\n## About me\n - **QQ：** 770413277\n - **掘金：**[https://juejin.im/user/56eec46d1ea49300555a176b/posts](https://juejin.im/user/56eec46d1ea49300555a176b/posts)\n - **简书：**[https://www.jianshu.com/u/e43c6e979831](https://www.jianshu.com/u/e43c6e979831)\n - **Email：** jingbin127@163.com\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyoulookwhat%2Fdesignpattern","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyoulookwhat%2Fdesignpattern","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyoulookwhat%2Fdesignpattern/lists"}