设计模式——装饰模式和代理模式

1 装饰模式

 装饰模式,动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活。装饰模式的结构如图所示。

 

public interface Component {
  void operation();
}

public interface Decorator extends Component {
  void addedBehavior();
}

public class ConcreteComponent implements Component {
  @Override
  public void operation() {
    System.out.println("operation!");
  }
}

public class ConcreteDecorator implements Decorator {
  private Component decoratedComponent;

  public ConcreteDecorator(Component decoratedComponent) {
    this.decoratedComponent = decoratedComponent;
  }

  @Override
  public void operation() {
    System.out.println("decorated operation!");

    decoratedComponent.operation();
  }

  @Override
  public void addedBehavior() {
    System.out.println("addedBehaviour!");
  }
}

public class Client {
  public static void main(String[] args) {
    Component component = new ConcreteComponent();
    component.operation();

    // 输出:
    // operation!

    Decorator decorator = new ConcreteDecorator(component);
    smart.operation();
    smart.addedBehavior();

    // 输出: 
    // decorated operation!
    // operation!
    // addedBehaviour!
  }
}
装饰模式的总结:装饰模式是为已有功能动态地添加更多功能的一种方式。
适用场景是:当系统需要新功能的时候,是向旧的类中添加新的代码。这些新加的代码通常装饰了原有类的核心职责或主要行为,但这种做法的问题在于,它们在主类中加入了新的字段,新的方法和新的逻辑,从而增加了主类的复杂度,而这些新加入的东西仅仅是为了满足一些只在某种特定情况下才会执行的特殊行为的需要。而装饰模式却提供了一个非常好的解决方案,它把每个要装饰的功能放在单独的类中,并让这个类保证它索要装饰的对象,因此,当需要执行特殊行为时,客户代码就可以在运行时根据需要有选择地、按顺序地使用装饰功能包装对象了。
装饰模式的优点:把类中的装饰功能从类中搬移去除,这样可以简化原有的类。这样做的更大的好处就是有效地把类的核心职责和服饰功能区分开了。而且可以去除相关类中重复的装饰逻辑。
 
二 代理模式
  代理模式,为其他对象提供一种代理以控制对这个对象的访问
Subject类,定义了RealSubject和Proxy的共用接口,这样就在任何使用RealSubject的地方都可以使用Proxy。代码如下:
abstract class Subject
{
    public abstract void Request();
}

RealSubject类,定义Proxy所代表的真实实体。
class RealSubject : Subject
{
      public override void Request()
      {
             Console.WriteLine("真实的请求");
      }
}

Proxy类,保存一个引用使得代理可以访问实体,并提供一个与Subject的接口相同的接口,这样代理就可以用来替代实体。
class Proxy : Subject
{
      RealSubject realSubject;
      public override void Request()
      {
             if (realSubject == null)
             {
                    realSubject = new RealSubject();
             }
             realSubject.Request();
      }
}

客户端代码:
static viod Main(string[] args)
{
      Proxy proxy = new Proxy();
      proxy.Request();
      Console.Read();
}

三 两种模式的区别

装饰模式:以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案;
代理模式:给一个对象提供一个代理对象,并有代理对象来控制对原有对象的引用;
装饰模式应该为所装饰的对象增强功能;代理模式对代理的对象施加控制,并不提供对象本身的增强功能

二者的实现机制确实是一样的,可以看到他们的实例代码重复是很多的。但就语义上说,这两者的功能是相反的,模式的一个重要作用是简化其他程序员对你程序的理解,
你在一个地方写装饰,大家就知道这是在增加功能,你写代理,大家就知道是在限制,
posted @ 2017-07-02 10:28  刘大飞  阅读(246)  评论(0编辑  收藏  举报