Design Pattern
↳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:
Component Class
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){//}
}
Component Concrete Class
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 ArrayList<BoardComponent> getChildren(){//}
@Override
public void Remove(BoardComponent child){//}
}
Decorator Class
单出一个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);
}
}
Decorator Concrete Class
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
Conclusion
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)