之前有寫過一個簡單工廠的的demo,接下來來一起實現一下它的升級版:工廠方法和抽象工廠
代碼實現 - 工廠方法
我們以寶馬汽車工廠生產寶馬汽車為例子,一個BMWFactory 和BMWCar
ICar 汽車協議接口
相當于汽車產品規范,所有汽車必須能行駛,該有的屬性配置得有 不能胡亂造汽車
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
//汽車協議接口類
@protocol ICar <NSObject>
@required
-(void)run:(int)speed;
@end
NS_ASSUME_NONNULL_END
寶馬車
遵循汽車產品規范(實現ICar協議)
#import <Foundation/Foundation.h>
#import "ICar.h"
NS_ASSUME_NONNULL_BEGIN
@interface BMWCar : NSObject<ICar>
-(void)run:(int)speed;
@end
NS_ASSUME_NONNULL_END
#import "BMWCar.h"
@implementation BMWCar
-(void)run:(int)speed {
NSLog(@"BMW時速%d",speed);
}
@end
汽車工廠協議接口
相當于營業執照 有該營業執照的工廠可以生產汽車
#import <Foundation/Foundation.h>
#import "ICar.h"
#import "IAutoParts.h"
NS_ASSUME_NONNULL_BEGIN
//汽車工廠 可以生產各種汽車
@protocol ICarFactory <NSObject>
//生產汽車
@required
-(id<ICar>)produceCar;
//生產汽車零部件
@required
-(id<IAutoParts>)produceAutoParts;
@end
NS_ASSUME_NONNULL_END
寶馬汽車工廠
寶馬汽車工廠要生產寶馬汽車則必須擁有汽車生產營業執照(實現ICarFactory協議)
只生產寶馬車 其他車品牌不生產(只創建BMWCar一種品牌的汽車)
#import <Foundation/Foundation.h>
#import "ICarFactory.h"
NS_ASSUME_NONNULL_BEGIN
@interface BMWFactory : NSObject<ICarFactory>
-(id<ICar>)produceCar;
@end
NS_ASSUME_NONNULL_END
#import "BMWFactory.h"
#import "BMWCar.h"
#import "BWMAutoParts.h"
@implementation BMWFactory
-(id<ICar>)produceCar {
return [[BMWCar alloc] init];//只生產寶馬汽車
}
-(id<IAutoParts>)produceAutoParts {
return [[BWMAutoParts alloc] init];
}
@end
工廠方法實現
指定寶馬汽車工廠 生產寶馬汽車
id<ICarFactory> carFactory = nil;//申明一個汽車工廠
carFactory = [[BMWFactory alloc] init];//指定寶馬工廠來生產
id<ICar> car = [carFactory produceCar];//寶馬汽車工廠只生產寶馬汽車
[car run:100];//汽車已生產 可以開跑啦
擴展:現在要想造奔馳車
同樣的原理,要造奔馳車 就建一個奔馳汽車工廠,專門用來生產奔馳車(單一原則)
奔馳汽車
#import <Foundation/Foundation.h>
#import "ICar.h"
NS_ASSUME_NONNULL_BEGIN
@interface BensCar : NSObject<ICar>
-(void)run:(int)speed;
@end
NS_ASSUME_NONNULL_END
#import "BensCar.h"
@implementation BensCar
-(void)run:(int)speed {
NSLog(@"Bens時速%d",speed);
}
@end
奔馳汽車工廠
#import <Foundation/Foundation.h>
#import "ICarFactory.h"
NS_ASSUME_NONNULL_BEGIN
@interface BMWFactory : NSObject<ICarFactory>
-(id<ICar>)produceCar;
@end
NS_ASSUME_NONNULL_END
#import "BMWFactory.h"
#import "BMWCar.h"
#import "BWMAutoParts.h"
@implementation BMWFactory
-(id<ICar>)produceCar {
return [[BMWCar alloc] init];
}
-(id<IAutoParts>)produceAutoParts {
return [[BWMAutoParts alloc] init];
}
@end
要生產奔馳車
我們只要在原有的基礎上指定奔馳工廠就可以造奔馳車了 而不用修改其他的邏輯
carFactory = [[BensFactory alloc] init];
id<ICarFactory> carFactory = nil;
carFactory = [[BensFactory alloc] init];
id<ICar> car = [carFactory produceCar];
[car run:100];
抽象工廠實現
定義與區別
區別:① 工廠方法模式只有一個抽象產品類,而抽象工廠模式有多個。
② 工廠方法模式的具體工廠類只能創建一個具體產品類的實例,而抽象工廠模式可以創建多個。
擴展:每種品牌的要生產對應的汽車配件怎么辦?
一個工廠不單單可以造汽車,同樣也是可以造該品牌的配件
所以,我們可以修改汽車工廠協議(ICarFactory)允許生產汽車配件(IAutoParts)
看到之前的ICarFactory有定義produceAutoParts,則BMWFactory,BensFactory有這個權限生產了
//生產汽車零部件
@required
-(id<IAutoParts>)produceAutoParts;
抽象工廠
//抽象工廠
id<ICarFactory> carFactory = nil;//申明一個汽車工廠
carFactory = [[BMWFactory alloc] init];//指定寶馬工廠來生產
id<ICar>car = [carFactory produceCar];//讓該工廠生產汽車(不同的工廠生產不會的車)
[car run:100];//汽車已生產 可以開跑啦
id<IAutoParts>parts = [carFactory produceAutoParts];//讓該工廠生產配件
[parts install];//生產的配件可以安裝啦
只要更換carFactory工廠 就可以達到生產奔馳汽車和奔馳配件的目的 其他都不用修改
carFactory = [[BensFactory alloc] init];//指定寶馬工廠來生產
Java的DataSouce就是抽象工廠的一個例子,數據庫連接可以使用常用的JDBC,Drui等方式,只要更換DataSouce就可以靈活更換