设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。

GitHub地址

DesignPattern

文章说明

一个Demo,集合常用的十种设计模式,每个模式使用易被人们接受的案例讲述,按模式分包,使用设计模式前后对比,界面显示定义讲解,让你更深刻的了解每种设计模式。 大部分案例来自张鸿洋的博客。如有错误欢迎指正,如有侵权,请联系我删除。

项目结构

包结构.png

设计模式分为三种类型,共23种:

  • 创建型模式:单例模式、抽象工厂模式、建造者模式、工厂模式、原型模式。
  • 结构型模式:适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式。
  • 行为型模式:模版方法模式、命令模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式、状态模式、策略模式、职责链模式(责任链模式)、访问者模式。 上面链接点击直接跳转到GitHub对应模式解析内

MainActivity.png

博客目录

  • 1 . 设计模式 观察者模式(Observer Pattern) 以微信公众服务为例
  • 2 . 设计模式 工厂模式(Factory Pattern) 从卖肉夹馍说起
  • 3 . 设计模式 单例设计模式(Singleton Pattern) 完全解析
  • 4 . 设计模式 策略模式(Strategy Pattern) 以角色游戏为背景
  • 5 . 设计模式 适配器模式(Adapter Pattern) 以手机充电器为例
  • 6 . 设计模式 命令模式(Command Pattern) 管理智能家电
  • 7 . 设计模式 装饰者模式(Decorator Pattern) 带你重回传奇世界
  • 8 . 设计模式 外观模式(Facade Pattern) 一键电影模式
  • 9 . 设计模式 模版方法模式(TemplateMethod Pattern) 展现程序员的一天
  • 10 . 设计模式 状态模式(State Pattern) 以自动售货机为例

对应模式所在的包

  • 1 . Observer
  • 2 . Factory
  • 3 . Singleton
  • 4 . Strategy
  • 5 . Adapter
  • 6 . Command
  • 7 . Decorator
  • 8 . Facade
  • 9 . Template Method
  • 10 . State

模式分析

1. 观察者模式

定义了对象之间的一对多的依赖,这样一来,当一个对象改变时,它的所有的依赖者都会收到通知并自动更新。

  • 对于JDK或者Andorid中都有很多地方实现了观察者模式,比如XXXView.addXXXListenter , 当然了 XXXView.setOnXXXListener不一定是观察者模式,因为观察者模式是一种一对多的关系,对于setXXXListener是1对1的关系,应该叫回调。

  • 专题接口:Subject.java ;

      /*** 注册一个观察者*/public void registerObserver(Observer observer);/*** 移除一个观察者*/public void removeObserver(Observer observer);/*** 通知所有观察者*/public void notifyObservers();
    • 3D服务号的实现类:ObjectFor3D.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

    public ObserverUser1(Subject subject) {subject.registerObserver(this);}@Overridepublic void update(String msg) {Log.e("-----ObserverUser1 ", "得到 3D 号码:" + msg + ", 我要记下来。 ");}
  • 最后测试:ObserverActivity.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

      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
      public abstract RoujiaMo sellRoujiaMo(String type);
    • 具体实现抽象方法:XianRoujiaMoStore.java
    • 分店依旧使用简单工厂模式:XianSimpleRoujiaMoFactory.java
  • 4、抽象工厂模式(使用官方提供的原料)

    • 定义:提供一个接口,用于创建相关的或依赖对象的家族,而不需要明确指定具体类。
    • 对比定义:
      • 1、提供一个接口:public interface RouJiaMoYLFactroy
      • 2、用于创建相关的或依赖对象的家族 public Meat createMeat();public YuanLiao createYuanliao();我们接口用于创建一系列的原材料。
    • 创建用于提供原料的接口工厂:RoujiaMoYLFactory.java
    • 各自分店实现接口,完成原料提供:XianRoujiaMoYLFoctory.java
    • 准备时,使用官方的原料:RoujiaMo.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
  • 含懒汉式[双重校验锁 推荐用]:SingletonLanHan.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

  • 枚举[推荐用]:SingletonEnum.java

单例设计模式.png

4. 策略模式

策略模式:定义了算法族,分别封装起来,让它们之间可相互替换,此模式让算法的变化独立于使用算法的客户。

  • 以创建游戏角色为例子:

    • 最初的游戏角色的父类:Role.java
    • 发现有重复代码后,重构后的父类:Role.java
  • 总结:
    • 1、封装变化(把可能变化的代码封装起来)
    • 2、多用组合,少用继承(我们使用组合的方式,为客户设置了算法)
    • 3、针对接口编程,不针对实现(对于Role类的设计完全的针对角色,和技能的实现没有关系)
  • 最后测试:创建角色:

    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
  • 手机依赖一个提供5V电压的接口: V5Power.java
  • 我们拥有的是220V家用交流电: V220Power.java
  • 适配器,完成220V转5V的作用:V5PowerAdapter.java
  • 最后测试:给手机冲个电:

      Mobile mobile = new Mobile();
    V5Power v5Power = new V5PowerAdapter(new V200Power());
    mobile.inputPower(v5Power);

