设计模式之禅之包装模式群大PK【装饰模式VS适配器模式VS门面模式VS代理模式VS桥梁模式】

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/eieiei438/article/details/79050659

包装模式群大PK

写在前面

  • 这么多的设计模式,大家有没有发觉在很多的模式中有角色是不干活的,他们只充当着黔首作用,你有问题,找我,但是我不处理,我让其他人处理,最典型的就是代理模式了,代理角色接收请求然后传递到被代理角色处理。门面模式也是一样,门面模式的任务就是把请求转发到子系统,类似这种结构的模式还有很多,我们先给这种结构类型的模式起一个名称,叫做包装模式
  • 包装模式:是一种模式,而不是一个模式,包括
    1. 装饰模式
    2. 适配器模式
    3. 门面模式
    4. 代理模式
    5. 桥梁模式

五种模式的区别

  • 代理模式

    • 从明星的经纪人说起

      • 类图
      • 代码实现

        • Agent

          package com.peng.baozhuang1;
          
          /**
           * @author kungfu~peng
           * @data 2018年1月6日
           * @description
           */
          public class Agent implements IStar {
              private IStar star;// 定义谁的经纪人
          
              public Agent(IStar star) {
                  super();
                  this.star = star;
              }
          
              @Override
              public void sign() {
                  // 经纪人是不会签名的,得靠具体的明星来签名
                  System.out.println("我是经纪人:下列签名由明星来签!");
                  star.sign();
              }
          
          }
          
        • Idolater

          package com.peng.baozhuang1;
          
          /**
           * @author kungfu~peng
           * @data 2018年1月6日
           * @description
           */
          public class Idolater {
              public static void main(String[] args) {
                  // 崇拜的明星是谁
                  IStar star = new Single();
                  // 找明星的经纪人
                  IStar agent = new Agent(star);
                  // 崇拜者要明星的签名
                  System.out.println("我是你的崇拜者,我想要你的签名");
                  agent.sign();
              }
          }
          
        • IStar

          package com.peng.baozhuang1;
          
          /**
           * @author kungfu~peng
           * @data 2018年1月6日
           * @description
           */
          public interface IStar {
              // 明星都会签名
              public void sign();
          }
          
        • Single

          package com.peng.baozhuang1;
          
          /**
           * @author kungfu~peng
           * @data 2018年1月6日
           * @description
           */
          public class Single implements IStar {
          
              @Override
              public void sign() {
                  System.out.println("明星签名:我是KungFu~Peng");
              }
          
          }
          
        • 执行结果

          我是你的崇拜者,我想要你的签名
          我是经纪人:下列签名由明星来签!
          明星签名:我是KungFu~Peng
          
  • 装饰模式

    • 粉饰一个演员

      • 类图
      • 代码

        • Client

          package com.peng.baozhuang2;
          
          /**
           * @author kungfu~peng
           * @data 2018年1月6日
           * @description
           */
          public class Client {
              public static void main(String[] args) {
                  // 定义出明星
                  IStar star = new FreakStar();
                  // 粉饰自己
                  System.out.println("==========表演前=========");
                  HotAir ha = new HotAir(star);
                  ha.act();
                  System.out.println("===========表演后=========");
                  Deny dy = new Deny(star);
                  dy.act();
              }
          }
          
        • Decorator

          package com.peng.baozhuang2;
          
          /**
           * @author kungfu~peng
           * @data 2018年1月6日
           * @description
           */
          public abstract class Decorator implements IStar {
              // 粉饰的是谁
              private IStar star;
          
              public Decorator(IStar star) {
                  super();
                  this.star = star;
              }
          
              @Override
              public void act() {
                  this.star.act();
              }
          
          }
          
        • Deny

          package com.peng.baozhuang2;
          
          /**
           * @author kungfu~peng
           * @data 2018年1月6日
           * @description
           */
          public class Deny extends Decorator {
          
              public Deny(IStar star) {
                  super(star);
              }
          
              public void act() {
                  super.act();
                  // 表演结束后的死不承认
                  System.out.println("表演后:百般抵赖,死不承认!");
              }
          }
          
        • FreakStar

          package com.peng.baozhuang2;
          
          /**
           * @author kungfu~peng
           * @data 2018年1月6日
           * @description
           */
          public class FreakStar implements IStar {
          
              @Override
              public void act() {
                  System.out.println("表演中:演技很拙劣~~");
              }
          
          }
          
        • HotAir

          package com.peng.baozhuang2;
          
          /**
           * @author kungfu~peng
           * @data 2018年1月6日
           * @description
           */
          public class HotAir extends Decorator {
          
              public HotAir(IStar star) {
                  super(star);
              }
          
              public void act() {
                  System.out.println("表演前的夸夸其谈");
                  super.act();
              }
          
          }
          
        • IStar

          package com.peng.baozhuang2;
          
          /**
           * @author kungfu~peng
           * @data 2018年1月6日
           * @description
           */
          public interface IStar {
              // 演戏
              public void act();
          }
          
        • 执行结果

          ==========表演前=========
          表演前的夸夸其谈
          表演中:演技很拙劣~~
          ===========表演后=========
          表演中:演技很拙劣~~
          表演后:百般抵赖,死不承认!
          
  • 适配器模式

    • 演员的替身

      • 类图
      • 代码

        • Director

          package com.peng.baozhuang3;
          
          /**
           * @author kungfu~peng
           * @data 2018年1月6日
           * @description
           */
          public class Director {
              public static void main(String[] args) {
                  System.out.println("=======演戏过程模拟========");
                  // 定义一个大明星
                  IStar star = new FilmStar();
                  star.act("前十分钟,明星本人出演~~");
                  // 中间5分钟提示来演
                  IActor actor = new UnknownActor();
                  IStar standin = new Standin(actor);
                  standin.act("中间五分钟,替身来演");
                  // 最后十分钟,明星来演
                  star.act("最后十分钟,明星本人来演");
              }
          }
          
        • FilmStar

          package com.peng.baozhuang3;
          
          /**
           * @author kungfu~peng
           * @data 2018年1月6日
           * @description
           */
          public class FilmStar implements IStar {
          
              @Override
              public void act(String context) {
                  System.out.println("明星演戏:" + context);
              }
          }
          
        • IActor

          package com.peng.baozhuang3;
          
          /**
           * @author kungfu~peng
           * @data 2018年1月6日
           * @description
           */
          public interface IActor {
              // 普通演员演戏
              public void playact(String contet);
          }
          
        • IStar

          package com.peng.baozhuang3;
          
          /**
           * @author kungfu~peng
           * @data 2018年1月6日
           * @description
           */
          public interface IStar {
              // 明星都要演戏
              public void act(String context);
          }
          
        • Standin

          package com.peng.baozhuang3;
          
          /**
           * @author kungfu~peng
           * @data 2018年1月6日
           * @description
           */
          public class Standin implements IStar {
              // 替身是谁
              private IActor actor;
          
              public Standin(IActor actor) {
                  super();
                  this.actor = actor;
              }
          
              @Override
              public void act(String context) {
                  actor.playact(context);
              }
          }
          
        • UnknownActor

          package com.peng.baozhuang3;
          
          /**
           * @author kungfu~peng
           * @data 2018年1月6日
           * @description
           */
          public class UnknownActor implements IActor {
              @Override
              public void playact(String contet) {
                  // 普通演员演戏
                  System.out.println("普通演员演戏:" + contet);
              }
          
          }
          
        • 执行结果

          =======演戏过程模拟========
          明星演戏:前十分钟,明星本人出演~~
          普通演员演戏:中间五分钟,替身来演
          明星演戏:最后十分钟,明星本人来演
          
  • 桥梁模式

    • 明星类型太多了:
      1. 电影明星
      2. 电视明星
      3. 歌星
      4. 体育明星
      5. 网络明星
      6. 。。。
    • 明星可能身兼数职,即多元化发展

      • 类图
      • 代码

        • AbsAction

          package com.peng.baozhuang4;
          
          /**
           * @author kungfu~peng
           * @data 2018年1月6日
           * @description 
           */
          public abstract class AbsAction {
          //每个活动都有描述
              public abstract void desc();
          }
          
        • AbsStar

          package com.peng.baozhuang4;
          
          /**
           * @author kungfu~peng
           * @data 2018年1月6日
           * @description
           */
          public abstract class AbsStar {
              // 一个明星参加那些活动
              protected final AbsAction action;
          
              // 通过构造函数传递参数
          
              public AbsStar(AbsAction action) {
                  super();
                  this.action = action;
              }
          
              // 每个明星都有自己的工作
              public void doJob() {
                  action.desc();
              }
          }
          
        • ActFilm

          package com.peng.baozhuang4;
          
          /**
           * @author kungfu~peng
           * @data 2018年1月6日
           * @description
           */
          public class ActFilm extends AbsAction {
          
              @Override
              public void desc() {
                  System.out.println("演出精彩绝伦的电影");
              }
          
          }
          
        • Client

          package com.peng.baozhuang4;
          
          /**
           * @author kungfu~peng
           * @data 2018年1月6日
           * @description
           */
          public class Client {
              public static void main(String[] args) {
                  // 声明一个电影明星
                  AbsStar zhangSan = new FilmStar();
                  // 声明一个歌星
                  AbsStar liSi = new Singer();
                  // 展示一下各个明星的主要工作
                  zhangSan.doJob();
                  liSi.doJob();
                  // 也有部分明星不务正业
                  liSi = new Singer(new ActFilm());
                  liSi.doJob();
              }
          }
          
        • FilmStar

          package com.peng.baozhuang4;
          
          /**
           * @author kungfu~peng
           * @data 2018年1月6日
           * @description
           */
          public class FilmStar extends AbsStar {
          
              // 默认的电影明星的主要工作是拍电影
          
              public FilmStar() {
                  super(new ActFilm());
              }
          
              // 也可以重新设置一个新的角色
              public FilmStar(AbsAction action) {
                  super(action);
              }
          
              // 细化电影明星的职责
              public void doJob() {
                  System.out.println("\n======影星的工作=========");
                  super.doJob();
              }
          
          }
          
        • Sing

          package com.peng.baozhuang4;
          
          /**
           * @author kungfu~peng
           * @data 2018年1月6日
           * @description
           */
          public class Sing extends AbsAction {
              @Override
              public void desc() {
                  System.out.println("唱出优美的歌曲");
              }
          
          }
          
        • Singer

          package com.peng.baozhuang4;
          
          /**
           * @author kungfu~peng
           * @data 2018年1月6日
           * @description
           */
          public class Singer extends AbsStar {
          
              // 默认的歌星的主要工作是拍唱歌
          
              public Singer() {
                  super(new Sing());
              }
          
              // 也可以重新设置一个新的角色
              public Singer(AbsAction action) {
                  super(action);
              }
          
              // 细化歌星的职责
              public void doJob() {
                  System.out.println("\n======歌星的工作=========");
                  super.doJob();
              }
          
          }
          
        • 执行结果

          ======影星的工作=========
          演出精彩绝伦的电影
          
          ======歌星的工作=========
          唱出优美的歌曲
          
          ======歌星的工作=========
          演出精彩绝伦的电影
          

