Structural
Decorator
Main idea:
Attach additional responsibilities to an object dynamically.
Decorators provide a flexible alternative to subclassing for extending functionality.
动态的 给一个对象添加一些额外的职责,比生成子类更加灵活
装饰一个已有的对象,override或添加额外的功能,同时又不改变其结构。Dynamically decorate and remove. 看到的一个最合适的比喻:孙悟空有72变,当孙悟空变身成一座庙(Decorator)的时候,他还是孙悟空(被装饰的类本身),但是他拥有额外的庙的功能(additional responsibilities).
Example:
public abstract class BoardComponent { protected BoardComponent parent; public BoardComponent(){//} public abstract void Operation(); public abstract void Add(BoardComponent child); public abstract void Remove(BoardComponent child); public abstract void Update(); public void SetParent(BoardComponent parent){//} }
public class Square extends BoardComponent { public Square(){//} @Override public void Update() { //Square update } @Override public void Operation() { //Square operation } @Override public void Add(BoardComponent child){//} public ArrayListgetChildren(){//} @Override public void Remove(BoardComponent child){//} }
单出一个decorator类是遵循了Open/Close原则,可以拓展装饰类,只有一个装饰类的话可以省略这一步,直接写装饰concrete类。
public abstract class Decorator extends Square{ protected Square square; public BoardComponent parent; public Decorator(Square square) { this.square = square; } @Override public void Operation() { square.Operation(); } @Override public void Update() { square.Update(); } @Override public void Add(BoardComponent child) { square.Add(child); } @Override public void Remove(BoardComponent child) { square.Remove(child); } }
public class Shield extends Decorator{ public Shield(Square square) { super(square); } @Override public void Operation() { //Shield operation } @Override public void Update() { //Shield update } @Override public void Add(BoardComponent child) {//} @Override public void Remove(BoardComponent child) {//} }
使用Shield下的Square的成员:shield.square
Use Decorator when:
- To add responsibilities to individual objects dynamically and transparently, without affecting other objects
- For responsibilities that can be withdrawn. (e.g. logic gates)
- When extension by subclassing is impractical:
- When you have a large number of independent extensions possible and subclassing would create an unmanageable number of small classes without much code in them
- When a class definition may be hidden or unavailable for subclassing (e.g. final in Java)