6. 命令模式

定义:将“请求”封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象。命令模式也支持可撤销的操作。(简化: 将请求封装成对象,将动作请求者和动作执行者解耦。)

  • 需求:最近智能家电很火热,假设现在有电视、电脑、电灯等家电,现在需要你做个遥控器控制所有家电的开关,要求做到每个按钮对应的功能供用户个性化,对于新买入家电要有非常强的扩展性。
  • 1、家电的API:Door.java
  • 2、把命令封装成类:
    • 统一的命令接口:Command.java
    • 家电实现该接口:DoorOpenCommand.java
  • 3、遥控器:ControlPanel.java
  • 4、定义一个命令,可以干一系列的事情:QuickCommand.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

    controlPanel.setCommands(0, new DoorOpenCommand(door));// 开门
    controlPanel.keyPressed(0);

命令模式

7. 装饰者模式

装饰者模式:若要扩展功能,装饰者提供了比集成更有弹性的替代方案,动态地将责任附加到对象上。

  • 先简单描述下装饰者模式发挥作用的地方,当我们设计好了一个类,我们需要给这个类添加一些辅助的功能,并且不希望改变这个类的代码,这时候就是装饰者模式大展雄威的时候了。这里还体现了一个原则:类应该对扩展开放,对修改关闭。

  • 需求:设计游戏的装备系统,基本要求,要可以计算出每种装备在镶嵌了各种宝石后的攻击力和描述:

  • 1、装备的超类:IEquip.java
  • 2、各个装备的实现类:
    • eg:武器的实现类: ArmEquip.java
  • 3、装饰品的超类(装饰品也属于装备):IEquipDecorator.java
  • 4、装饰品的实现类:

    • eg:蓝宝石的实现类(可累加): BlueGemDecorator.java
  • 5、最后测试:计算攻击力和查看描述:

      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
  • 电影院类:HomeTheaterFacade.java

      /*** 一键观影*/public void watchMovie() {computer.on();light.down();popcornPopper.on();popcornPopper.makePopcorn();projector.on();projector.open();player.on();player.make3DListener();}
    • 最后测试:一键观影:

      new HomeTheaterFacade(computer, light, player, popcornPopper, projector).watchMovie();

9. 模板方法模式

定义:定义了一个算法的骨架,而将一些步骤延迟到子类中,模版方法使得子类可以在不改变算法结构的情况下,重新定义算法的步骤。

  • 需求:简单描述一下:本公司有程序猿、测试、HR、项目经理等人,下面使用模版方法模式,记录下所有人员的上班情况
  • 模板方法模式中的三类角色
    • 1、具体方法(Concrete Method)
    • 2、抽象方法(Abstract Method)
    • 3、钩子方法(Hook Method)
  • 工人的超类:Worker.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

      /*** 重写父类的此方法,使可以查看离开公司时间*/@Overridepublic boolean isNeedPrintDate() {return true;}
  • 最后测试:

    • 查看所有人员的工作情况:

        QAWorker qaWorker = new QAWorker("测试人员");qaWorker();HRWorker hrWorker = new HRWorker("莉莉姐");hrWorker.workOneDay();...
    • 查看程序猿离开公司的时间:

        ITWorker itWorker = new ITWorker("jingbin");itWorker.workOneDay();

10. 状态模式

定义:允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。

  • 定义又开始模糊了,理一下,当对象的内部状态改变时,它的行为跟随状态的改变而改变了,看起来好像重新初始化了一个类似的。

  • 需求:已自动售货机为例(有已投币、未投币等状态和投币、投币等方法)

  • 最初实现待改进的售货机:VendingMachine.java
  • 改进后的售货机(更具有延展性):VendingMachineBetter.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

  • 对应状态的接口实现类:
    • eg: 中奖状态:WinnerState.java
    • eg: 售卖状态:SoldState.java
  • 改进后的售货机测试:

      // 初始化售货机,且里面有3个商品VendingMachineBetter machineBetter = new VendingMachineBetter(3);machineBetter.insertMoney();machineBetter.turnCrank();

参考链接

  • http://blog.csdn.net/lmj623565791/article/category/2206597

Thanks

  • CSDN:张鸿洋
  • CSDN:dmk877

End

感兴趣的小伙伴可以Star哦~

GitHub:DesignPattern


作者:Jingbin_链接:http://www.jianshu.com/p/61b67ca754a3來源:简书

