首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

抽象工廠模式:創建相關物件家族的介面

     編輯:關於C++

定義與動機

在軟體設計中,若用戶端需手動建立物件,必須了解其內部結構、資料結構及方法呼叫,甚至牽涉其他依賴物件,導致建立過程複雜。工廠方法模式可解決單一物件建立問題,但面對「一組相關或相依的物件」時,抽象工廠模式更適合。

抽象工廠模式:提供一個介面,用於建立一系列相關或相依的物件,而無需指定其具體類別。(Gang of Four, Design Patterns)

類別結構

抽象工廠類別圖

客戶端僅依賴 AbstractFactory、AbstractProductA、AbstractProductB 等抽象介面,透過 createProductA()、createProductB() 建立產品,完全不需知道具體工廠(ConcreteFactory1/2)與具體產品(ConcreteProductA1/2、ConcreteProductB1/2)的存在。

抽象工廠 vs 工廠方法

兩種模式比較
特性抽象工廠工廠方法
建立方式物件組合類別繼承
產品數量一族相關產品(多種)單一產品
新增產品類型需修改抽象介面子類別化並重載工廠方法

程式範例:UI 主題系統

一個主題包含三個元件:主視圖、按鈕、工具列。不同主題(Serra、Acme)擁有不同風格。

抽象工廠介面

@interface BrandFactory : NSObject
+ (BrandFactory*)factoryWithName:(NSString*)name;
- (UIView*)brandView;
- (UIButton*)brandMainButton;
- (UIToolbar*)brandToolbar;
@end

具體工廠實作

@implementation SerraBrandFactory
- (UIView*)brandView {
    UIView* v = [[UIView alloc] init];
    v.backgroundColor = [UIColor redColor];
    return v;
}
- (UIButton*)brandMainButton {
    UIButton* b = [[UIButton alloc] init];
    [b setTitle:@"Serra" forState:UIControlStateNormal];
    return b;
}
- (UIToolbar*)brandToolbar {
    UIToolbar* tb = [[UIToolbar alloc] init];
    tb.barStyle = UIBarStyleBlack;
    UIBarButtonItem* item = [[UIBarButtonItem alloc] init];
    [item setImage:[UIImage imageNamed:@"cat.png"]];
    tb.items = @[item];
    return tb;
}
@end

@implementation AcmeBrandFactory
- (UIView*)brandView {
    UIView* v = [[UIView alloc] init];
    v.backgroundColor = [UIColor blueColor];
    return v;
}
- (UIButton*)brandMainButton {
    UIButton* b = [[UIButton alloc] init];
    [b setTitle:@"Acme" forState:UIControlStateNormal];
    return b;
}
- (UIToolbar*)brandToolbar {
    UIToolbar* tb = [[UIToolbar alloc] init];
    tb.barStyle = UIBarStyleBlack;
    UIBarButtonItem* item = [[UIBarButtonItem alloc] init];
    [item setImage:[UIImage imageNamed:@"dog.png"]];
    tb.items = @[item];
    return tb;
}
@end

工廠選擇邏輯

+ (BrandFactory*)factoryWithName:(NSString*)name {
    if ([name isEqualToString:@"Serra"]) return [[SerraBrandFactory alloc] init];
    if ([name isEqualToString:@"Acme"]) return [[AcmeBrandFactory alloc] init];
    return nil;
}

用戶端呼叫

- (void)viewDidLoad {
    [super viewDidLoad];
    BrandFactory* factory = [BrandFactory factoryWithName:@"Serra"];
    // BrandFactory* factory = [BrandFactory factoryWithName:@"Acme"];
    
    UIView* view = [factory brandView];
    view.frame = self.view.frame;
    [self.view addSubview:view];
    
    UIButton* btn = [factory brandMainButton];
    btn.frame = CGRectMake(60, 100, 200, 100);
    [self.view insertSubview:btn aboveSubview:view];
    
    UIToolbar* tb = [factory brandToolbar];
    tb.frame = CGRectMake(0, view.frame.size.height-40, view.frame.size.width, 40);
    [self.view insertSubview:tb aboveSubview:view];
}

優缺點總結

  • 優點:封裝物件建立細節、確保產品族一致性、用戶端與具體類別解耦、易於切換產品族。
  • 缺點:新增產品類型需修改抽象介面(違反開閉原則)、類別數量較多。

抽象工廠是基礎且常用的創建型模式,適合「一組相關物件需一起建立且保持一致」的場景。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved