程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> 抽象工廠(Abstract Factory)

抽象工廠(Abstract Factory)

編輯:關於C++

定義

在軟件設計中,如果客戶想手動創建一個對象,需要知道對象的詳細結構,包括其數據結構以及方法調用,如果運氣不好,還可能因為該對象引用了其他對象,導致客戶端還得了解其他對象,如此..使得該對象的創建變得復雜起來。之前講過的工廠方法模式可以解決該類問題,不過工廠方法模式一般用來解決單個對象的創建,對於需要創建多個有關聯的對象,那麼可能就需要使用抽象工廠模式的方法了。此時,客戶端只需要知道抽象出來的工廠以及自己所要的對象即可,不必清楚是誰創建以及怎樣創建那些具體的對象。


抽象工廠的具體定義為:抽象工廠提供固定的接口,用於創建一系列有關聯的對象,而不必指出其創建的細節。

ABSTRACT FACTORY: Provides an interface for creating families of related or dependent objects without specifying their concrete classes.*

* The original definition appeared in Design Patterns, by the “Gang of Four” (Addison-Wesley,1994).

其類似的類圖示意圖可能如下所示

\

上述的類圖示意圖中,如果客戶端想創建產品A和B,他只需要知道抽象工廠的固定接口createProductA和createProductB(當然還得知道AbstractFactory、AbstractProductA和AbstractProductB的存在),這樣他就能夠直接使用這兩個接口創建自己所需要的產品A和B了,而不需要知道產品A和B是誰創建的,在哪創建以及其他細節問題。通過抽象工廠的封裝,使得有關聯的對象的創建變得透明、簡單化。<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+tMvN4qOszai5/bPpz/O5pLOnxKPKvbXEseCzzLe9t6ijrMTjyOe5+7rz0PjP68ztvNPG5Mv7svrGt6Os1PLWsb3TsLTV1baousO1xLPpz/O5pLOnvdO/2sq1z9a8tL/Jo6y2+LK70OjSqrjEseS/zbuntsu1xLT6wuu199PDoaM8L3A+CjxwPtTa1eLA77u5tcOyubPk0ru147nY09q5pLOnt723qLrNs+nP87mks6e1xLnYz7XOyszio6zJz8281tCjrLPpz/O5pLOnysfT0LD8uqy5pLOnt723qLXEyei8xsSjyr21xKOsxuTW0GNyZWF0ZVByb2R1Y3RBus1jcmVhdGVQcm9kdWN0Qra8yvTT2rmks6e3vbeoo6y4/LbgtcSxyL3Pv8m8+8/Cse2jujwvcD4KPGJsb2NrcXVvdGU+CjxibG9ja3F1b3RlPgo8YmxvY2txdW90ZT4KPHA+Cjx0YWJsZSBib3JkZXI9"1" width="800" cellspacing="1" cellpadding="1"> 工廠方法和抽象工廠 抽象工廠 工廠方法 通過對象組合創建產品 通過類繼承創建產品 創建一類有關聯的產品,包括多種產品 創建一種產品 如果新增產品類型,必須修改抽象類的固定接口 子類化創建者並重載工廠方法以創建新產品


代碼示例

還是用主題來做個例子吧,這個例子是一個界面主題,該主題包括三部分:主視圖,按鈕,工具欄,不同的主題,這些元素的樣式不一樣,其他的是一樣的。因此由此可抽象出一個抽象工廠類,該類提供的固定接口是三個創建對象的方法,分別用來創建主視圖、按鈕和工具欄。主要的關系圖如下所示:

\

抽象類的定義如下所示:

#import 
#import 

@interface BrandFactory : NSObject
+ (BrandFactory*)fatoryWithName:(NSString*)name;
- (UIView*) brandView;
- (UIButton*) brandMainButton;
- (UIToolbar*) brandToolbar;
@end
上述代碼定義了三個固定的接口,而類方法fatoryWithName則會根據名字選擇對應的工廠。其中三個固定接口在抽象工廠類返回值是nil,而其中的類方法其實現如下所示:
+ (BrandFactory*)fatoryWithName:(NSString*)name
{
    BrandFactory* factory = nil;
    if([name isEqualToString:@"Serra"])
    {
        factory = [[SerraBrandFactory alloc] init];
    }
    else if([name isEqualToString:@"Acme"])
    {
        factory = [[AcmeBrandFactory alloc] init];
    }
    return factory;
}

對應於上圖的關系圖,實現的兩個具體工廠類如下所示:

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

@implementation AcmeBrandFactory
- (UIView*) brandView
{
    UIView* view = [[UIView alloc] init];
    view.backgroundColor = [UIColor blueColor];
    return view;
}
- (UIButton*) brandMainButton
{
    UIButton* button = [[UIButton alloc] init];
    [button setTitle:@"Acme" forState:UIControlStateNormal];
    return button;
}
- (UIToolbar*) brandToolbar
{
    UIToolbar* toolbar = [[UIToolbar alloc] init];
    toolbar.barStyle = UIBarStyleBlack;
    
    UIBarButtonItem* item = [[UIBarButtonItem alloc] init];
    [item setImage:[UIImage imageNamed:@"dog.png"]];
    
    toolbar.items = [NSArray arrayWithObject:item];
    
    return toolbar;
}
@end
上兩個實現分別返回自身定制的產品對象,而且都是通過基類抽象工廠類的固定接口返回的,這樣當客戶端需要構建這些對象的時候,直接使用抽象工廠提供的接口即可完成對所需的對象的創建,客戶端凍得代碼調用如下所示:
- (void)viewDidLoad 
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    // 客戶端加載視圖
    BrandFactory* brand = [BrandFactory fatoryWithName:@"Serra"];
    //BrandFactory* brand = [BrandFactory fatoryWithName:@"Acme"];
    
    UIView* brandView = [brand brandView];
    brandView.frame = self.view.frame;
    [self.view addSubview:brandView];
    
    UIButton* brandButton = [brand brandMainButton];
    brandButton.frame = CGRectMake(60, 100, 200, 100);
    [self.view insertSubview:brandButton aboveSubview:brandView];
    
    
    UIToolbar* brandToolbar = [brand brandToolbar];
    brandToolbar.frame = CGRectMake(0, brandView.frame.size.height-40, brandView.frame.size.width, 40);
    [self.view insertSubview:brandToolbar aboveSubview:brandView];
}
使用抽象工廠的設計模式後,通過工廠的封裝,客戶端不再需要知道產品的具體細節,實現內部的黑盒透明化,同時,如果新增了產品後,客戶端的代碼調用改動會很小,只需要指定名字即可。如果不適用抽象工廠,那麼常規的方法是這裡需要自己手動創建每個產品對象,需要了解產品的具體細節,同時如果要修改為其他產品的話,要修改大量代碼,可維護性和代碼的重用性大大降低。因此,抽象工廠模式是好的,工廠設計模式是好的。


總結

抽象工廠以及其他的工廠模式是一種比較常見以及簡單的編程設計模式,他也是最基本的設計模式,因為他涉及到許多類型對象的創建。在創建對象的時候,最好使用設計模式封裝對象,使得對象抽象出來,具體細節得到隱藏。


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved