继上一篇的面向对象设计的设计原则,本篇是面向对象设计系列的第二个部分:面向对象设计的设计模式。
介绍设计模式最著名的一本书莫属《设计模式 可复用面向对象软件的基础》这本书,书中共介绍了23个设计模式。而这些设计模式分为三大类,每个类别都包含几个设计模式:
本系列对设计模式的讲解按照上面分类排列的顺序进行。而且从多维度来理解一件事物有助于更深刻地理解它,因此每个设计模式我都会从以下这几点来讲解:
最后一项:“iOS SDK 和 JDK中的应用”讲解的是该设计模式在Objective-C和java语言(JDK)中的应用。
本篇是面向对象设计中面向对象设计的第一篇文章,讲解的是简单工厂模式。
注意:简单工厂模式不是 GoF总结出来的23种设计模式之一,不存在于《设计模式 可复用面向对象软件的基础》这本书中。
简单工厂模式(Simple Factory Pattern):专门定义一个类(工厂类)来负责创建其他类的实例。可以根据创建方法的参数来返回不同类的实例,被创建的实例通常都具有共同的父类。
简单工厂模式又称为静态工厂方法(Static Factory Method)模式,它属于类创建型模式。
如果我们希望将一些为数不多的类似的对象的创建和他们的创建细节分离开,也不需要知道对象的具体类型,可以使用简单工厂模式。
举个形象点的例子:在前端开发中,常常会使用外观各式各样的按钮:比如有的按钮有圆角,有的按钮有阴影,有的按钮有边框,有的按钮无边框等等。但是因为同一种样式的按钮可以出现在项目的很多地方,所以如果在每个地方都把创建按钮的逻辑写一遍的话显然是会造成代码的重复(而且由于业务的原因有的按钮的创建逻辑能比较复杂,代码量大)。
那么为了避免重复代码的产生,我们可以将这些创建按钮的逻辑都放在一个“工厂”里面,让这个工厂来根据你的需求(传入的参数)来创建对应的按钮并返回给你。这样一来,同样类型的按钮在多个地方使用的时候,就可以只给这个工厂传入其对应的参数并拿到返回的按钮即可。
下面来看一下简单工厂模式的成员和类图。
简单工厂模式的结构比较简单,一共只有三个成员:
下面通过类图来看一下各个成员之间的关系:
简单工厂模式类图
从类图中可以看出,工厂类提供一个静态方法:通过传入的字符串来制造其所对应的产品。
举一个店铺售卖不同品牌手机的例子:店铺,即客户端类向手机工厂购进手机售卖。
该场景可以使用简单工厂的角色来设计:
Phone
,是所有具体产品类的父类,提供一个公共接口packaging
表示手机的装箱并送到店铺。IPhone
),小米手机类(MIPhone
),华为手机类(HWPhone
)。PhoneFactory
根据不同的参数来创建不同的手机。Store
负责售卖手机。抽象产品类Phone
:
//================== Phone.h ==================
@interface Phone : NSObject
//package to store
- (void)packaging;
@end
具体产品类 IPhone
:
//================== IPhone.h ==================
@interface IPhone : Phone
@end
//================== IPhone.m ==================
@implementation IPhone
- (void)packaging{
NSLog(@"IPhone has been packaged");
}
@end
具体产品类 MIPhone
:
//================== MIPhone.h ==================
@interface MIPhone : Phone
@end
//================== MIPhone.m ==================
@implementation MIPhone
- (void)packaging{
NSLog(@"MIPhone has been packaged");
}
@end
具体产品类:HWPhone
:
//================== HWPhone.h ==================
@interface HWPhone : Phone
@end
//================== HWPhone.m ==================
@implementation HWPhone
- (void)packaging{
NSLog(@"HUAWEI Phone has been packaged");
}
@end
以上是抽象产品类以及它的三个子类:苹果手机类,小米手机类和华为手机类。
下面看一下工厂类 PhoneFactory
:
//================== PhoneFactory.h ==================
@interface PhoneFactory : NSObject
+ (Phone *)createPhoneWithTag:(NSString *)tag;
@end
//================== PhoneFactory.m ==================
#import "IPhone.h"
#import "MIPhone.h"
#import "HWPhone.h"
@implementation PhoneFactory
+ (Phone *)createPhoneWithTag:(NSString *)tag{
if ([tag isEqualToString:@"i"]) {
IPhone *iphone = [[IPhone alloc] init];
return iphone;
}else if ([tag isEqualToString:@"MI"]){
MIPhone *miPhone = [[MIPhone alloc] init];
return miPhone;
}else if ([tag isEqualToString:@"HW"]){
HWPhone *hwPhone = [[HWPhone alloc] init];
return hwPhone;
}else{
return nil;
}
}
@end
工厂类向外部(客户端)提供了一个创造手机的接口
createPhoneWithTag:
,根据传入参数的不同可以返回不同的具体产品类。因此客户端只需要知道它所需要的产品所对应的参数即可获得对应的产品了。
在本例中,我们声明了店铺类 Store
为客户端类:
//================== Store.h ==================
#import "Phone.h"
@interface Store : NSObject
- (void)sellPhone:(Phone *)phone;
@end
//================== Store.m ==================
@implementation Store
- (void)sellPhone:(Phone *)phone{
NSLog(@"Store begins to sell phone:%@",[phone class]);
}
@end
客户端类声明了一个售卖手机的接口
sellPhone:
。表示它可以售卖作为参数所传入的手机。
最后我们用代码模拟一下这个实际场景:
//================== Using by client ==================
//1. A phone store wants to sell iPhone
Store *phoneStore = [[Store alloc] init];
//2. create phone
Phone *iPhone = [PhoneFactory createPhoneWithTag:@"i"];
//3. package phone to store
[iphone packaging];
//4. store sells phone after receving it
[phoneStore sellPhone:iphone];
上面代码的解读:
i
。在这里我们需要注意的是:商店从工厂拿到手机不需要了解手机制作的过程,只需要知道它要工厂做的是手机(只知道Phone
类即可),和需要给工厂类传入它所需手机所对应的参数即可(这里的iPhone手机对应的参数就是i
)。
下面我们看一下该例子对应的 UML类图,可以更直观地看一下各个成员之间的关系:
简单工厂模式代码示例类图
NSNumber
的工厂方法传入不同类型的数据,则会返回不同数据所对应的NSNumber
的子类。Calendar
类中的私有的createCalendar(TimeZone zone, Locale aLocale)
方法通过不同的入参来返回不同类型的Calendar子类的实例。扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有