Decorator模式

    技术2022-05-11  139

    Component 给出一个抽象接口,以规范准备接收附加责任的对象。 Concrete Component 定义一个将要接收附加责任的类。 Decorator 持有一个构件(Component)对象的实例,并定义一个与抽象构件接口一致的接口。 Concrete Decorator 负责给构件对象"贴上"附加的责任。

    该例子演示了通过装饰模式为图书馆的图书与录像带添加"可借阅"装饰。

    // Componentabstract class LibraryItem {  private int numCopies;

      public int getNumCopies() {     return numCopies;  }

      public void setNumCopies(int numCopies) {     this.numCopies = numCopies;   }

      public abstract void Display();}

    // ConcreteComponentclass Book extends LibraryItem {  private string author;  private string title;

      public Book(string author,string title,int numCopies) {    this.author = author;    this.title = title;    this.numCopies = numCopies;  }

      public void Display() {    System.out.println( " Book ------ " );    System.out.println( " Author: ", author );    System.out.println( " Title: " + title );    System.out.println( " # Copies: " + NumCopies );  }}

    // ConcreteComponentclass Video extends LibraryItem {  private string director;  private string title;  private int playTime;

      public Video( string director, string title,    int numCopies, int playTime ) {    this.director = director;    this.title = title;    this.NumCopies = numCopies;    this.playTime = playTime;  }

      public void Display() {    System.out.println( " Video ----- " );    System.out.println( " Director: " + director );    System.out.println( " Title: " + title );    System.out.println( " # Copies: " + NumCopies );    System.out.println( " Playtime: " + playTime );  }}

    // Decoratorabstract class Decorator extends LibraryItem {  protected LibraryItem libraryItem;

      public Decorator ( LibraryItem libraryItem ) {     this.libraryItem = libraryItem;   }

      public void Display() {    libraryItem.Display();   }}

    // ConcreteDecoratorclass Borrowable extends Decorator {  protected ArrayList<String> borrowers = new ArrayList><String>();

      public Borrowable( LibraryItem libraryItem ) {     super( libraryItem );  }

      public void BorrowItem( string name ) {    borrowers.Add( name );    libraryItem.numCopies--;  }

      public void ReturnItem( string name ) {    borrowers.Remove( name );    libraryItem.NumCopies++;  }

      public void Display() {    super.Display();    for( string borrower in borrowers )      System.out.println( " borrower: " + borrower );  }}

    public class DecoratorApp {  public static void Main( string[] args ) {    // Create book and video and display    Book book = new Book( "Schnell", "My Home", 10 );    Video video = new Video( "Spielberg", "Schindler's list", 23, 60 );    book.Display();    video.Display();

        // Make video borrowable, then borrow and display    System.out.println( " Video made borrowable:" );    Borrowable borrowvideo = new Borrowable( video );    borrowvideo.BorrowItem( "Cindy Lopez" );    borrowvideo.BorrowItem( "Samuel King" );

        borrowvideo.Display();  }}

    尽量保持Component作为一个"轻"类,不要把太多的逻辑和状态放在Component类里。

    如果只有一个ConcreteComponent类而没有抽象的Component类(接口),那么Decorator类经常可以是ConcreteComponent的一个子类。

    如果只有一个ConcreteDecorator类,那么就没有必要建立一个单独的Decorator类,而可以把Decorator和ConcreteDecorator的责任合并成一个类。


    最新回复(0)