簡介
裝飾器模式(Decorator Pattern)是一種結構型設計模式。將物件放入到一個特殊封裝的物件中,為這個物件繫結新的行為,具備新的能力,同時又不改變其原有結構。
如果你希望在無需修改程式碼的情況下即可使用物件,且希望在執行時為物件新增額外的行為,可以使用裝飾模式。或者你用繼承來擴充套件物件行為的方案難以實現或者根本不可行,你可以使用該模式。
作用
- 動態地給一個物件新增一些額外的職責,相比生成子類更為靈活。
- 在不想增加很多子類的情況下擴充套件類的能力,實現強大擴充套件能力。
實現步驟
- 建立一個基礎工具介面或抽象類,設定基本的方法。
- 增加具體工具類實現基礎介面,保持工具類的規範性。
- 建立一個裝飾器抽象類,用於裝飾具體工具,聚合基礎工具,同時也可以實現基礎工具的介面。
- 增加多個裝飾器類,繼承抽象類,根據需要設定裝飾能力。
UML
Java程式碼
基礎形狀介面
// Shape.java 基礎形狀介面 public interface Shape { void draw(); }
具體形狀實現
// Circle.java 具體形狀實現了基礎形狀介面 public class Circle implements Shape { @Override public void draw() { System.out.println("Circle::draw()"); } } // Square.java 具體形狀實現了基礎形狀介面 public class Square implements Shape { @Override public void draw() { System.out.println("Square::draw()"); } }
抽象裝飾器
// ShapeDecorator.java 抽象裝飾類,是否實現Shape可選 public abstract class ShapeDecorator implements Shape { // public abstract class ShapeDecorator { protected Shape decoratedShape; public ShapeDecorator(Shape decoratedShape) { this.decoratedShape = decoratedShape; } public void draw() { decoratedShape.draw(); } }
具體裝飾器
// RedShapeDecorator.java 具體裝飾器1 public class RedShapeDecorator extends ShapeDecorator { public RedShapeDecorator(Shape decoratedShape) { super(decoratedShape); } @Override public void draw() { decoratedShape.draw(); setRedColor(decoratedShape); } private void setRedColor(Shape decoratedShape) { System.out.println( "RedShapeDecorator::setRedColor() " + decoratedShape.getClass().getName() ); } } // ShadowShapeDecorator.java 具體裝飾器2 public class ShadowShapeDecorator extends ShapeDecorator { public ShadowShapeDecorator(Shape decoratedShape) { super(decoratedShape); } @Override public void draw() { // decoratedShape.draw(); setShadow(decoratedShape); } private void setShadow(Shape decoratedShape) { System.out.println( "ShadowShapeDecorator::setShadow() " + decoratedShape.getClass().getName() ); } }
測試呼叫
/** * 裝飾器模式是將一個物件放到一個裝飾器物件中,執行裝飾器類裡的方法時,物件的行為能力得到增強。 * 先宣告具體物件,然後放到裝飾器,得到一個帶有裝飾器的新物件,該物件具備了新的能力。 */ // 宣告形狀 Shape circle = new Circle(); Shape square = new Square(); // 增加紅色裝飾 ShapeDecorator redCircle = new RedShapeDecorator(circle); ShapeDecorator redSquare = new RedShapeDecorator(square); circle.draw(); redCircle.draw(); redSquare.draw(); // 增加影子裝飾 ShadowShapeDecorator shadowCircle = new ShadowShapeDecorator(circle); ShadowShapeDecorator shadowSquare = new ShadowShapeDecorator(square); shadowCircle.draw(); shadowSquare.draw();
Go程式碼
基礎形狀介面
// Shape.go 基礎形狀介面 type Shape interface { Draw() GetName() string }
具體形狀實現
// Circle.go 具體形狀實現了基礎形狀介面 type Circle struct { } func (c *Circle) Draw() { fmt.Println("Circle::Draw()") } func (c *Circle) GetName() string { return "Circle" } // Square.go 具體形狀實現了基礎形狀介面 type Square struct { } func (c *Square) Draw() { fmt.Println("Square::Draw()") } func (c *Square) GetName() string { return "Square" }
抽象裝飾器
// ShapeDecorator.go 抽象裝飾類,是否實現Shape可選 type ShapeDecorator interface { Draw() }
具體裝飾器
// RedShapeDecorator.go 具體裝飾器1 type RedShapeDecorator struct { DecoratedShape Shape } func (r *RedShapeDecorator) Draw() { r.DecoratedShape.Draw() r.SetRedColor(r.DecoratedShape) } func (r *RedShapeDecorator) SetRedColor(decoratedShape Shape) { fmt.Println("RedShapeDecorator::setRedColor() " + decoratedShape.GetName()) } // ShadowShapeDecorator.go 具體裝飾器2 type ShadowShapeDecorator struct { DecoratedShape Shape } func (s *ShadowShapeDecorator) Draw() { // 裝飾器根據需要是否呼叫形狀的Draw方法 // s.DecoratedShape.Draw() s.SetShadow(s.DecoratedShape) } func (s *ShadowShapeDecorator) SetShadow(decoratedShape Shape) { fmt.Println("ShadowShapeDecorator::SetShadow() " + decoratedShape.GetName()) }
測試呼叫
/** * 裝飾器模式是將一個物件放到一個裝飾器物件中,執行裝飾器類裡的方法時,物件的行為能力得到增強。 * 先宣告具體物件,然後放到裝飾器,得到一個帶有裝飾器的新物件,該物件具備了新的能力。 */ // 宣告形狀 var circle = new(src.Circle) var square = new(src.Square) // 增加紅色裝飾 var redCircle = &src.RedShapeDecorator{ DecoratedShape: circle, } var redSquare = &src.RedShapeDecorator{ DecoratedShape: square, } circle.Draw() redCircle.Draw() redSquare.Draw() // 增加影子裝飾 var shadowCircle = &src.ShadowShapeDecorator{ DecoratedShape: circle, } var shadowSquare = &src.ShadowShapeDecorator{ DecoratedShape: square, } shadowCircle.Draw() shadowSquare.Draw()
更多語言版本
不同語言實現設計模式:https://github.com/microwind/design-pattern