設(shè)計(jì)模式系列文章
《iOS設(shè)計(jì)模式(1)簡(jiǎn)單工廠模式》
《iOS設(shè)計(jì)模式(2)工廠模式》
《iOS設(shè)計(jì)模式(3)適配器模式》
《iOS設(shè)計(jì)模式(5)策略模式》
《iOS設(shè)計(jì)模式(6)模板模式》
《iOS設(shè)計(jì)模式(7)建造者模式》
1.概念描述
今天我們學(xué)習(xí)一下抽象工廠模式,照例先把百度百科上的正規(guī)解釋給大家展示出來(lái)看看。
抽象工廠模式是所有形態(tài)的工廠模式中最為抽象和最具一般性的一種形態(tài)。抽象工廠模式是指當(dāng)有多個(gè)抽象角色時(shí),使用的一種工廠模式。抽象工廠模式可以向客戶端提供一個(gè)接口,使客戶端在不必指定產(chǎn)品的具體的情況下,創(chuàng)建多個(gè)產(chǎn)品族中的產(chǎn)品對(duì)象。根據(jù)里氏替換原則,任何接受父類型的地方,都應(yīng)當(dāng)能夠接受子類型。因此,實(shí)際上系統(tǒng)所需要的,僅僅是類型與這些抽象產(chǎn)品角色相同的一些實(shí)例,而不是這些抽象產(chǎn)品的實(shí)例。換言之,也就是這些抽象產(chǎn)品的具體子類的實(shí)例。工廠類負(fù)責(zé)創(chuàng)建抽象產(chǎn)品的具體子類的實(shí)例。---百度百科
在上面抽象工廠模式的定義中涉及到了一個(gè)名詞:產(chǎn)品族。他的意思是有多類產(chǎn)品,每一類產(chǎn)品中又分多種相似的產(chǎn)品。下面是百度百科的解釋:
是指位于不同產(chǎn)品等級(jí)結(jié)構(gòu)中,功能相關(guān)聯(lián)的產(chǎn)品組成的家族。一般是位于不同的等級(jí)結(jié)構(gòu)中的相同位置上。顯然,每一個(gè)產(chǎn)品族中含有產(chǎn)品的數(shù)目,與產(chǎn)品等級(jí)結(jié)構(gòu)的數(shù)目是相等的,形成一個(gè)二維的坐標(biāo)系,水平坐標(biāo)是產(chǎn)品等級(jí)結(jié)構(gòu),縱坐標(biāo)是產(chǎn)品族。叫做相圖。---百度百科

