当前位置: 首页 > 编程笔记 >

详解iOS应用开发中使用设计模式中的抽象工厂模式

狄阳华
2023-03-14
本文向大家介绍详解iOS应用开发中使用设计模式中的抽象工厂模式,包括了详解iOS应用开发中使用设计模式中的抽象工厂模式的使用技巧和注意事项,需要的朋友参考一下

概述

  我们知道简单工厂模式的优点是去除了客户端与具体产品的依赖,缺点是违反了“开放-关闭原则”;工厂方法模式克服了简单工厂模式的缺点,将产品的创建工作放到具体的工厂类,每个工厂类负责生成一个产品。但是在实际应用中,一个工厂类只创建单个产品的情况很少,一般一个工厂类会负责创建一系列相关的产品,如果我们要设计这样的系统,工厂方法模式显然不能满足应用的需求,本章要介绍的抽象工厂模式,可以很好地解决一系列产品创建的问题。

定义

  “提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。”

最初的定义出现于《设计模式》(Addison-Wesley,1994)。
结构图

 先对上面结构图的几个角色进行说明:

AbstractFactory:抽象工厂接口,里面应该包含所有产品创建的抽象方法;
ConcreteFactory1和ConcreteFactory2:具体的工厂,创建具有特定实现的产品对象;
AbstractProductA和AbstractProductB:抽象产品,它们可能有多种不同的实现方式;
ProductA1、ProductA2、ProductB1和ProductB2:具体的产品,是抽象产品的具体实现。
  从结构图中可以看到,抽象工厂方法最大的好处是能够很方便的变换产品系列(例如id<AbstractFactory> factory =[ [ConcreteFactory1 alloc] init],只需要将ConcreteFactory1换成ConcreteFactory2,就可以创建ProductA2和ProductB2)。另外,抽象工厂方法让具体的创建实例过程与客户端分离,客户端是通过它们的抽象接口操作实例,产品的具体类名也被具体工厂的实现分离,不会出现在客户代码中(例如id<AbstractProductA> product = [factory createProductA],客户端根本不知道具体的类名是ProductA1还是ProductA2)。

  但是,抽象工厂方法也是存在缺点的,比如说现在我们要增加一个新的产品,首先,我们需要增加三个类:AbstractProductC、ProductC1、ProductC2;另外,我们还需要更改三个类:AbstractFactory、ConcreteFactory1、ConcreteFactory2,这样,很明显是违背“开放-关闭原则”。这也是可以理解的,没有任何一个设计模式是完美没有瑕疵的,这就好比世界上没有打不败的武功一样。我们可以做的就是在实际的需求中,尽可能的将变化点进行隔离,以达到变化发生的时候,对整个系统的影响最小,变化所带来的变更和成本最低。

示例

先给大家看一下数据库访问的类结构图吧。

好的,简单分析一下上面这张类结构图,这张图中有三个独立的模块儿,一个是IFactory接口,以不同数据库为划分原则对部门进行抽象,一个是对访问数据库的不同部门,还有一个是对数据库操作的人员进行了抽象。类图中没有提到接下来需要给大家展示的两个类,一个是User类,一个是Department类,因为这两个类是对数据库数据的封装,和结构并没有直接关系,所以没有显示出来,在此说明一下,以免大家引起混乱。其实,静下心来细细的看,结构还是蛮清晰的。

呵呵,下面还是老样子,给大家展示一下代码。

注意:本文所有代码均在ARC环境下编译通过。

User类接口


#import <Foundation/Foundation.h>

@interface User :NSObject @property int *ID; @property NSString *Name; @end


User类实现

#import "User.h"

@implementation User @synthesize Name =_Name; @synthesize ID =_ID; @end


Department类接口

#import <Foundation/Foundation.h>

@interface Department:NSObject @property int *ID; @property NSString *DeptName; @end


Department类实现

#import "Department.h"

@implementation Department @synthesize ID =_ID; @synthesize DeptName =_DeptName; @end


IDepartment类接口

#import <Foundation/Foundation.h> 

@class Department; @interface IDepartment :NSObject -(void)Insert:(Department*)department; -(Department*)GetDepartment:(int)myId; @end


IDepartment类实现

#import "IDepartment.h"

#import "Department.h"

@implementation IDepartment -(void)Insert:(Department *)department{     return; } -(Department*)GetDepartment:(int)myId{     return nil; } @end