java 常用十种设计模式示例归纳 | 已打包请带走相关推荐

  1. Java 23种设计模式全归纳 | 已打包请带走

    设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结. 设计模式分为三种类型,共23种: 创建型模式:单例模式.抽象工厂模式.建造者模式.工厂模式 ...

  2. Java常用的设计模式总结

    前言 java设计模式有23种,他们分别是: 创建型模式:单例模式.抽象工厂模式.建造者模式.工厂模式.原型模式. 结构型模式:适配器模式.桥接模式.装饰器模式.组合模式.外观模式.享元模式.代理模式 ...

  3. 【Java 常用的设计模式】

    目录 前言 一.设计原则 1.1 开闭原则 1.2 单一职责原则 1.3 依赖倒置原则 1.4 接口分离原则 1.5 迪米特法则 1.6 里氏替换原则 二.设计模式 2.1 单例模式 2.1.1 饿汉 ...

  4. Java设计模式 --- 七大常用设计模式示例归纳

    设计模式分为三种类型,共23种: 创建型模式:单例模式.抽象工厂模式.建造者模式.工厂模式.原型模式 结构型模式:适配器模式.桥接模式.装饰模式.组合模式.外观模式.享元模式.代理模式 行为型模式:模 ...

  5. java常用代码架构示例

    1.前言 本文针对特定业务,以一种灵活的方式来设计代码结构,使得代码具有较好的可扩展性和可读性.主要实现的是消息队列的功能,业务类为一个常驻线程,每隔一段时间去数据库(可以认为是队列)中获取可以读取的 ...

  6. Java常用设计模式(一)

      当代软件开发中,设计模式已经成为一种标准的编程实践.在Java编程中,设计模式也同样重要.Java设计模式是软件开发中广泛应用的一种编程方法,它可以帮助开发人员更快地编写出高效.可靠和可维护的代码 ...

  7. Java依赖注入 - DI设计模式示例教程

    Java依赖注入 - DI设计模式示例教程 Java依赖注入 设计模式允许我们删除硬编码的依赖项,并使我们的应用程序松散耦合,可扩展和可维护.我们可以在java中实现依赖注入,以将依赖项解析从编译时移 ...

  8. Java设计模式 - 示例教程

    Java设计模式 - 示例教程 设计模式在软件开发人员中非常流行.设计模式是针对常见软件问题的良好描述的解决方案.我已经写了很多关于java设计模式的文章.您可以订阅我们的时事通讯下载PDF电子书(1 ...

  9. java 设计模式 示例_Java设计模式–示例教程

    java 设计模式 示例 Design Patterns are very popular among software developers. A design pattern is a well- ...

最新文章

  1. keepalive 配合mysql主主复制
  2. 看到OSC有一期是:“OSChina 第 37 期高手问答 —— 消息队列服务”
  3. 一个程序看fputc和fgetc
  4. 在CentOS上使用Jexus托管运行 ZKEACMS
  5. [css] absolute的containing block(容器块)计算方式和正常流有什么区别?
  6. 小白学docker(1)---docker安装
  7. java读取yaml配置文件,snakeyaml读取yaml配置文件
  8. 淤泥管道机器人_丛台区设备管道清洗超高效率
  9. Css兼容:如何解决IE7和IE8的BUG
  10. 使用二维NDRange workgroup
  11. Linux 命令(67)—— time 命令
  12. 古代的政令 —— 两汉均输
  13. 经典机器学习系列(七)【聚类分析前序--相似性度量】
  14. 本科计算机软件类毕业论文写作那些事
  15. socket 服务器
  16. Java 给PPT添加动画效果(预设动画/自定义动画)
  17. 计算机重新启动操作处于挂起状态,win7系统安装Photoshop提示安装程序检测到计算机重新启动操作可能处于挂起状挂起状态的解决方法...
  18. 可视化Keras模型
  19. 选择隔离电源还是非隔离电源?
  20. 树莓派无线鼠标不灵敏问题安装输入法

热门文章

  1. Linux 的启动流程--转
  2. 消费金融首推即时沟通工具“马上”探索科技金融发展新方向
  3. 李宏毅深度学习——Tips for Deep Learning
  4. 【行业报告】基于社交图谱关系的反欺诈产品应用——青云
  5. 谷歌新 AI 实验室主管 Hugo 深度学习教程:神经网络、CV、NLP 难点解析
  6. 还能开发搜索引擎吗?
  7. 白话Elasticsearch16-深度探秘搜索技术之使用原生cross-fiedls技术解决搜索弊端
  8. Spring-Spring整合MyBatis详解
  9. linux 服务器 iptables 防止arp病毒,让Linux系统有效防御ARP攻击的实用技巧
  10. mysql 插入数据后返回该条数据id