先開個小頭,明天寫出來,不逼著自己是不會干活的。
題外話:
首先,設計模式是什么,為什么要用設計模式,設計模式用來做什么?
設計模式是什么?
In software engineering, a design pattern is a general reusable solution to a commonly occurring problem within a given context in software design. It is a description or template for how to solve a problem that can be used in many different situations. Patterns are formalized best practices that the programmer can use to solve common problems when designing an application or system.
對于一些經(jīng)常出現(xiàn)的具有相似特征的問題,設計一個模式,來解決問題,這個模式具有可移植性,對于不同的問題有高度的抽象解決方法。
為什么用設計模式?
程序之美在與簡潔,優(yōu)雅,易擴展,易維護,可復用,封閉性與開放性兼具。利用設計模式可以達到這些目的。
設計模式用來做什么?
當我們的問題可以抽象成用某個模式,可以利用現(xiàn)有的設計模式來組織我們的代碼。
常見的設計模式有:單例模式,委托模式,工廠設計模式,協(xié)議等等。
進入正題:
簡單工廠模式
專門定義一個類負責創(chuàng)建其他類的實例,被創(chuàng)建的類通常具有共同的父類。
簡單工廠模式的UML圖
簡單工廠模式的角色:
工廠,接受客戶端的請求,通過請求負責創(chuàng)建相應的產(chǎn)品對象。
抽象產(chǎn)品,工廠模式所創(chuàng)建對象的父類或者共同擁有的接口??梢允浅橄箢惢蚪涌?。
具體產(chǎn)品,工廠模式所創(chuàng)建的對象都是它的實例。
簡單工廠模式的主要實現(xiàn)
+(Product *)createProductWithType:(ProductType)type {
? ? switch(type){
? ? ? ? case ProductTypeOne:
? ? ? ? ? ? return[[ProductOne alloc]init];
? ? ? ? ? ? break;
? ? ? ? case ProductTypeTwo:
? ? ? ? ? ? return[[ProductTwo alloc]init];
? ? ? ? ? ? break;
? ? ? ? case ProductTypeThree:
? ? ? ? ? ? return[[ProductThree alloc]init];
? ? ? ? ? ? break;
? ? ? ? default:
? ? ? ? ? ? break;
? ? }
? ? return nil;
}
簡單工廠模式的主要缺點:
簡單工廠模式不僅對擴展開放,而且對修改也開放,所以違反了“開放-關閉原則”。說人話:當需要擴展一個產(chǎn)品時,不僅需要新建一個產(chǎn)品類,同時還要修改工廠方法。另外,所有產(chǎn)品對象創(chuàng)建的邏輯都被集中到了工廠類中,并不優(yōu)雅。
工廠方法
和簡單工廠方法相比,工廠方法的改進:將工廠類也抽象為了抽象工廠類和工廠子類,外界調(diào)用更加靈活,這也是對多態(tài)的一種體現(xiàn)。具體產(chǎn)品的生成分布到具體工廠中實現(xiàn)。
具體產(chǎn)品繼承抽象產(chǎn)品,具體工廠繼承抽象工廠。
//抽象產(chǎn)品
@interfaceProduct:NSObject
@end
@implementationProduct
@end
//具體產(chǎn)品1
@interfaceProductOne:Product
@end
@implementationProductOne
@end
//具體產(chǎn)品2
@interfaceProductTwo:Product
@end
@implementationProductTwo
@end
//抽象工廠
@interfaceFactory:NSObject
+(Product*)createProduct;
@end
@implementationFactory
+(Product*)createProduct
{
return [[Product alloc]init];
//如果Product是抽象的,那么這里可以返回nil
}
@end
//具體產(chǎn)品1的具體工廠
@interfaceProductOneFactory:Factory
+(Product*)createProduct;
@end
@implementationProductOneFactory
+(Product*)createProduct
{
return[[ProductOne alloc]init];
}@end
//具體產(chǎn)品2的具體工廠
@interfaceProductTwoFactory:Factory
+(Product*)createProduct;
@end
@implementationProductTwoFactory
+(Product*)createProduct
{
return[[ProductTwo alloc]init];
}
@end
//客戶端調(diào)用
Product*p=[ProductOneFactory createProduct];
NSLog(@"%@",p);
Product*p2=[ProductTwoFactory createProduct];
NSLog(@"%@",p2);
優(yōu)點
工廠方法模式的的優(yōu)點在于更大的靈活性,增加或刪除某個產(chǎn)品都不會對其他地方造成影響,更佳符合開放封閉原則。
而且對抽象的使用更佳深入,將工廠類也抽象為了抽象工廠類和工廠子類,外界調(diào)用更加靈活,這也是對多態(tài)的一種體現(xiàn)。
缺點
工廠方法模式的缺點也是非常顯而易見的,工廠方法模式中新增一個抽象子類,意味著工廠子類要跟著成對增加(OC中要x4),這樣會造成生成過多的類,工廠方法模式的復雜度也會隨之增加。
抽象工廠模式
抽象工廠模式和工廠方法模式很相似,但是抽象工廠模式將抽象發(fā)揮的更加極致,是三種工廠模式中最抽象的一種設計模式
抽象工廠模式中定義了抽象工廠類,抽象工廠類中定義了每個系列的抽象子類創(chuàng)建所需的方法,這些方法對應著不同類型的抽象子類實例化過程。每個工廠子類都對應著一個系列,工廠子類通過重寫這些方法來實例化當前系列的抽象子類。
抽象工廠模式與工廠方法模式
兩者都用于相同的目的:創(chuàng)建對象而不讓客戶端知道返回了什么確切的具體對象。
在工廠方法模式中,工廠子類負責抽象子類的實例化,每個工廠子類對應著一個抽象子類,且具有唯一性。而在抽象工廠模式中,一個工廠子類代表一個系列,工廠子類根據(jù)當前系列對不同類型的抽象子類進行創(chuàng)建。工廠方法模式中工廠子類對應的是一個類型的抽象子類,抽象工廠模式對應的是一個系列的抽象子類。
簡單說:工廠方法模式是針對單個類型的抽象類,而抽象工廠模式是針對具有相同結構的一系列類型的抽象類。
//抽象工廠
@interfaceBrandingFactory:NSObject
+(BrandingFactory*)factory;
-(Hatchback*)createHatchback;
-(SUV*)createSUV;
@end
@implementationBrandingFactory
+(BrandingFactory*)factory
{
if([[self class]isSubclassOfClass:[ToyotaBrandingFactory class]]){
return[[ToyotaBrandingFactory alloc]init];
}else if([[self class]isSubclassOfClass:[FordBrandingFactory class]]){
return[[FordBranding Factory alloc]init];
}else
{
return nil;
}
}
-(Hatchback*)createHatchback
{
return nil;
}
-(SUV*)createSUV
{
return nil;
}
@end
// 具體工廠
@interfaceFordBrandingFactory:BrandingFactory
@end
@implementationFordBrandingFactory
-(Hatchback*)createHatchback
{
FordHatchback*hatchback=[[FordHatchback alloc]init];
return hatchback;
}
-(SUV*)createSUV
{FordSUV *suv=[[FordSUValloc]init];
return suv;
}
@end
@interfaceToyotaBrandingFactory:BrandingFactory
@end
@implementationToyotaBrandingFactory
-(Hatchback*)createHatchback
{
ToyotaHatchback*hatchback=[[ToyotaHatchback alloc]init];
return hatchback;
}
-(SUV*)createSUV
{
ToyotaSUV*suv=[[ToyotaSUValloc]init];returnsuv;
}
@end
//抽象產(chǎn)品
@interfaceHatchback:NSObject
@end
@implementation Hatchback
@end
@interfaceSUV:NSObject
@end
@implementation SUV
@end
//具體產(chǎn)品
@interfaceFordHatchback:Hatchback
@end
@implementationFordHatchback
@end
@interfaceToyotaHatchback:Hatchback
@end
@implementationToyotaHatchback
@end
@interfaceFordSUV:SUV
@end
@implementationFordSUV
@end
@interfaceToyotaSUV:SUV
@end
@implementationToyotaSUV
@end
Cocoa中的抽象工廠模式
創(chuàng)建NSNumber實例的方式完全符合抽象工廠模式。
創(chuàng)建Cocoa對象有兩種方式:使用先alloc后init的方法,或者使用類中的+ className...方法。在Cocoa的基礎框架中,NSNumber類有很多類方法用于創(chuàng)建各種類型的NSNumber對象。
NSNumber*boolNumber=[NSNumbernumberWithBool:YES];NSNumber*charNumber=[NSNumbernumberWithChar:'a'];NSNumber*intNumber=[NSNumbernumberWithInteger:2];
每個返回的對象屬于代表最初輸入值的不同私有子類。打印如下:
2016-09-0810:30:28.415OCDemo[1164:29635]__NSCFBoolean2016-09-0810:30:28.416OCDemo[1164:29635]__NSCFNumber2016-09-0810:30:28.416OCDemo[1164:29635]__NSCFNumber
接受不同類型的參數(shù)并返回NSNumber實例的類方法是類工廠方法。NSNumber是抽象工廠實現(xiàn)的一個例子?;A框架中抽象工廠的此種特點被稱為“類簇”(Class Cluster)。
類簇是基礎框架中一種常見的設計模式,基于抽象工廠模式的思想。它將若干相關的私有具體工廠子類集合到一個工友的抽象超類指下。例如,“數(shù)”包含了各種數(shù)值類型的完整集合,如字符、整數(shù)、浮點數(shù)和雙精度輸。這些數(shù)值類型是”數(shù)“的字集。所以NSNumber自然成為這些數(shù)子類型的超類型(super-type)。NSNumber有一系列共有API,定義了各種類型的數(shù)所共有的行為??蛻舳嗽谑褂脮r無需知道NSNumber實例的具體類型。
類簇是抽象工廠的一種形式。比如,NSNumber本身是一個高度抽象的工廠,而NSCFBoolean和NSCFNumber是具體的工廠子類。子類是具體工廠,因為他們重載了NSNumber中聲明的公有工廠方法以生產(chǎn)產(chǎn)品。例如,intValue和boolValue根據(jù)實際NSNumber對象的內(nèi)部值返回一個值,雖說值的數(shù)據(jù)類型可能不同。從這些工廠方法返回的實際值就是抽象工廠模式的最初定義中所說的“產(chǎn)品”。
創(chuàng)建抽象產(chǎn)品的工廠方法與創(chuàng)建抽象工廠的工廠方法之間有個不同點。顯然,像intValue和boolValue這樣的工廠方法,應在具體工廠(NSCFBoolean和NSCFNumber)中重載以返回實際值(產(chǎn)品)。其他像numberWithBool:和numberWithInteger:這樣的工廠方法并不是為了返回產(chǎn)品,而是為了返回能返回產(chǎn)品的工廠,因此它們不應該在具體工廠子類中重載。
其他時限為類簇的基礎類有NSData、NSArray、NSDictionary、NSString。
在這三種設計模式中都有一個共同的特點,就是繼承自抽象類的抽象子類或工廠子類,都必須對抽象類定義的方法給出對應的實現(xiàn)(可以相同,也可以不同),這種模式才叫做工廠模式。工廠模式的核心就是抽象和多態(tài),抽象子類繼承自抽象類,對抽象類中定義的方法和屬性給出不同的實現(xiàn)方式,通過多態(tài)的方式進行方法實現(xiàn)和調(diào)用,構成了工廠模式的核心。
在工廠類中對“開放-封閉原則”有著完美的體現(xiàn),對擴展的開放以及對修改的封閉。例如最抽象的抽象工廠模式,抽象工廠模式中增加新的系列,直接擴展一個工廠子類及對應的抽象子類,對整個模式框架不會帶來其他影響。如果增加一個新的類型,創(chuàng)建新的類型對應的類,并對整個抽象工廠類及其子類進行方法擴展。
在外界使用抽象子類的功能時,不需要知道任何關于抽象子類的特征,抽象子類也不會出現(xiàn)在外界,外界只需要和抽象類打交道就可以。工廠模式將抽象子類的創(chuàng)建和實現(xiàn)分離,具體的創(chuàng)建操作由工廠類來進行,抽象子類只需要關注業(yè)務即可,外界不需要知道抽象子類實例化的過程。這種方式非常靈活并易于擴展,而且在大型項目中尤為明顯,可以很好的避免代碼量過多的問題。
大部分摘自:http://ibloodline.com/articles/2016/09/06/factory.html