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

叁歲伎倆 2022-06-02 12:26 205阅读 0赞

包装模式群大PK

写在前面

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

    1. 装饰模式
    2. 适配器模式
    3. 门面模式
    4. 代理模式
    5. 桥梁模式

五种模式的区别

  • 代理模式

    • 从明星的经纪人说起

      • 类图

        • 4XQBdl5.png
      • 代码实现

        • Agent

          #

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

          #

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

          #

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

          #

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

          #

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

    • 粉饰一个演员

      • 类图

        • th5YxJe.png
      • 代码

        • Client

          #

          1. package com.peng.baozhuang2;
          2. /**
          3. * @author kungfu~peng
          4. * @data 2018年1月6日
          5. * @description
          6. */
          7. public class Client {
          8. public static void main(String[] args) {
          9. // 定义出明星
          10. IStar star = new FreakStar();
          11. // 粉饰自己
          12. System.out.println("==========表演前=========");
          13. HotAir ha = new HotAir(star);
          14. ha.act();
          15. System.out.println("===========表演后=========");
          16. Deny dy = new Deny(star);
          17. dy.act();
          18. }
          19. }
        • Decorator

          #

          1. package com.peng.baozhuang2;
          2. /**
          3. * @author kungfu~peng
          4. * @data 2018年1月6日
          5. * @description
          6. */
          7. public abstract class Decorator implements IStar {
          8. // 粉饰的是谁
          9. private IStar star;
          10. public Decorator(IStar star) {
          11. super();
          12. this.star = star;
          13. }
          14. @Override
          15. public void act() {
          16. this.star.act();
          17. }
          18. }
        • Deny

          #

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

          #

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

          #

          1. package com.peng.baozhuang2;
          2. /**
          3. * @author kungfu~peng
          4. * @data 2018年1月6日
          5. * @description
          6. */
          7. public class HotAir extends Decorator {
          8. public HotAir(IStar star) {
          9. super(star);
          10. }
          11. public void act() {
          12. System.out.println("表演前的夸夸其谈");
          13. super.act();
          14. }
          15. }
        • IStar

          #

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

          #

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

    • 演员的替身

      • 类图

        • LexlqtO.png
      • 代码

        • Director

          #

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

          #

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

          #

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

          #

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

          #

          1. package com.peng.baozhuang3;
          2. /**
          3. * @author kungfu~peng
          4. * @data 2018年1月6日
          5. * @description
          6. */
          7. public class Standin implements IStar {
          8. // 替身是谁
          9. private IActor actor;
          10. public Standin(IActor actor) {
          11. super();
          12. this.actor = actor;
          13. }
          14. @Override
          15. public void act(String context) {
          16. actor.playact(context);
          17. }
          18. }
        • UnknownActor

          #

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

          #

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

    • 明星类型太多了:

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

      • 类图

        • a8x6mpK.png
      • 代码

        • AbsAction

          #

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

          #

          1. package com.peng.baozhuang4;
          2. /**
          3. * @author kungfu~peng
          4. * @data 2018年1月6日
          5. * @description
          6. */
          7. public abstract class AbsStar {
          8. // 一个明星参加那些活动
          9. protected final AbsAction action;
          10. // 通过构造函数传递参数
          11. public AbsStar(AbsAction action) {
          12. super();
          13. this.action = action;
          14. }
          15. // 每个明星都有自己的工作
          16. public void doJob() {
          17. action.desc();
          18. }
          19. }
        • ActFilm

          #

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

          #

          1. package com.peng.baozhuang4;
          2. /**
          3. * @author kungfu~peng
          4. * @data 2018年1月6日
          5. * @description
          6. */
          7. public class Client {
          8. public static void main(String[] args) {
          9. // 声明一个电影明星
          10. AbsStar zhangSan = new FilmStar();
          11. // 声明一个歌星
          12. AbsStar liSi = new Singer();
          13. // 展示一下各个明星的主要工作
          14. zhangSan.doJob();
          15. liSi.doJob();
          16. // 也有部分明星不务正业
          17. liSi = new Singer(new ActFilm());
          18. liSi.doJob();
          19. }
          20. }
        • FilmStar

          #

          1. package com.peng.baozhuang4;
          2. /**
          3. * @author kungfu~peng
          4. * @data 2018年1月6日
          5. * @description
          6. */
          7. public class FilmStar extends AbsStar {
          8. // 默认的电影明星的主要工作是拍电影
          9. public FilmStar() {
          10. super(new ActFilm());
          11. }
          12. // 也可以重新设置一个新的角色
          13. public FilmStar(AbsAction action) {
          14. super(action);
          15. }
          16. // 细化电影明星的职责
          17. public void doJob() {
          18. System.out.println("\n======影星的工作=========");
          19. super.doJob();
          20. }
          21. }
        • Sing

          #

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

          #

          1. package com.peng.baozhuang4;
          2. /**
          3. * @author kungfu~peng
          4. * @data 2018年1月6日
          5. * @description
          6. */
          7. public class Singer extends AbsStar {
          8. // 默认的歌星的主要工作是拍唱歌
          9. public Singer() {
          10. super(new Sing());
          11. }
          12. // 也可以重新设置一个新的角色
          13. public Singer(AbsAction action) {
          14. super(action);
          15. }
          16. // 细化歌星的职责
          17. public void doJob() {
          18. System.out.println("\n======歌星的工作=========");
          19. super.doJob();
          20. }
          21. }
        • 执行结果

          #

          1. ======影星的工作=========
          2. 演出精彩绝伦的电影
          3. ======歌星的工作=========
          4. 唱出优美的歌曲
          5. ======歌星的工作=========
          6. 演出精彩绝伦的电影

最佳实践

综述

  • 5个包装模式是大家在系统设计中经常使用到的模式,它们具有相似的特征:

    1. 都是通过委托的方式对一个对象或一系列的对象进行包装
    2. 有了包装,设计的系统才更加的灵活,稳定,并且极具扩展性
    3. 从实现的角度来看,它们都是代理的具体表现形式
  • 代理模式

    • 主要用在不希望展示一个对象内部细节的场景之中,比如一个远程服务不需要把远程连接的所有细节都暴露给外部模块,通过一个代理类,可以很轻松的实现被代理类对象的封装。此外,代理模式还可以用在一个对象的访问需要限制的场景中,比如AOP
  • 装饰模式

    • 是一种特殊的代理模式,他倡导的是不改变接口的前提下为对象增强功能,或者动态添加额外职责,就扩展性而言,他比子类更加灵活
  • 适配器模式

    • 适配器模式的主要意图是接口转换,把一个对象的接口转换成希望的另外一个接口,这里的系统指的不仅仅是一个应用,也可以是某个环境,比如可以通过接口转换可以屏蔽外界的接口,以免受外界深入系统内部,从而提高系统的稳定性和可靠性
  • 桥梁模式

    • 桥梁模式是在抽象层产生耦合,解决的是自行扩展的问题,它可以使两个耦合关系的对象互不影响的扩展
  • 门面模式

    • 门面模式是一个粗粒度的封装,它提供一个方便访问子系统的接口,不具有任何的业务逻辑,仅仅是一个访问复杂的快速通道,没有它,子系统照样运行,有了它,只是更方便的运行而已

发表评论

表情:
评论列表 (有 0 条评论,205人围观)

还没有评论,来说两句吧...

相关阅读