Decorator模式

本文介绍了装饰模式,通过Component给出抽象接口,Concrete Component定义接收附加责任的类,Decorator持有构件实例,Concrete Decorator添加附加责任。并以图书馆的图书与录像带添加“可借阅”装饰为例进行演示,还给出了Component类设计及类结构简化的建议。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

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

// Component
abstract class LibraryItem {
  private int numCopies;

  public int getNumCopies() {
     return numCopies;
  }

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

  public abstract void Display();
}

// ConcreteComponent
class 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 );
  }
}

// ConcreteComponent
class 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 );
  }
}

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

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

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

// ConcreteDecorator
class 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的责任合并成一个类。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值