简单工厂模式
一、角色:
1、具体工厂
具有统一的接口;根据客户端请求,创建并返回相应具体的产品实例
2、抽象产品
具体产品的父类,定义具体产品所需要的属性和方法。子类通过继承来获取这些属性和方法(当整个系统中只有唯一的产品时,可以省略抽象产品。将具体工厂和具体产品进行合并)
3、具体产品
继承自抽象产品,具体工厂类创建的对象就是具体产品的实例
二、优缺点
1、优点
核心是具体工厂类,包含有必要的判断逻辑,决定什么条件下创建什么样的具体产品实例。客户端只需要调用,不用关心具体产品的创建过程和实施细则。这实现了责任的分离,成功解耦,有利于以后的维护和扩展
2、缺点
具体工厂集中了所有的产品创建逻辑。也将成为整个系统的瓶颈,如某些类不是继承自同一个抽象产品(父类)时,便造成了系统难以拓展
三、运用场景
具体产品的业务逻辑相同,但是各自的具体实现不同;相同的执行方法,不同的操作(条件)结果不同。
四、示意图
五、代码实例
============================== 具体工厂.h文件 ==============================
#import <Foundation/Foundation.h>
// 抽象产品类(产品的父类)
#import "LogInAbstractProduct.h"
typedef NS_ENUM(NSInteger, LogInType) {
loginType_one,
loginType_two
};
@interface LogInFactory : NSObject
/// 根据传入的条件,返回不同的登录方式
+ (LogInAbstractProduct *)loginWayChooseWithType:(LogInType)type;
@end
============================== 具体工厂.m文件 ==============================
#import "LogInFactory.h"
#import "LogInWayOne.h"
#import "LogInWayTwo.h"
@implementation LogInFactory
/// 根据传入的条件,返回不同的登录方式
+ (LogInAbstractProduct *)loginWayChooseWithType:(LogInType)type{
LogInAbstractProduct *product;
switch (type) {
case loginType_one:
product = [[LogInWayOne alloc] init];
break;
case loginType_two:
product = [[LogInWayTwo alloc] init];
break;
default:
break;
}
return product;
}
@end
============================== 抽象产品.h文件 ==============================
@interface LogInAbstractProduct : NSObject
@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSString *password;
- (void)requestLogin;
@end
============================== 具体产品.h文件 ==============================
// 产品一
@interface LogInWayOne : LogInAbstractProduct
@end
// 产品二
@interface LogInWayTwo : LogInAbstractProduct
@end
============================== 具体产品.m文件 ==============================
// 登录方式一的具体实现
@implementation LogInWayOne
- (void)requestLogin{
}
@end
// 登录方式二的具体实现
@implementation LogInWayTwo
- (void)requestLogin{
}
@end
============================== 客户端调用 ==============================
// 传入loginType_one、loginType_two得到不同的具体产品
LogInAbstractProduct *product = [LogInFactory loginWayChooseWithType:loginType_one];
[product requestLogin];