最佳实践

综述

  • 5个包装模式是大家在系统设计中经常使用到的模式,它们具有相似的特征:
    1. 都是通过委托的方式对一个对象或一系列的对象进行包装
    2. 有了包装,设计的系统才更加的灵活,稳定,并且极具扩展性
    3. 从实现的角度来看,它们都是代理的具体表现形式
  • 代理模式
    • 主要用在不希望展示一个对象内部细节的场景之中,比如一个远程服务不需要把远程连接的所有细节都暴露给外部模块,通过一个代理类,可以很轻松的实现被代理类对象的封装。此外,代理模式还可以用在一个对象的访问需要限制的场景中,比如AOP
  • 装饰模式
    • 是一种特殊的代理模式,他倡导的是不改变接口的前提下为对象增强功能,或者动态添加额外职责,就扩展性而言,他比子类更加灵活
  • 适配器模式
    • 适配器模式的主要意图是接口转换,把一个对象的接口转换成希望的另外一个接口,这里的系统指的不仅仅是一个应用,也可以是某个环境,比如可以通过接口转换可以屏蔽外界的接口,以免受外界深入系统内部,从而提高系统的稳定性和可靠性
  • 桥梁模式
    • 桥梁模式是在抽象层产生耦合,解决的是自行扩展的问题,它可以使两个耦合关系的对象互不影响的扩展
  • 门面模式
    • 门面模式是一个粗粒度的封装,它提供一个方便访问子系统的接口,不具有任何的业务逻辑,仅仅是一个访问复杂的快速通道,没有它,子系统照样运行,有了它,只是更方便的运行而已

没有更多推荐了,返回首页