概念
抽象工厂提供一个固定的接口,用于创建一系列有关联或相依存的对象,而不必指定其具体类或其创建的细节。客户端与从工厂得到的具体对象之间没有耦合。
实例
我们以一个员工与部门的例子来实现,首先我们创建员工和部门的数据模型,并各声明一个名称的属性:
~/Model/Staff.h
Staff.h
@interface Staff : NSObject
@property(nonatomic, copy) NSString *staffName;
@end
~/Model/Department.h
Department.h
@interface Department : NSObject
@property(nonatomic, copy) NSString *departmentName;
@end
然后分别创建员工协议和部门协议,分别用于插入到数据库中加入员工和加入部门:
~/Staff/StaffProtocol.h
StaffProtocol.h
@class Staff;
@protocol StaffProtocol <NSObject>
- (void)insertStaff:(Staff *)staff;
@end
~/Department/DepartmentProtocol.h
DepartmentProtocol.h
@class Department;
@protocol DepartmentProtocol <NSObject>
- (void)insertDepartment:(Department *)department;
@end
然后分别创建基于各自协议的 SQLServer数据库数据处理类,实现协议 insert 方法:
~/Staff/SQLServerStaff.h
SQLServerStaff.h
#import <Foundation/Foundation.h>
#import "StaffProtocol.h"
#import "Staff.h"
@interface SQLServerStaff : NSObject <StaffProtocol>
@end
~/Staff/SQLServerStaff.m
SQLServerStaff.m
@implementation SQLServerStaff
- (void)insertStaff:(Staff *)staff {
NSLog(@"%s 插入员工【%@】",__func__,staff.staffName);
}
@end
~/Department/SQLServerDepartment.h
SQLServerDepartment.h
#import <Foundation/Foundation.h>
#import "DepartmentProtocol.h"
#import "Department.h"
@interface SQLServerDepartment : NSObject <DepartmentProtocol>
@end
~/Department/SQLServerDepartment.m
SQLServerDepartment.m
@implementation SQLServerDepartment
- (void)insertDepartment:(Department *)department {
NSLog(@"%s 插入【%@】部门",__func__,department.departmentName);
}
@end
同样方式创建 Access 数据库的相应数据处理类。
工厂实现
创建数据库的工厂协议 DBFactoryProtocol,声明两个创建数据库的协议方法:
~/Basic version/DBFactoryProtocol.h
#import "StaffProtocol.h"
#import "DepartmentProtocol.h"
@protocol DBFactoryProtocol <NSObject>
- (id <StaffProtocol>)createStaffDB;
- (id <DepartmentProtocol>)createDepartmentDB;
@end
创建 SQLServer 的工厂类 SQLServerFactory 实现协议方法:
#import "SQLServerFactory.h"
#import "SQLServerStaff.h"
#import "SQLServerDepartment.h"
@implementation SQLServerFactory
- (id <StaffProtocol>)createStaffDB {
return [[SQLServerStaff alloc] init];
}
- (id <DepartmentProtocol>)createDepartmentDB {
return [[SQLServerDepartment alloc] init];
}
@end
在创建相应数据库,产出相应遵循相应协议的数据处理类。
同样的方式实现 Access 数据库工厂类。
实际上这里写的有点不好,不应该用协议,使用继承会更为合理。使用继承就不会产生方法的连续调用。
于是实现了以下优化版本:
~/Optimized version/DBFactory.h
DBFactory.h
#import <Foundation/Foundation.h>
#import "StaffProtocol.h"
#import "DepartmentProtocol.h"
typedef NS_ENUM(NSUInteger, DBType) {
DBTypeSQLServer,
DBTypeAccess
};
@interface DBFactory : NSObject
+ (id <StaffProtocol>)createStaffDBWithDBType:(DBType)dbType;
+ (id <DepartmentProtocol>)createDepartmentDBWithDBType:(DBType)dbType;
@end
~/Optimized version/DBFactory.m
DBFactory.m
#import "DBFactory.h"
#import "SQLServerStaff.h"
#import "SQLServerDepartment.h"
#import "AccessStaff.h"
#import "AccessDepartment.h"
@implementation DBFactory
+ (id <StaffProtocol>)createStaffDBWithDBType:(DBType)dbType {
switch (dbType) {
case DBTypeSQLServer:
return [[SQLServerStaff alloc] init];
break;
case DBTypeAccess:
return [[AccessStaff alloc] init];
break;
default:
return nil;
break;
}
}
+ (id <DepartmentProtocol>)createDepartmentDBWithDBType:(DBType)dbType {
switch (dbType) {
case DBTypeSQLServer:
return [[SQLServerDepartment alloc] init];
break;
case DBTypeAccess:
return [[AccessDepartment alloc] init];
break;
default:
return nil;
break;
}
}
@end
调用
//=============== 基础版本(Basic version) ===============
NSLog(@"=============== 基础版本(Basic version) ===============");
Staff *staff = [[Staff alloc] init];
staff.staffName = @"Gavin";
Department *department = [[Department alloc] init];
department.departmentName = @"研发";
// SQLServer
NSLog(@"--------------- SQLServer ---------------");
SQLServerFactory *sqlServerFactory = [[SQLServerFactory alloc] init];
[[sqlServerFactory createStaffDB] insertStaff:staff];
[[sqlServerFactory createDepartmentDB] insertDepartment:department];
// Access
NSLog(@"--------------- Access ---------------");
AccessFactory *accessFactory = [[AccessFactory alloc] init];
[[accessFactory createStaffDB] insertStaff:staff];
[[accessFactory createDepartmentDB] insertDepartment:department];
//=============== 优化版本(Optimized version) ===============
NSLog(@"=============== 优化版本(Optimized version) ===============");
// SQLServer
NSLog(@"--------------- SQLServer ---------------");
[[DBFactory createStaffDBWithDBType:DBTypeSQLServer] insertStaff:staff];
[[DBFactory createDepartmentDBWithDBType:DBTypeSQLServer] insertDepartment:department];
// Access
NSLog(@"--------------- Access ---------------");
[[DBFactory createStaffDBWithDBType:DBTypeAccess] insertStaff:staff];
[[DBFactory createDepartmentDBWithDBType:DBTypeAccess] insertDepartment:department];
执行结果:
执行结果源码
源码地址:FactoryPatternDemo
网友评论