【iOS-設(shè)計(jì)模式】創(chuàng)建型之抽象工廠模式

概念

抽象工廠提供一個(gè)固定的接口,用于創(chuàng)建一系列有關(guān)聯(lián)或相依存的對(duì)象,而不必指定其具體類或其創(chuàng)建的細(xì)節(jié)??蛻舳伺c從工廠得到的具體對(duì)象之間沒有耦合。

實(shí)例

我們以一個(gè)員工與部門的例子來實(shí)現(xiàn),首先我們創(chuàng)建員工和部門的數(shù)據(jù)模型,并各聲明一個(gè)名稱的屬性:

~/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

然后分別創(chuàng)建員工協(xié)議和部門協(xié)議,分別用于插入到數(shù)據(jù)庫(kù)中加入員工和加入部門:

~/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

然后分別創(chuàng)建基于各自協(xié)議的 SQLServer數(shù)據(jù)庫(kù)數(shù)據(jù)處理類,實(shí)現(xiàn)協(xié)議 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

同樣方式創(chuàng)建 Access 數(shù)據(jù)庫(kù)的相應(yīng)數(shù)據(jù)處理類。

工廠實(shí)現(xiàn)

創(chuàng)建數(shù)據(jù)庫(kù)的工廠協(xié)議 DBFactoryProtocol,聲明兩個(gè)創(chuàng)建數(shù)據(jù)庫(kù)的協(xié)議方法:

~/Basic version/DBFactoryProtocol.h

#import "StaffProtocol.h"
#import "DepartmentProtocol.h"

@protocol DBFactoryProtocol <NSObject>

- (id <StaffProtocol>)createStaffDB;

- (id <DepartmentProtocol>)createDepartmentDB;

@end

創(chuàng)建 SQLServer 的工廠類 SQLServerFactory 實(shí)現(xiàn)協(xié)議方法:

#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

在創(chuàng)建相應(yīng)數(shù)據(jù)庫(kù),產(chǎn)出相應(yīng)遵循相應(yīng)協(xié)議的數(shù)據(jù)處理類。

同樣的方式實(shí)現(xiàn) Access 數(shù)據(jù)庫(kù)工廠類。

實(shí)際上這里寫的有點(diǎn)不好,不應(yīng)該用協(xié)議,使用繼承會(huì)更為合理。使用繼承就不會(huì)產(chǎn)生方法的連續(xù)調(diào)用。

于是實(shí)現(xiàn)了以下優(yōu)化版本:

~/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

調(diào)用

//=============== 基礎(chǔ)版本(Basic version) ===============
    NSLog(@"=============== 基礎(chǔ)版本(Basic version) ===============");
    Staff *staff = [[Staff alloc] init];
    staff.staffName = @"Gavin";
    Department *department = [[Department alloc] init];
    department.departmentName = @"研發(fā)";
    
    //  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];
    
    //=============== 優(yōu)化版本(Optimized version) ===============
    NSLog(@"=============== 優(yōu)化版本(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];

執(zhí)行結(jié)果:

執(zhí)行結(jié)果

源碼

源碼地址:FactoryPatternDemo

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容