在日常開發中,當需要給一個現有類新增附加職責,而又不能採用生成子類的方法進行擴充時。例如,該類被隱藏或者該類是終極類或者採用繼承方式會產生大量的子類。這時候,我們該怎麼辦呢?我們可以使用裝飾器器模式來解決這個問題,本文將從以下四個方面講解裝飾器器模式。
裝飾器模式(Decorator Pattern)是一種結構型設計模式,它可以在不改變現有物件的結構的情況下,動態地給物件增加一些額外的功能。裝飾器模式通過建立一個包裝物件(即裝飾器)來包裹真實物件,並在保持真實物件的介面不變的前提下,為其提供額外的功能。裝飾器模式可以在執行時根據需要選擇不同的裝飾器來組合和修改物件的行為。
推薦博主開源的 H5 商城專案waynboot-mall,這是一套全部開源的微商城專案,包含三個專案:運營後臺、H5 商城前臺和伺服器端介面。實現了商城所需的首頁展示、商品分類、商品詳情、商品 sku、分詞搜尋、購物車、結算下單、支付寶/微信支付、收單評論以及完善的後臺管理等一系列功能。 技術上基於最新得 Springboot3.0、jdk17,整合了 MySql、Redis、RabbitMQ、ElasticSearch 等常用中介軟體。分模組設計、簡潔易維護,歡迎大家點個 star、關注博主。
github 地址:https://github.com/wayn111/waynboot-mall
裝飾器模式的優點有:
裝飾器模式的缺點有:
裝飾器模式適用於以下場景:
以下是一個實現裝飾器模式的 java 範例程式碼
//抽象元件介面
public interface Shape {
void draw();
}
//具體元件類:圓形
public class Circle implements Shape {
@Override
public void draw() {
System.out.println("Drawing a circle");
}
}
//具體元件類:矩形
public class Rectangle implements Shape {
@Override
public void draw() {
System.out.println("Drawing a rectangle");
}
}
//抽象裝飾器類
public abstract class ShapeDecorator implements Shape {
//持有一個抽象元件物件
protected Shape shape;
//構造方法
public ShapeDecorator(Shape shape) {
this.shape = shape;
}
//呼叫被包裝物件的方法
@Override
public void draw() {
shape.draw();
}
}
//具體裝飾器類:紅色裝飾器
public class RedShapeDecorator extends ShapeDecorator {
//構造方法
public RedShapeDecorator(Shape shape) {
super(shape);
}
//重寫draw方法,在呼叫被包裝物件的方法之前或之後新增新的功能
@Override
public void draw() {
//呼叫被包裝物件的方法
super.draw();
//新增新的功能
setRedBorder();
}
//定義新的功能方法
private void setRedBorder() {
System.out.println("Setting red border");
}
}
//具體裝飾器類:綠色裝飾器
public class GreenShapeDecorator extends ShapeDecorator {
//構造方法
public GreenShapeDecorator(Shape shape) {
super(shape);
}
//重寫draw方法,在呼叫被包裝物件的方法之前或之後新增新的功能
@Override
public void draw() {
//呼叫被包裝物件的方法
super.draw();
//新增新的功能
setGreenBorder();
}
//定義新的功能方法
private void setGreenBorder() {
System.out.println("Setting green border");
}
}
//測試類
public class DecoratorPatternDemo {
public static void main(String[] args) {
//建立一個圓形物件
Shape circle = new Circle();
//建立一個矩形物件
Shape rectangle = new Rectangle();
//建立一個紅色裝飾器物件,包裝圓形物件
Shape redCircle = new RedShapeDecorator(circle);
//建立一個綠色裝飾器物件,包裝矩形物件
Shape greenRectangle = new GreenShapeDecorator(rectangle);
//呼叫各個物件的方法,展示不同的效果
System.out.println("Normal circle:");
circle.draw();
System.out.println("Normal rectangle:");
rectangle.draw();
System.out.println("Red circle:");
redCircle.draw();
System.out.println("Green rectangle:");
greenRectangle.draw();
}
}
輸出結果如下:
Normal circle:
Drawing a circle
Normal rectangle:
Drawing a rectangle
Red circle:
Drawing a circle
Setting red border
Green rectangle:
Drawing a rectangle
Setting green border
要想再 Spring 專案中應用裝飾器模式,只需對以上程式碼進行簡單改造即可,
@Component
public class Rectangle implements Shape {
@Override
public void draw() {
System.out.println("Drawing a rectangle");
}
}
@Component
public class Rectangle implements Shape {
@Override
public void draw() {
System.out.println("Drawing a rectangle");
}
}
@Component
public class GreenShapeDecorator extends ShapeDecorator {
// 構造方法
public GreenShapeDecorator(@Qualifier("rectangle") Shape shape) {
super(shape);
}
// 重寫draw方法,在呼叫被包裝物件的方法之前或之後新增新的功能
@Override
public void draw() {
// 呼叫被包裝物件的方法
super.draw();
// 新增新的功能
setGreenBorder();
}
// 定義新的功能方法
private void setGreenBorder() {
System.out.println("Setting green border");
}
}
@Component
public class RedShapeDecorator extends ShapeDecorator {
// 構造方法
public RedShapeDecorator(@Qualifier("circle") Shape shape) {
super(shape);
}
// 重寫draw方法,在呼叫被包裝物件的方法之前或之後新增新的功能
@Override
public void draw() {
// 呼叫被包裝物件的方法
super.draw();
// 新增新的功能
setRedBorder();
}
// 定義新的功能方法
private void setRedBorder() {
System.out.println("Setting red border");
}
}
@SpringBootTest
@RunWith(SpringRunner.class)
public class DecoratorTest {
// 從Spring容器中獲取Context物件
@Autowired
private RedShapeDecorator redCircle;
@Autowired
private GreenShapeDecorator greenRectangle;
@Test
public void test() {
System.out.println("Red circle:");
redCircle.draw();
System.out.println("Green rectangle:");
greenRectangle.draw();
}
}
輸出結果如下:
Red circle:
Drawing a circle
Setting red border
Green rectangle:
Drawing a rectangle
Setting green border
裝飾器模式可以將不同功能的單個模組規劃至不同的裝飾器類中,各裝飾器類獨立自主,各司其職。使用者端可以根據自己的需求自由搭配各種裝飾器,每加一層裝飾就會有新的特性體現出來,巧妙的設計讓功能模組層層疊加,裝飾之上套裝飾,最終使原始物件的特性動態地得到增強。
關注公眾號【waynblog】每週分享技術乾貨、開源專案、實戰經驗、國外優質文章翻譯等,您的關注將是我的更新動力!