zoukankan      html  css  js  c++  java
  • 浅谈设计模式(二):装饰器模式|中介模式|原型模式

    装饰器模式(Decorator Pattern)

    装饰器模式可用来给一个类动态添加功能,将其装饰成一个新的类。这就是装饰器的概念。看到这里我们可能会想,要达到这种效果,我们用子类继承父类不就可以了吗? 没错装饰器模式,本身是一种继承的替代方案。那既然是替代方案,那么自然就有它不一样的地方。
    具体区别在哪里呢? 请看
    • 装饰器模式更灵活:继承时父子类的关系是静态的,而装饰器模式是动态的,装饰类和被装饰类的关系是运行时候确认的
    • 装饰类和被装饰类的耦合关系是松散的,各自可以独立变化
     
    下面看看具体的代码。具体过程可看注释
    // 1.首先我们有一个Pen接口
    public interface Pen {
      public void write();
    }
    // 2.Pencil类实现了Pen这个接口
    public class Pencil implements Pen {
        public void write () {
            System.out.print("写");
        }
    }
    // 3.装饰类PencilDecorator也实现了Pen这个接口,且代理调用Pencil的方法
    public class PencilDecorator implements Pen{
        Pen pen;
        public PencilDecorator(Pen pen) {
          this.pen = pen;
        }
        public void write () {
          pen.write();
        }
    }
    // 4.用具体装饰类继承PencilDecorator,这样就可以做扩展变化
    public class BluePencilDecorator extends PencilDecorator{
        public BluePencilDecorator (Pen pen) {
            super(pen);
        }
        public void writeBlue () {
            this.write();
            System.out.println("写出来是蓝色的");
        }
    }
    // 同4.用具体装饰类继承PencilDecorator,这样就可以做扩展变化
    public class RedPencilDecorator extends PencilDecorator{
        public RedPencilDecorator (Pen pen) {
            super(pen);
        }
        public void writeRed () {
            this.write();
            System.out.println("写出来是红色的");
        }
    }
    // 测试
    public class Test {
        public static void main(String args []) {
           Pen pencil = new Pencil();
           RedPencilDecorator redPencil = new RedPencilDecorator(pencil);
           BluePencilDecorator bluePencil = new BluePencilDecorator(pencil);
           redPencil.writeRed();
           bluePencil.writeBlue();
        }
    }
    输出结果
     
    代码的结构如下图所示
    从这里我们看到了,经过PencilDecorator类这一层的隔离,Pencil类和BluePencilDecorator类/RedPencilDecorator类在一定程度上解耦,从而各自独立发展了。这就是代理模式能够替代继承的原因和它的独特优势
     
    唉!! 等一下,好像看到了什么熟悉的东西,请看
     
    没错,这还真就是代理模式的代码。
     
    在这里,我们可以从两个角度去理解装饰器模式。
    • 第一,从构成上看,装饰器模式 = 代理模式 + 类继承。 也就是在代理模式的基础上,加了一堆继承[代理类]的子类,从而进行扩展变化,并且还尽量减少了和原有类的联系。
    • 第二,从功能上看,代理模式侧重的是“控制”,而装饰器模式侧重的是“扩展”。比如说,类A代理了类B,那么这两个类由于同一个接口的约束,它们的方法和实现的功能其实是一样的。而类C装饰了类D,那么这个时候类C不仅仅具备了类D的方法,同时还能加入自己的特殊逻辑。
     

    中介者模式(Mediator Pattern)

    简单的说,中介者模式是一个分散到集中的一个过程
    还是看下具体的代码
     
    // Colleague接口
    public interface Colleague {
        public void handleExternal(Mediator mediator);
        public void handleInternal();
    }
    // 中介者接口
    public abstract class Mediator {
       public Colleague A;
       public Colleague B;
       public Colleague C;
       public Mediator (Colleague A, Colleague B, Colleague C) {
           super();
        this.A = A;
        this.B = B;
        this.C = C;
      }
      public abstract void handleA ();
      public abstract void handleB ();
      public abstract void handleC ();
    }
    // 实现了中介者接口的中介者类,封装了不同Colleague类的对象间的复杂操作
    public class ConcreteMediator extends Mediator{
        public ConcreteMediator(Colleague A, Colleague B, Colleague C) {
            super(A,B,C);
        }
        public void handleA() {
            B.handleInternal();
            C.handleInternal();
        }
        public void handleB() {
          A.handleInternal();
          C.handleInternal();
        }
        public void handleC() {
          A.handleInternal();
          B.handleInternal();
        }
    }
    // Colleague类在涉及其他Colleague类的复杂操作的时候,通过中介者调用
    public class A implements Colleague {
        public void handleExternal(Mediator mediator) {
          mediator.handleA();
          System.out.println("---------------");
        }
        public void handleInternal() {
            System.out.println("A");
        }
    }
    // Colleague类在涉及其他Colleague类的复杂操作的时候,通过中介者调用
    public class B implements Colleague {
        public void handleExternal(Mediator mediator) {
            mediator.handleB();
            System.out.println("---------------");
        }
        public void handleInternal() {
            System.out.println("B");
        }
    }
    // Colleague类在涉及其他Colleague类的复杂操作的时候,通过中介者调用
    public class C implements Colleague {
        public void handleExternal(Mediator mediator) {
            mediator.handleC();
            System.out.println("---------------");
        }
     
        public void handleInternal() {
            System.out.println("C");
        }
    }
    // 测试
    public class main {
        public static void main(String args []) {
            Colleague a = new A();
            Colleague b = new B();
            Colleague c = new C();
            Mediator mediator = new ConcreteMediator(a,b,c);
            a.handleExternal(mediator);
            b.handleExternal(mediator);
            c.handleExternal(mediator);
        }
    }
    结果输出
     
    中介者模式理解起来,就好像
     
    1. 你有很多杂乱的物品摆放在房间的不同地方,找起来很不好找,现在把这些物品统一放到一个柜子里,方便集中管理。
    2. 一群人去食堂打饭的时候,如果各自去取菜那么食堂可能乱做一团,所以这时候食堂大妈就成为了“中介者”
     
     

    原型模式(Prototype Pattern)

    原型模式是什么?
    一句话,原型模式就是克隆对象,完了。
    这么简单? 这也能叫设计模式?
    没错,就是这样
     
    让我们看下代码
    // 通过实现Cloneable接口并重写clone方法的方式,让Bar对象变得可克隆。
    public class Bar implements Cloneable {
        String value;
        public String getValue () {
          return value;
        }
        public void setValue (String value) {
            this.value = value;
        }
        public Bar clone() {
            Bar clone = null;
            try {
                clone = (Bar)super.clone();
            } catch (CloneNotSupportedException e) {
                e.printStackTrace();
            }
            return clone;
        }
    }
    // 调用clone方法可以克隆对象
    public class mian {
        public static void main(String args []) {
          Bar bar = new Bar();
          Bar bar2 = bar.clone();
          bar.setValue("1");
          bar2.setValue("2");
          System.out.println(bar.getValue());
          System.out.println(bar2.getValue());
        }
    }
     
    运行结果
     
    告诉我,原型模式的本质是什么
     
    原型模式的本质就是—— 套娃
     
    原型模式的优缺点
    • 原型模式的优点: 底层的二进制实现拷贝,相比起new操作可以节约性能
    • 原型模式的缺点: 构造函数没有调用,牺牲了灵活性
  • 相关阅读:
    spring-cloud服务器雪崩效应
    zookeeper集群
    Hash表的扩容(转载)
    算法时间复杂度和空间复杂度的计算
    Java 8 新特性
    jdk8 流操作
    jdk8十大特性并代码demo(转)
    hashmap实现原理2
    hashmap实现原理
    Semaphore控制同时访问的线程个数countdownlatch等待多个线程执行完本身线程再执行
  • 原文地址:https://www.cnblogs.com/penghuwan/p/12123954.html
Copyright © 2011-2022 走看看