定义
简单工厂模式(Simple Factory Pattern):又称为静态工厂方法(Static Factory Method)模式,它属于类创建型模式。在简单工厂模式中,可以根据参数的不同返回不同类的实例。简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。
模式结构
简单工厂模式包含如下角色:
- 工厂角色(
Factory):负责实现创建所有实例的内部逻辑 - 抽象产品角色(
Product):所创建的所有对象的父类,负责描述所有实例所共有的公共接口 - 具体产品角色(ConcreteProduct):创建目标,所有创建的对象都充当这个角色的某个具体类的实例。

代码实现
抽象产品
#import <Foundation/Foundation.h>#import <UIKit/UIKit.h>@protocol LHCarLicenseProtocol <NSObject>// 打印牌照- (NSString *)printLicenseNumber;@end@interface LHCarLicense : NSObject<LHCarLicenseProtocol>@property(nonatomic, copy)NSString *city; // 城市@property(nonatomic, copy, readonly)NSString *licenseNumber; // 车牌号@end
#import "LHCarLicense.h"@implementation LHCarLicense#pragma mark -#pragma mark Public Method- (NSString *)printLicenseNumber{_licenseNumber = [self getLicenseNumber];return _licenseNumber;}#pragma mark -#pragma mark Private Method// 获取牌照- (NSString *)getLicenseNumber{NSString *firstChar = [self getRandomChar];NSString *lastNumber = @"";for (NSInteger index = 0; index < 5; index++) {NSInteger random = [self getRandomNumber:0 to:1];NSString *newNumber = random == 0 ? [self getRandomChar] : [NSString stringWithFormat:@"%ld",(long)[self getRandomNumber:0 to:9]];lastNumber = [NSString stringWithFormat:@"%@%@",lastNumber,newNumber];}return [NSString stringWithFormat:@"%@%@·%@",_city,firstChar,lastNumber];}// 获取牌照号- (NSString *)getRandomChar{int NUMBER_OF_CHARS = 1;char data[NUMBER_OF_CHARS];data[0] = (char)('A' + (arc4random_uniform(26)));return [[NSString alloc] initWithBytes:data length:NUMBER_OF_CHARS encoding:NSUTF8StringEncoding];}//获取一个随机整数,范围在[from,to),包括from,不包括to-(NSInteger)getRandomNumber:(NSInteger)from to:(NSInteger)to{return (NSInteger)(from + (arc4random() % (to - from + 1)));}
具体产品
#import "LHCarLicense.h"@interface LHBlueCarLicense : LHCarLicense@end#import "LHBlueCarLicense.h"@implementation LHBlueCarLicense// 打印牌照号- (NSString *)printLicenseNumber{[super printLicenseNumber];return [NSString stringWithFormat:@"蓝色牌照: %@",self.licenseNumber];}@end
#import "LHCarLicense.h"@interface LHYellowCarLicense : LHCarLicense@end#import "LHYellowCarLicense.h"@implementation LHYellowCarLicense// 打印牌照号- (NSString *)printLicenseNumber{[super printLicenseNumber];return [NSString stringWithFormat:@"黄色牌照: %@",self.licenseNumber];}@end
工厂角色
#import <Foundation/Foundation.h>@class LHCarLicense;typedef enum : NSUInteger {ELicenseType_Blue,ELicenseType_Yellow} ELicenseType;@interface LHCarLicenseFactory : NSObject/*** 获取牌照工厂* @param type 牌照类型* @return 返回牌照对象*/+ (LHCarLicense *)createCarLicenseWithType:(ELicenseType)type;@end#import "LHCarLicenseFactory.h"#import "LHCarLicense.h"#import "LHBlueCarLicense.h"#import "LHYellowCarLicense.h"@implementation LHCarLicenseFactory+ (LHCarLicense *)createCarLicenseWithType:(ELicenseType)type{LHCarLicense *_license;switch (type) {case ELicenseType_Blue:_license = [[LHBlueCarLicense alloc] init];break;case ELicenseType_Yellow:_license = [[LHYellowCarLicense alloc] init];break;}return _license;}@end
客户端调用
#import "ViewController.h"#import "LHCarLicenseFactory.h"#import "LHCarLicense.h"@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];}- (void)didReceiveMemoryWarning {[super didReceiveMemoryWarning];}- (void)createLicense:(ELicenseType)type{LHCarLicense *_license = [LHCarLicenseFactory createCarLicenseWithType:type];_license.city = _txtCity.text ? _txtCity.text : @"京";_lbLicenseNumber.text = [_license printLicenseNumber];}#pragma mark -#pragma mark Button Event// 生成蓝色牌照- (IBAction)btnBlueEvent:(UIButton *)sender {[self createLicense:ELicenseType_Blue];}// 生成黄色牌照- (IBAction)btnYellowEvent:(UIButton *)sender {[self createLicense:ELicenseType_Yellow];}@end
这样工作人员就可以批量生成不同类型的车牌号了,输出结果如下:
优点
- 工厂类含有必要的判断逻辑,可以决定在什么时候创建哪一个产品类的实例,客户端可以免除直接创建产品对象的责任,通过这种做法实现了对责任的分割,它提供了专门的工厂类用于创建对象。
- 客户端无须知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数即可,对于一些复杂的类名,通过简单工厂模式可以减少使用者的记忆量。
通过引入配置文件,可以在不修改任何客户端代码的情况下更换和增加新的具体产品类,在一定程度上提高了系统的灵活性。
缺点
由于工厂类集中了所有产品创建逻辑,一旦不能正常工作,整个系统都要受到影响。
- 产品类本身是符合开闭原则的,对扩展开放对修改关闭,但是工厂类却违反了开闭原则,
- 系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,在产品类型较多时,有可能造成工厂逻辑过于复杂,不利于系统的扩展和维护。
- 简单工厂模式由于使用了静态工厂方法,造成工厂角色无法形成基于继承的等级结构。