2.實(shí)例場(chǎng)景
看過(guò)《iOS設(shè)計(jì)模式(1)簡(jiǎn)單工廠模式》和《iOS設(shè)計(jì)模式(2)工廠模式》的同學(xué)知道在前兩篇文章中我們舉了一個(gè)汽車牌照的例子,本文繼續(xù)承接上兩篇文章中的例子。
在現(xiàn)實(shí)生活中的汽車牌照沒有咱們例子中那么簡(jiǎn)單。除了國(guó)家規(guī)定不同類型的車輛所上的牌照不同意外,不同省份的牌照生成規(guī)則也不一樣,最明顯的就是牌照號(hào)中那唯一的漢字,比如北京市的牌照就是“京X·XXXXX”,而河北省的牌照就是“冀X·XXXXX”,當(dāng)然同一省份不同地區(qū)的牌照在漢字后面的那個(gè)字母也不一樣。
今天咱們只看不同省份牌照不一樣的需求怎么解決。這就需要我們?cè)谥岸x的藍(lán)色車牌和黃色車牌(LHBlueCarLicense和LHYellowCarLicense)中再派生出不同地區(qū)的藍(lán)色車牌和黃色車牌類。這里我們就舉北京和河北兩個(gè)例子:LHBeijingBlueCarLicense、LHBeijingYellowCarLicense和LHHebeiBlueCarLicense、LHHebeiYellowCarLicense。
3.代碼實(shí)現(xiàn)
兩個(gè)車牌基類:藍(lán)色車牌和黃色車牌
#import "LHCarLicenseProtocol.h"
@interface LHBlueCarLicense : NSObject<LHCarLicenseProtocol>
@property(nonatomic, copy)NSString *city; // 城市
@end
#import "LHBlueCarLicense.h"
@implementation LHBlueCarLicense
// 打印車牌號(hào)
- (NSString *)printLicenseNumber{
return nil;
}
@end
#import "LHCarLicenseProtocol.h"
@interface LHYellowCarLicense : NSObject<LHCarLicenseProtocol>
@property(nonatomic, copy)NSString *city; // 城市
@end
#import "LHYellowCarLicense.h"
@implementation LHYellowCarLicense
// 打印牌照號(hào)
- (NSString *)printLicenseNumber{
return nil;
}
@end
下面是北京藍(lán)色車牌和黃色車牌類實(shí)現(xiàn)(河北車牌代碼一樣,這里就不再貼代碼了)
#import "LHBlueCarLicense.h"
@interface LHBeijingBlueCarLicense : LHBlueCarLicense
@property(nonatomic, copy, readonly)NSString *licenseNumber; // 車牌號(hào)
@end
#import "LHBeijingBlueCarLicense.h"
#import "LHCommonClass.h"
@implementation LHBeijingBlueCarLicense
// 打印牌照號(hào)
- (NSString *)printLicenseNumber{
self.city = @"京";
_licenseNumber = [LHCommonClass getLicenseNumberWithCity:self.city];
return [NSString stringWithFormat:@"北京藍(lán)色車牌號(hào):%@",_licenseNumber];
}
@end
#import "LHYellowCarLicense.h"
@interface LHBeijingYellowCarLicense : LHYellowCarLicense
@property(nonatomic, copy, readonly)NSString *licenseNumber; // 車牌號(hào)
@end
#import "LHBeijingYellowCarLicense.h"
#import "LHCommonClass.h"
@implementation LHBeijingYellowCarLicense
// 打印牌照號(hào)
- (NSString *)printLicenseNumber{
self.city = @"京";
_licenseNumber = [LHCommonClass getLicenseNumberWithCity:self.city];
return [NSString stringWithFormat:@"北京黃色車牌號(hào):%@",_licenseNumber];
}
@end
產(chǎn)品族類定義完成后,下面我們看工廠類的實(shí)現(xiàn)。之前我們的工廠類定義的是藍(lán)色車牌工廠類和黃色車牌工廠類,在抽象工廠模式中我們要定義的是北京車牌工廠類和河北車牌工廠類。我們先看工廠基類的定義
#import <Foundation/Foundation.h>
@class LHBlueCarLicense;
@class LHYellowCarLicense;
@interface LHCarLicenseFactory : NSObject
/**
* 獲取藍(lán)色牌照工廠
*
* @return 返回牌照對(duì)象
*/
+ (LHBlueCarLicense *)createBlueCarLicense;
/**
* 獲取黃色牌照工廠
*
* @return 返回牌照對(duì)象
*/
+ (LHYellowCarLicense *)createYellowCarLicense;
@end
#import "LHCarLicenseFactory.h"
#import "LHBlueCarLicense.h"
#import "LHYellowCarLicense.h"
@implementation LHCarLicenseFactory
// 獲取藍(lán)色牌照工廠
+ (LHBlueCarLicense *)createBlueCarLicense
{
return nil;
}
// 獲取黃色牌照工廠
+ (LHYellowCarLicense *)createYellowCarLicense
{
return nil;
}
@end
下面看北京工廠類的實(shí)現(xiàn)(河北工廠類代碼實(shí)現(xiàn)一樣,不在這里貼了)
#import "LHCarLicenseFactory.h"
@interface LHBeijingCarLicenseFactory : LHCarLicenseFactory
@end
#import "LHBeijingCarLicenseFactory.h"
#import "LHBlueCarLicense.h"
#import "LHYellowCarLicense.h"
#import "LHBeijingBlueCarLicense.h"
#import "LHBeijingYellowCarLicense.h"
@implementation LHBeijingCarLicenseFactory
// 北京藍(lán)色牌照
+ (LHBlueCarLicense *)createBlueCarLicense
{
LHBlueCarLicense *_license = [[LHBeijingBlueCarLicense alloc] init];
return _license;
}
// 北京黃色牌照
+ (LHYellowCarLicense *)createYellowCarLicense
{
LHYellowCarLicense *_license = [[LHBeijingYellowCarLicense alloc] init];
return _license;
}
@end
那么客戶端的調(diào)用就簡(jiǎn)單多了
// 北京藍(lán)色牌照點(diǎn)擊事件
- (IBAction)btnBeijingBlueEvent:(UIButton *)sender {
LHBlueCarLicense *_license = [LHBeijingCarLicenseFactory createBlueCarLicense];
_lbText.text = [NSString stringWithFormat:@"%@\n%@",_lbText.text,_license.printLicenseNumber];
}
// 北京黃色牌照點(diǎn)擊事件
- (IBAction)btnBeijingYellowEvent:(UIButton *)sender {
LHYellowCarLicense *_license = [LHBeijingCarLicenseFactory createYellowCarLicense];
_lbText.text = [NSString stringWithFormat:@"%@\n%@",_lbText.text,_license.printLicenseNumber];
}
輸出結(jié)果:

這樣,抽象工廠模式代碼實(shí)現(xiàn)就完成了。不過(guò)個(gè)人覺得抽象模式還是比較復(fù)雜的,而且擴(kuò)展擴(kuò)展起來(lái)也不是很靈活,如果產(chǎn)品族非常多的話會(huì)生成很多產(chǎn)品類出來(lái),是一件恐怖的事情。所以有人結(jié)合簡(jiǎn)單工廠模式和工廠模式,利用反射(java)機(jī)制對(duì)抽象工廠模式進(jìn)行優(yōu)化,避免生成太多的產(chǎn)品類。感興趣的同學(xué)可以看看這篇文章
引用
配圖引用