# DesignPattern **Repository Path**: moyongjun/DesignPattern ## Basic Information - **Project Name**: DesignPattern - **Description**: 设计模式示例Demo - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2019-12-03 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # DesignPattern > 参照Hongyang的CSDN博客所写。如有错误欢迎指正,如有侵权,请联系我删除。 #### Java 设计模式(观察者模式、工厂模式、单例模式、策略模式、命令模式、装饰者模式、外观模式、模板方法模式、状态模式) > 设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。 设计模式分为三种类型,共23种: - **创建型模式**:[单例模式](https://github.com/youlookwhat/DesignPattern#3-单例设计模式)、抽象工厂模式、建造者模式、[工厂模式](https://github.com/youlookwhat/DesignPattern#2-工厂模式)、原型模式。 - **结构型模式**:[适配器模式](https://github.com/youlookwhat/DesignPattern#5-适配器模式)、桥接模式、[装饰模式](https://github.com/youlookwhat/DesignPattern#7-装饰者模式)、组合模式、[外观模式](https://github.com/youlookwhat/DesignPattern#8-外观模式)、享元模式、代理模式。 - **行为型模式**:[模版方法模式](https://github.com/youlookwhat/DesignPattern#9-模板方法模式)、[命令模式](https://github.com/youlookwhat/DesignPattern#6-命令模式)、迭代器模式、[观察者模式](https://github.com/youlookwhat/DesignPattern#1-观察者模式)、中介者模式、备忘录模式、解释器模式、[状态模式](https://github.com/youlookwhat/DesignPattern#10-状态模式)、[策略模式](https://github.com/youlookwhat/DesignPattern#4-策略模式)、职责链模式(责任链模式)、访问者模式。 ---- ## Blog Catalogue: - 1.[ 设计模式 观察者模式(Observer Pattern) 以微信公众服务为例](http://blog.csdn.net/lmj623565791/article/details/24179699) - 2.[ 设计模式 工厂模式(Factory Pattern) 从卖肉夹馍说起](http://blog.csdn.net/lmj623565791/article/details/24460585) - 3.[ 设计模式 单例设计模式(Singleton Pattern) 完全解析](http://blog.csdn.net/dmk877/article/details/50311791) - 4.[ 设计模式 策略模式(Strategy Pattern) 以角色游戏为背景](http://blog.csdn.net/lmj623565791/article/details/24116745) - 5.[ 设计模式 适配器模式(Adapter Pattern) 以手机充电器为例](http://blog.csdn.net/lmj623565791/article/details/25833393) - 6.[ 设计模式 命令模式(Command Pattern) 管理智能家电](http://blog.csdn.net/lmj623565791/article/details/24602057) - 7.[ 设计模式 装饰者模式(Decorator Pattern) 带你重回传奇世界](http://blog.csdn.net/lmj623565791/article/details/24269409) - 8.[ 设计模式 外观模式(Facade Pattern) 一键电影模式](http://blog.csdn.net/lmj623565791/article/details/25837275) - 9.[ 设计模式 模版方法模式(Template Method Pattern) 展现程序员的一天](http://blog.csdn.net/lmj623565791/article/details/26276093) - 10.[ 设计模式 状态模式(State Pattern) 以自动售货机为例](http://blog.csdn.net/lmj623565791/article/details/26350617) ## Source Code > - 1. [Observer](https://github.com/youlookwhat/DesignPattern/tree/master/app/src/main/java/com/example/jingbin/designpattern/observer) > - 2. [Factory](https://github.com/youlookwhat/DesignPattern/tree/master/app/src/main/java/com/example/jingbin/designpattern/factory) > - 3. [Singleton](https://github.com/youlookwhat/DesignPattern/tree/master/app/src/main/java/com/example/jingbin/designpattern/singleton) > - 4. [Strategy](https://github.com/youlookwhat/DesignPattern/tree/master/app/src/main/java/com/example/jingbin/designpattern/strategy) > - 5. [Adapter](https://github.com/youlookwhat/DesignPattern/tree/master/app/src/main/java/com/example/jingbin/designpattern/adapter) > - 6. [Command](https://github.com/youlookwhat/DesignPattern/tree/master/app/src/main/java/com/example/jingbin/designpattern/command) > - 7. [Decorator](https://github.com/youlookwhat/DesignPattern/tree/master/app/src/main/java/com/example/jingbin/designpattern/decorator) > - 8. [Facade](https://github.com/youlookwhat/DesignPattern/tree/master/app/src/main/java/com/example/jingbin/designpattern/facade) > - 9. [Template Method](https://github.com/youlookwhat/DesignPattern/tree/master/app/src/main/java/com/example/jingbin/designpattern/templatemethod) > - 10. [State](https://github.com/youlookwhat/DesignPattern/tree/master/app/src/main/java/com/example/jingbin/designpattern/state) ## Project Picture ## Pattern Analysis ### 1. 观察者模式 > 定义了对象之间的一对多的依赖,这样一来,当一个对象改变时,它的所有的依赖者都会收到通知并自动更新。 - 对于JDK或者Andorid中都有很多地方实现了观察者模式,比如XXXView.addXXXListenter , 当然了 XXXView.setOnXXXListener不一定是观察者模式,因为观察者模式是一种一对多的关系,对于setXXXListener是1对1的关系,应该叫回调。 - 专题接口:[Subject.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/observer/interfaces/Subject.java) ; ```java /** * 注册一个观察者 */ public void registerObserver(Observer observer); /** * 移除一个观察者 */ public void removeObserver(Observer observer); /** * 通知所有观察者 */ public void notifyObservers(); ``` - 3D服务号的实现类:[ObjectFor3D.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/observer/classs/ObjectFor3D.java) ```java @Override public void registerObserver(Observer observer) { observers.add(observer); } @Override public void removeObserver(Observer observer) { int index = observers.indexOf(observer); if (index >= 0) { observers.remove(index); } } @Override public void notifyObservers() { for (Observer observer : observers) { observer.update(msg); } } /** * 主题更新信息 */ public void setMsg(String msg) { this.msg = msg; notifyObservers(); } ``` - 所有观察者需要实现此接口:[Observer.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/observer/interfaces/Observer.java) ```java public ObserverUser1(Subject subject) { subject.registerObserver(this); } @Override public void update(String msg) { Log.e("-----ObserverUser1 ", "得到 3D 号码:" + msg + ", 我要记下来。"); } ``` - 最后测试:[ObserverActivity.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/observer/ObserverActivity.java) ```java // 创建服务号 objectFor3D = new ObjectFor3D(); // 创建两个订阅者 observerUser1 = new ObserverUser1(objectFor3D); observerUser2 = new ObserverUser2(objectFor3D); // 两个观察者,发送两条信息 objectFor3D.setMsg("201610121 的3D号为:127"); objectFor3D.setMsg("20161022 的3D号为:000"); ``` ### 2. 工厂模式 简单列一下这个模式的家族: - **1、静态工厂模式** - 这个最常见了,项目中的辅助类,TextUtil.isEmpty等,类+静态方法。 - **2、简单工厂模式(店里买肉夹馍)** - 定义:通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。 - 根据类型直接创建肉夹馍:[SimpleRoujiaMoFactory.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/factory/jdgc/SimpleRoujiaMoFactory.java) ```java public RoujiaMo creatRoujiaMo(String type) { RoujiaMo roujiaMo = null; switch (type) { case "Suan": roujiaMo = new ZSuanRoujiaMo(); break; case "La": roujiaMo = new ZLaRoujiaMo(); break; case "Tian": roujiaMo = new ZTianRoujiaMo(); break; default:// 默认为酸肉夹馍 roujiaMo = new ZSuanRoujiaMo(); break; } return roujiaMo; } ``` - **3、工厂方法模式(开分店)** - 定义:定义一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法模式把类实例化的过程推迟到子类。 - 对比定义: - 1、定义了创建对象的一个接口:public abstract RouJiaMo sellRoujiaMo(String type); - 2、由子类决定实例化的类,可以看到我们的馍是子类生成的。 - 提供创建肉夹馍店抽象方法:[RoujiaMoStore.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/factory/gcff/RoujiaMoStore.java) ```java public abstract RoujiaMo sellRoujiaMo(String type); ``` - 具体实现抽象方法:[XianRoujiaMoStore.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/factory/gcff/XianRoujiaMoStore.java) - 分店依旧使用简单工厂模式:[XianSimpleRoujiaMoFactory.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/factory/gcff/XianSimpleRoujiaMoFactory.java) - **4、抽象工厂模式(使用官方提供的原料)** - 定义:提供一个接口,用于创建相关的或依赖对象的家族,而不需要明确指定具体类。 - 对比定义: - 1、提供一个接口:public interface RouJiaMoYLFactroy - 2、用于创建相关的或依赖对象的家族 public Meat createMeat();public YuanLiao createYuanliao();我们接口用于创建一系列的原材料。 - 创建用于提供原料的接口工厂:[RoujiaMoYLFactory.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/factory/cxgc/RoujiaMoYLFactory.java) - 各自分店实现接口,完成原料提供:[XianRoujiaMoYLFoctory.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/factory/cxgc/XianRoujiaMoYLFoctory.java) - 准备时,使用官方的原料:[RoujiaMo.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/factory/cxgc/RoujiaMo.java) ```java /** * 准备工作 */ public void prepare(RoujiaMoYLFactory roujiaMoYLFactory) { Meet meet = roujiaMoYLFactory.creatMeet(); YuanLiao yuanLiao = roujiaMoYLFactory.creatYuanLiao(); Log.e("---RoujiaMo:", "使用官方的原料 ---" + name + ": 揉面-剁肉-完成准备工作 yuanLiao:"+meet+"yuanLiao:"+yuanLiao); } ``` ### 3. 单例设计模式 > 单例模式主要是为了避免因为创建了多个实例造成资源的浪费,且多个实例由于多次调用容易导致结果出现错误,而**使用单例模式能够保证整个应用中有且只有一个实例**。 - 定义:只需要三步就可以保证对象的唯一性 - (1) 不允许其他程序用new对象 - (2) 在该类中创建对象 - (3) 对外提供一个可以让其他程序获取该对象的方法 - 对比定义: - (1) 私有化该类的构造函数 - (2) 通过new在本类中创建一个本类对象 - (3) 定义一个公有的方法,将在该类中所创建的对象返回 - 饿汉式[可用]:[SingletonEHan.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/singleton/ehan/SingletonEHan.java) - 含懒汉式[双重校验锁 推荐用]:[SingletonLanHan.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/singleton/lanhan/SingletonLanHan.java) ```java private SingletonLanHan() {} private static SingletonLanHan singletonLanHanFour; public static SingletonLanHan getSingletonLanHanFour() { if (singletonLanHanFour == null) { synchronized (SingletonLanHan.class) { if (singletonLanHanFour == null) { singletonLanHanFour = new SingletonLanHan(); } } } return singletonLanHanFour; } ``` - 内部类[推荐用]:[SingletonIn.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/singleton/inclass/SingletonIn.java) - 枚举[推荐用]:[SingletonEnum.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/singleton/enums/SingletonEnum.java) ### 4. 策略模式 > 策略模式:定义了算法族,分别封装起来,让它们之间可相互替换,此模式让算法的变化独立于使用算法的客户。 - 以创建游戏角色为例子: - 最初的游戏角色的父类:[Role.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/strategy/old/Role.java) - 发现有重复代码后,重构后的父类:[Role.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/strategy/better/Role.java) - 总结: - 1、封装变化(把可能变化的代码封装起来) - 2、多用组合,少用继承(我们使用组合的方式,为客户设置了算法) - 3、针对接口编程,不针对实现(对于Role类的设计完全的针对角色,和技能的实现没有关系) - 最后测试:创建角色: ```java RoleA roleA = new RoleA("---A"); roleA.setiDisplayBehavior(new DisplayYZ()) .setiAttackBehavior(new AttackXL()) .setiDefendBehavior(new DefendTMS()) .setiRunBehavior(new RunJCTQ()); roleA.display();// 样子 roleA.attack();// 攻击 roleA.run();// 逃跑 roleA.defend();// 防御 ``` ### 5. 适配器模式 > 定义:将一个类的接口转换成客户期望的另一个接口,适配器让原本接口不兼容的类可以相互合作。这个定义还好,说适配器的功能就是把一个接口转成另一个接口。 - 以充电器为实例: 手机充电器一般都是5V左右吧,咱天朝的家用交流电压220V,所以手机充电需要一个适配器(降压器) - 一部手机: [Mobile.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/adapter/Mobile.java) - 手机依赖一个提供5V电压的接口: [V5Power.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/adapter/V5Power.java) - 我们拥有的是220V家用交流电: [V220Power.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/adapter/V220Power.java) - **适配器,完成220V转5V的作用**:[V5PowerAdapter.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/adapter/V5PowerAdapter.java) - 最后测试:给手机冲个电: ```java Mobile mobile = new Mobile(); V5Power v5Power = new V5PowerAdapter(new V200Power()); mobile.inputPower(v5Power); ``` ### 6. 命令模式 > 定义:将“请求”封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象。命令模式也支持可撤销的操作。(简化: 将请求封装成对象,将动作请求者和动作执行者解耦。) - 需求:最近智能家电很火热,假设现在有电视、电脑、电灯等家电,现在需要你做个遥控器控制所有家电的开关,要求做到每个按钮对应的功能供用户个性化,对于新买入家电要有非常强的扩展性。 - 1、家电的API:[Door.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/command/Door.java) - 2、把命令封装成类: - 统一的命令接口:[Command.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/command/Command.java) - 家电实现该接口:[DoorOpenCommand.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/command/DoorOpenCommand.java) - 3、遥控器:[ControlPanel.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/command/ControlPanel.java) - 4、定义一个命令,可以干一系列的事情:[QuickCommand.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/command/QuickCommand.java) ```java QuickCommand quickCloseCommand = new QuickCommand(new Command[]{new LightOffCommand(light), new ComputerOffCommand(computer), new DoorCloseCommand(door)}); controlPanel.setCommands(6, quickOpenCommand); controlPanel.keyPressed(6); ``` - 5、遥控器面板执行:[CommandActivity.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/command/CommandActivity.java) ```java controlPanel.setCommands(0, new DoorOpenCommand(door));// 开门 controlPanel.keyPressed(0); ``` ### 7. 装饰者模式 > 装饰者模式:若要扩展功能,装饰者提供了比集成更有弹性的替代方案,动态地将责任附加到对象上。 - 先简单描述下装饰者模式发挥作用的地方,当我们设计好了一个类,我们需要给这个类添加一些辅助的功能,并且不希望改变这个类的代码,这时候就是装饰者模式大展雄威的时候了。这里还体现了一个**原则:类应该对扩展开放,对修改关闭。** - 需求:设计游戏的装备系统,基本要求,要可以计算出每种装备在镶嵌了各种宝石后的攻击力和描述: - 1、装备的超类:[IEquip.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/decorator/IEquip.java) - 2、各个装备的实现类: - eg:**武器**的实现类: [ArmEquip.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/decorator/equip/ArmEquip.java) - 3、装饰品的超类(装饰品也属于装备):[IEquipDecorator.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/decorator/gem/IEuipDecotator.java) - 4、装饰品的实现类: - eg:**蓝宝石**的实现类(可累加): [BlueGemDecorator.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/decorator/gem/BlueGemDecotator.java) - 5、最后测试:计算攻击力和查看描述: ```java Log.e("---", "一个镶嵌2颗红宝石,1颗蓝宝石的靴子: "); IEquip iEquip = new RedGemDecotator(new RedGemDecotator(new BlueGemDecotator(new ShoeEquip()))); Log.e("---", "攻击力:" + iEquip.caculateAttack()); Log.e("---", "描述语:" + iEquip.description()); ``` ### 8. 外观模式 > 定义:提供一个统一的接口,用来访问子系统中的一群接口,外观定义了一个高层的接口,让子系统更容易使用。**其实就是为了方便客户的使用,把一群操作,封装成一个方法。** - 需求:我比较喜欢看电影,于是买了投影仪、电脑、音响、设计了房间的灯光、买了爆米花机,然后我想看电影的时候,我需要一键观影和一键关闭。 - 每个设备类的开关等操作: - eg: 爆米花机:[PopcornPopper.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/facade/device/PopcornPopper.java) - 电影院类:[HomeTheaterFacade.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/facade/theater/HomeTheaterFacade.java) ```java /** * 一键观影 */ public void watchMovie() { computer.on(); light.down(); popcornPopper.on(); popcornPopper.makePopcorn(); projector.on(); projector.open(); player.on(); player.make3DListener(); } ``` - 最后测试:一键观影: ```java new HomeTheaterFacade(computer, light, player, popcornPopper, projector).watchMovie(); ``` ### 9. 模板方法模式 > 定义:定义了一个算法的骨架,而将一些步骤延迟到子类中,模版方法使得子类可以在不改变算法结构的情况下,重新定义算法的步骤。 - 需求:简单描述一下:本公司有程序猿、测试、HR、项目经理等人,下面使用模版方法模式,记录下所有人员的上班情况 - 模板方法模式中的三类角色 - 1、具体方法(Concrete Method) - 2、抽象方法(Abstract Method) - 3、钩子方法(Hook Method) - 工人的超类:[Worker.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/templatemethod/Worker.java) ```java // 具体方法 public final void workOneDay() { Log.e("workOneDay", "-----------------work start----------------"); enterCompany(); work(); exitCompany(); Log.e("workOneDay", "-----------------work end----------------"); } // 工作 抽象方法 public abstract void work(); // 钩子方法 public boolean isNeedPrintDate() { return false; } private void exitCompany() { if (isNeedPrintDate()) { Log.e("exitCompany", "---" + new Date().toLocaleString() + "--->"); } Log.e("exitCompany", name + "---离开公司"); } ``` - 程序员实现类(可得知时间):[ITWorker.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/templatemethod/worker/ITWorker.java) ```java /** * 重写父类的此方法,使可以查看离开公司时间 */ @Override public boolean isNeedPrintDate() { return true; } ``` - 最后测试: - 查看所有人员的工作情况: ```java QAWorker qaWorker = new QAWorker("测试人员"); qaWorker(); HRWorker hrWorker = new HRWorker("莉莉姐"); hrWorker.workOneDay(); ... ``` - 查看程序猿离开公司的时间: ```java ITWorker itWorker = new ITWorker("jingbin"); itWorker.workOneDay(); ``` ### 10. 状态模式 > 定义:允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。 - 定义又开始模糊了,理一下,当对象的内部状态改变时,它的行为跟随状态的改变而改变了,看起来好像重新初始化了一个类似的。 - 需求:已自动售货机为例(有已投币、未投币等状态和投币、投币等方法) - 最初实现待改进的售货机:[VendingMachine.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/state/old/VendingMachine.java) - 改进后的售货机(更具有延展性):[VendingMachineBetter.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/state/better/VendingMachineBetter.java) ```java // 放钱 public void insertMoney() { currentState.insertMoney(); } // 退钱 public void backMoney() { currentState.backMoney(); } // 转动曲柄 public void turnCrank() { currentState.turnCrank(); if (currentState == soldState || currentState == winnerState) { currentState.dispense();//两种情况会出货 } } // 出商品 public void dispense() { Log.e("VendingMachineBetter", "---发出一件商品"); if (count > 0) { count--; } } // 设置对应状态 public void setState(State state) { this.currentState = state; } ``` - 状态的接口:[State.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/state/better/State.java) - 对应状态的接口实现类: - eg: 中奖状态:[WinnerState.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/state/better/WinnerState.java) - eg: 售卖状态:[SoldState.java](https://github.com/youlookwhat/DesignPattern/blob/master/app/src/main/java/com/example/jingbin/designpattern/state/better/SoldState.java) - 改进后的售货机测试: ```java // 初始化售货机,且里面有3个商品 VendingMachineBetter machineBetter = new VendingMachineBetter(3); machineBetter.insertMoney(); machineBetter.turnCrank(); ``` ## Download - [DesignPattern.apk](http://download.csdn.net/detail/jingbin_/9684545) ## Reference - [http://blog.csdn.net/lmj623565791/article/category/2206597](http://blog.csdn.net/lmj623565791/article/category/2206597) ## Thanks - [CSDN:张鸿洋](http://blog.csdn.net/lmj623565791) - [CSDN:dmk877](http://blog.csdn.net/dmk877/article/details/50311791)