SqlserverDepartment类接口

#import "IDepartment.h"

@interface SqlserverDepartment:IDepartment @end


SqlserverDepartment类实现

#import "SqlserverDepartment.h"

@implementation SqlserverDepartment -(void)Insert:(Department *)department{     NSLog(@"在SQL Server中给Department表增加一条记录"); } -(Department*)GetDepartment:(int)myId{     NSLog(@"在SQL Server中根据ID得到Department表一条记录");     return nil; } @end


AccessDepartment类接口

#import "IDepartment.h"

@interface AccessDepartment:IDepartment @end


*AccessDepartment类实现

#import "AccessDepartment.h"

@implementation AccessDepartment -(void)Insert:(Department *)department{     NSLog(@"在Access中给Department表增加一条记录"); } -(Department*)GetDepartment:(int)myId{     NSLog(@"在Access中根据myId得到Department表一条记录");     return nil; } @end


IUser类接口

#import <Foundation/Foundation.h>

@class User; @interfaceIUser :NSObject -(void)Insert:(User*)user; -(User*)GetUser:(int)myID; @end


IUser类实现

#import "IUser.h"

#import "User.h"

@implementation IUser -(void)Insert:(User *)user{     return; } -(User*)GetUser:(int)myID{     return nil; } @end


SqlServerUser类接口

#import "IUser.h"

@interface SqlServerUser :IUser @end SqlServerUser类实现

#import "SqlServerUser.h"

@implementation SqlServerUser -(void)Insert:(User *)user{     NSLog(@"在SQL Server中给User表增加一条记录"); } -(User*)GetUser:(int)myID{     NSLog(@"在SQL Server中根据myID得到User表一条记录");     return nil; } @end


AccessUser类接口

#import "IUser.h"

@interface AccessUser :IUser @end


AccessUser类实现

#import "AccessUser.h"

@implementation AccessUser -(void)Insert:(User *)user{     NSLog(@"在Access中给User表增加一条记录"); } -(User*)GetUser:(int)myID{     NSLog(@"在Access中根据myID得到User表一条记录");     return nil; } @end


IFactories类接口

#import "AccessUser.h"

@implementation AccessUser -(void)Insert:(User *)user{     NSLog(@"在Access中给User表增加一条记录"); } -(User*)GetUser:(int)myID{     NSLog(@"在Access中根据myID得到User表一条记录");     return nil; } @end


IFactories类实现

#import "IFactories.h"

#import "IUser.h"

#import "IDepartment.h"

@implementation IFactories -(IUser*)CreateUser{     return nil; } -(IDepartment*)CreateDepartment{     return nil; } @end


AccessFactory类接口

#import "IFactories.h"

@interface AccessFactory :IFactories @end


AccessFactory类实现

#import "AccessFactory.h"

#import "AccessUser.h"

#import "AccessDepartment.h"

@implementation AccessFactory -(IUser*)CreateUser{     return [[AccessUser alloc]init]; } -(IDepartment*)CreateDepartment{     return [[AccessDepartment alloc]init]; } @end


SqlServerFactory类接口

#import "IFactories.h"

@interface SqlServerFactory :IFactories @end


SqlServerFactory类实现

#import "SqlServerFactory.h"

#import "SqlServerUser.h"

#import "SqlserverDepartment.h"

@implementation SqlServerFactory -(IUser*)CreateUser{     return [[SqlServerUser alloc]init]; } -(IDepartment*)CreateDepartment{     return [[SqlserverDepartment alloc]init]; } @end


Main方法调用

#import <Foundation/Foundation.h>

#import "User.h"

#import "Department.h"

#import "IFactories.h"

#import "AccessFactory.h"

#import "IUser.h"

#import "IDepartment.h"

int main (int argc,const char * argv[]) {     @autoreleasepool{         User *user = [[User alloc]init];         Department *dept = [[Department alloc]init];         IFactories *factories = [[AccessFactory alloc]init];         IUser *iu = [factories CreateUser];         [iu Insert:user];         [iu GetUser:1];

        IDepartment *myId = [factories CreateDepartment];         [myId Insert:dept];         [myId GetDepartment:1];     }     return 0; }


