定义
创建对象的接口,让子类决定实例化哪一个类,工厂方法使得一个类的实例化延迟到其子类
通俗的说就是父类可以声明多种初始化方法提供给子类,子类按照自身需求可以动态的调用父类的方法完成特定的初始化操作
使用场景
1.在编码时不能预见需要创建哪种类的实例。
2.系统不应依赖于产品类实例如何被创建、组合和表达的细节
简单工厂模式
这个模式使用在业务简单的情况下,一般用于很少扩展的情况
其实现简单讲,具体的工厂生产抽象的产品,具体的产品继承与抽象的产品,获取具体产品的方式直接通过工厂方法即可
工厂类角色(BaseFactory):含有一定的业务逻辑和判断逻辑,根据逻辑不同,产生具体的产品
抽象产品角色(People):一般是具体产品要继承的父类或者实现的接口
具体产品角色(Student、Teacher):工厂类所创建的对象就是此角色
//抽象产品角色
#import <Foundation/Foundation.h>
@interface People : NSObject
- (void)doWork;
@end
#import "People.h"
@implementation People
-(void)doWork{
}
@end
//具体产品角色
#import "People.h"
@interface Student : People
- (void)doWork;
@end
----------------------------------
#import "Student.h"
@implementation Student
- (void)doWork{
NSLog(@"Student dowork");
}
@end
----------------------------------
#import "People.h"
@interface Teacher : People
- (void)doWork;
@end
----------------------------------
#import "Teacher.h"
@implementation Teacher
- (void)doWork{
NSLog(@"Teacher dowork");
}
@end
//工厂类角色
@class People;
typedef enum :NSUInteger{
PeopleType_Stu,
PeopleType_Tea,
}PeopleType;
@interface BaseFactory : NSObject
+ (People *)createPeopleWuthType:(PeopleType)type;
@end
----------------------------------
#import "BaseFactory.h"
#import "People.h"
#import "Student.h"
#import "Teacher.h"
@implementation BaseFactory
+ (People *)createPeopleWuthType:(PeopleType)type{
People *people = nil;
if (type == PeopleType_Stu) {
people = [[Student alloc]init];
}else{
people = [[Teacher alloc]init];
}
return people;
}
@end
//客户端的调用
#import "ViewController.h"
#import "Teacher.h"
#import "Student.h"
#import "BaseFactory.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
Teacher *teacher = (Teacher*)[BaseFactory createPeopleWuthType:PeopleType_Stu];
[teacher doWork];
Student *student = (Student*)[BaseFactory createPeopleWuthType:PeopleType_Tea];
[student doWork];
}
@end
log:
Student dowork
Teacher dowork
简单工厂模式的优缺点
- 优点
客户端调用简单明了,不需要关注太多的逻辑 - 缺点
导致工厂类业务逻辑庞大,违反了开闭原则,每增加一个产品,工厂类就会进行相应的修改,耦合度太高
抽象工厂模式
抽象工厂提供了创建一系列的相互依赖的接口,而无需指定他们具体的类
其实现简单讲:客户端在使用产品之前,先要通过抽象工厂获取一个具体的工厂,而由具体的工厂获取具体的产品
抽象工厂角色(BaseFactory):工厂方法的核心,与应用程序无关,是具体工厂角色必须实现的接口或者必须继承的父类
具体工厂类角色(AppleFactory、GoogleFactory):它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象
抽象产品角色(BasePhone、GoolePhone):它是具体产品继承的父类或者是实现的接口
具体产品角色(iPhone、GoolePhone、iWatch、GoogleWatch):具体工厂角色所创建的对象
//抽象工厂角色
#import <Foundation/Foundation.h>
@class BaseWatch;
@class BasePhone;
typedef enum:NSUInteger {
FactoryType_apple,
FactoryType_goole,
}FactoryType;
@interface BaseFactory : NSObject
+ (BaseFactory *)factoryWithBrand:(FactoryType)type;
-(BasePhone *)createPhone;
-(BaseWatch *)createWatch;
@end
-----------------------------------
#import "BaseFactory.h"
#import "AppleFactory.h"
#import "GoogleFactory.h"
#import "BasePhone.h"
#import "BaseWatch.h"
@implementation BaseFactory
+ (BaseFactory *)factoryWithBrand:(FactoryType)type{
BaseFactory *baseFactory = nil;
if (type == FactoryType_apple) {
baseFactory = [[AppleFactory alloc]init];
}else{
baseFactory = [[GoogleFactory alloc]init];
}
return baseFactory;
}
-(BasePhone *)createPhone{
return nil;
}
-(BaseWatch *)createWatch{
return nil;
}
@end
//具体工厂类角色
#import "BaseFactory.h"
@interface AppleFactory : BaseFactory
@end
---------------------
#import "AppleFactory.h"
#import "iPhone.h"
#import "iWatch.h"
@implementation AppleFactory
-(BasePhone *)createPhone{
return [[iPhone alloc]init];
}
-(BaseWatch *)createWatch{
return [[iWatch alloc]init];
}
@end
-----------------------
#import "BaseFactory.h"
@interface GoogleFactory : BaseFactory
@end
-----------------------
#import "GoogleFactory.h"
#import "GoolePhone.h"
#import "GoogleWatch.h"
@implementation GoogleFactory
-(BasePhone *)createPhone{
return [[GoolePhone alloc]init];
}
-(BaseWatch *)createWatch{
return [[GoogleWatch alloc]init];
}
@end
//抽象产品角色
#import <Foundation/Foundation.h>
@interface BasePhone : NSObject
@end
#import "BasePhone.h"
@implementation BasePhone
@end
-----------------
#import "BasePhone.h"
@interface GoolePhone : BasePhone
@end
#import "GoolePhone.h"
@implementation GoolePhone
@end
//具体产品角色
#import "BasePhone.h"
@interface iPhone : BasePhone
@end
-----------------
#import "iPhone.h"
@implementation iPhone
@end
-----------------
#import "BasePhone.h"
@interface GoolePhone : BasePhone
@end
-----------------
#import "GoolePhone.h"
@implementation GoolePhone
@end
-----------------
#import "BaseWatch.h"
@interface iWatch : BaseWatch
@end
-----------------
#import "iWatch.h"
@implementation iWatch
@end
-----------------
#import "BaseWatch.h"
@interface GoogleWatch : BaseWatch
@end
-----------------
#import "GoogleWatch.h"
@implementation GoogleWatch
@end
//客户端的调用
- (void)viewDidLoad {
[super viewDidLoad];
BaseFactory *factory = [BaseFactory factoryWithBrand:FactoryType_apple];
BasePhone *phone = [factory createPhone];
BaseWatch *watch = [factory createWatch];
NSLog(@"%@----%@",phone,watch);
}
log:
<iPhone: 0x60400000bfa0>----<iWatch: 0x60400000bf90>
抽象工厂模式的优缺点
- 优点
抽象工厂模式可以创建多个系列,并且每个系列抽象子类一一对应
通过抽象工厂模式统一控制多个系列的抽象子类,可以用多个系列的抽象子类完成一些复杂的需求 - 缺点
模式比较庞大,所以需要在适合的业务场景使用这种模式,否则会适得其反