服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - IOS - 详解iOS应用开发中使用设计模式中的抽象工厂模式

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

2021-01-13 16:21Snow Liang IOS

这篇文章主要介绍了iOS应用开发中使用设计模式中的抽象工厂模式,示例代码为传统的Objective-C,需要的朋友可以参考下

概述

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

定义

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

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

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

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

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,这样,很明显是违背“开放-关闭原则”。这也是可以理解的,没有任何一个设计模式是完美没有瑕疵的,这就好比世界上没有打不败的武功一样。我们可以做的就是在实际的需求中,尽可能的将变化点进行隔离,以达到变化发生的时候,对整个系统的影响最小,变化所带来的变更和成本最低。

示例

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

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

好的,简单分析一下上面这张类结构图,这张图中有三个独立的模块儿,一个是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;
}


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

延伸 · 阅读

精彩推荐
  • IOS关于iOS自适应cell行高的那些事儿

    关于iOS自适应cell行高的那些事儿

    这篇文章主要给大家介绍了关于iOS自适应cell行高的那些事儿,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的...

    daisy6092021-05-17
  • IOSiOS布局渲染之UIView方法的调用时机详解

    iOS布局渲染之UIView方法的调用时机详解

    在你刚开始开发 iOS 应用时,最难避免或者是调试的就是和布局相关的问题,下面这篇文章主要给大家介绍了关于iOS布局渲染之UIView方法调用时机的相关资料...

    windtersharp7642021-05-04
  • IOSiOS 雷达效果实例详解

    iOS 雷达效果实例详解

    这篇文章主要介绍了iOS 雷达效果实例详解的相关资料,需要的朋友可以参考下...

    SimpleWorld11022021-01-28
  • IOSiOS中tableview 两级cell的展开与收回的示例代码

    iOS中tableview 两级cell的展开与收回的示例代码

    本篇文章主要介绍了iOS中tableview 两级cell的展开与收回的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    J_Kang3862021-04-22
  • IOSiOS通过逆向理解Block的内存模型

    iOS通过逆向理解Block的内存模型

    自从对 iOS 的逆向初窥门径后,我也经常通过它来分析一些比较大的应用,参考一下这些应用中某些功能的实现。这个探索的过程乐趣多多,不仅能满足自...

    Swiftyper12832021-03-03
  • IOS解析iOS开发中的FirstResponder第一响应对象

    解析iOS开发中的FirstResponder第一响应对象

    这篇文章主要介绍了解析iOS开发中的FirstResponder第一响应对象,包括View的FirstResponder的释放问题,需要的朋友可以参考下...

    一片枫叶4662020-12-25
  • IOSIOS开发之字典转字符串的实例详解

    IOS开发之字典转字符串的实例详解

    这篇文章主要介绍了IOS开发之字典转字符串的实例详解的相关资料,希望通过本文能帮助到大家,让大家掌握这样的方法,需要的朋友可以参考下...

    苦练内功5832021-04-01
  • IOSIOS 屏幕适配方案实现缩放window的示例代码

    IOS 屏幕适配方案实现缩放window的示例代码

    这篇文章主要介绍了IOS 屏幕适配方案实现缩放window的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要...

    xiari5772021-06-01