天天看點

設計模式——裝飾模式和代理模式

代理模式, 裝飾模式

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();
}      
裝飾模式:以對用戶端透明的方式擴充對象的功能,是繼承關系的一個替代方案;
代理模式:給一個對象提供一個代理對象,并有代理對象來控制對原有對象的引用;
裝飾模式應該為所裝飾的對象增強功能;代理模式對代理的對象施加控制,并不提供對象本身的增強功能

二者的實作機制确實是一樣的,可以看到他們的執行個體代碼重複是很多的。但就語義上說,這兩者的功能是相反的,模式的一個重要作用是簡化其他程式員對你程式的了解,
你在一個地方寫裝飾,大家就知道這是在增加功能,你寫代理,大家就知道是在限制,