上面罗列了一堆代码,其实,罗列这些代码的目的只有一个,就是为了帮助像我一样基础不太好的同学尽快入门,有一个感性的认识,迈过第一道门槛。

 类似资料:
  • 本文向大家介绍PHP实现设计模式中的抽象工厂模式详解,包括了PHP实现设计模式中的抽象工厂模式详解的使用技巧和注意事项,需要的朋友参考一下 抽象工厂模式(Abstact Factory)是一种常见的软件设计模式。该模式为一个产品族提供了统一的创建接口。当需要这个产品族的某一系列的时候,可以为此系列的产品族创建一个 具体的工厂类。 【意图】 抽象工厂模式提供一个创建一系统相关或相互依赖对象的接口,而

  • 我正在努力学习创造性设计模式,我想我现在理解了工厂方法模式。但在转向抽象工厂模式时,我找不到它的用途。我知道我错过了一些东西,但不知道在哪里。 在抽象工厂模式中,我们将有一个抽象工厂,混凝土工厂将返回实例。假设我们正在处理汽车的创建。我们将有一个像这样的抽象工厂 我们的混凝土工厂将是 在用户类中,我们将像 我认为我们也可以使用工厂模式构建相同的功能 在用户类中,我们可以 如果我的理解是正确的(如果

  • 4. 抽象工厂(Abstract Factory) Intent 提供一个接口,用于创建 相关的对象家族 。 Class Diagram 抽象工厂模式创建的是对象家族,也就是很多对象而不是一个对象,并且这些对象是相关的,也就是说必须一起创建出来。而工厂方法模式只是用于创建一个对象,这和抽象工厂模式有很大不同。 抽象工厂模式用到了工厂方法模式来创建单一对象,AbstractFactory 中的 cr

  • 本文向大家介绍C++设计模式之抽象工厂模式,包括了C++设计模式之抽象工厂模式的使用技巧和注意事项,需要的朋友参考一下 问题描述 之前讲到了C++设计模式——工厂方法模式,我们可能会想到,后期产品会越来越多了,建立的工厂也会越来越多,工厂进行了增长,工厂变的凌乱而难于管理;由于工厂方法模式创建的对象都是继承于Product的,所以工厂方法模式中,每个工厂只能创建单一种类的产品,当需要生产一种全新的

  • 本文向大家介绍Java设计模式编程中的工厂方法模式和抽象工厂模式,包括了Java设计模式编程中的工厂方法模式和抽象工厂模式的使用技巧和注意事项,需要的朋友参考一下 工厂方法模式 动机 创建一个对象往往需要复杂的过程,所以不适合包含在一个复合工厂中,当有新的产品时,需要修改这个复合的工厂,不利于扩展。 而且,有些对象的创建可以需要用到复合工厂访问不到的信息,所以,定义一个工厂接口,通过实现这个接口来

  • 本文向大家介绍详解JavaScript设计模式开发中的桥接模式使用,包括了详解JavaScript设计模式开发中的桥接模式使用的使用技巧和注意事项,需要的朋友参考一下 桥接模式将抽象部分与实现部分分离开来,使两者都可以独立的变化,并且可以一起和谐地工作。抽象部分和实现部分都可以独立的变化而不会互相影响,降低了代码的耦合性,提高了代码的扩展性。 按照GoF的定义,桥接模式的作用在于“将抽象与其实现隔

  • 本文向大家介绍PHP设计模式之工厂模式详解,包括了PHP设计模式之工厂模式详解的使用技巧和注意事项,需要的朋友参考一下 在开发大型系统时,往往会出现这样一种情况: 我有一部分基础数据,是类classA是从数据库A读取出来的,其他很多的功能都是基于这个基础数据来操作的。现在呢,我想把数据从数据库A变成从另外的数据源去获取,这时候,要修改起来就比较麻烦,要修改其他很多类的代码。这种设计显然是不够灵活的

  • 本文向大家介绍JavaScript设计模式之抽象工厂模式介绍,包括了JavaScript设计模式之抽象工厂模式介绍的使用技巧和注意事项,需要的朋友参考一下 抽象工厂模式说明 1. 工厂方法模式的问题: 在工厂方法模式里,创建类都需要通过 工厂类,如果要扩展程序,就必须修改工厂类,这违背了闭包原则,对扩展开放,对修改关闭;对于设计有一定的问题。 2. 如何解决:就要用到抽象工厂模式,就是对功能类单独