iOS——工厂模式

什么是设计模式

所谓设计模式(Design pattern) 是解决软件开发某些特定问题而提出的一些解决方案也可以理解成解决问题的一些思路。通过设计模式可以帮助我们增强代码的可重用性、可扩充性、 可维护性、灵活性好。我们使用设计模式最终的目的是实现代码的 高内聚 和 低耦合。可以这么说,计算机中设计模式指的是一套广为人知、被反复使用、经过分类编目的代码设计经验。使用设计模式是为了可重用代码,让代码更容易被他人理解,最重要的是保证代码可靠性。

设计模式七大准则

开闭原则

开闭原则的核心是:对扩展开放,对修改关闭。在程序需要进⾏拓展的时候,不能去修改原有的代码,⽽是要扩展原有代码,实现⼀个热插拔的效果。所以⼀句话概括就是:为了使程序的扩展性好,易于维护和升级。想要达到这样的效果,我们需要使⽤接⼝和抽象类等,大部分具体设计模式中反复应用这一原则。

单⼀职责原则

一个类只做一件事。每个类应该实现单⼀的职责,如若不然,就应该把类拆分。
比如:UIView负责事件的传递、响应,CALayer负责视图的显示、动画,他们各自都有自己的单一职责。

里氏替换原则

里氏替换原则的主要内容:任何基类可以出现的地方,子类⼀定可以出现。该原则是继承复⽤的基⽯,只有当衍⽣类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为。原则上,⼦类对父类的方法尽量不要重写和重载,因为⽗类代表了定义好的结构,通过这个规范的接⼝与外界交互。除非万不得已,⼦类不应该随便破坏它。

依赖倒转原则

面向接口编程,依赖于抽象而不依赖于具体。高层模块不应该依赖底层模块,二者都应该依赖其抽象;我们可以依赖抽象类也可以依赖接口,但是不要依赖具体的子类或者实现类。依赖倒转原则是开闭原则的基础。

接口隔离原则

每个接口中不存在子类用不到却必须实现的方法,如果不然,就要将接口拆分。使⽤多个隔离的接口,⽐使用单个接口(多个接口⽅法集合到⼀个的接口)要好。

迪米特法则

迪米特法则的核心为:⼀个类对自己依赖的类知道的越少越好。也就是说⽆论被依赖的类多么复杂,都应该将逻辑封装在⽅法的内部,通过public方法提供给外部。这样当被依赖的类变化时,才能最小的影响该类。
最少知道原则的另⼀个表达⽅式是:只与直接的朋友通信。类之间只要有耦合关系,就叫朋友关系。耦合分为依赖、关联、聚合、组合等。我们称出现成员变量、⽅法参数、⽅法返回值中的类为直接朋友。局部变量、临时变量则不是直接的朋友。我们要求陌生的类不要作为局部变量出现在类中。

合成复用原则

合成复用原则是尽量⾸先使用合成/聚合的⽅式,而不是使用继承。此原则和里氏替换原则氏相辅相成的,两者都是详细实现"开-闭"原则的规范。我们先看什么是合成和聚合:
合成
合成是指一个总体对依托他而存在的关系,如一个人对他的房子和家具。该关系依赖性不强,比如人没了,这个关系就自然消失了。
聚合
聚合是比合成关系更强的一种依赖关系,如有一台汽车,汽车对引擎、轮胎的关系就是聚合关系。这些关系就是带有聚合性质的。车没了,该车的引擎和轮胎自然也没了。在我们的设计中,这种关系不应该频繁出现,因为这样会增大设计的耦合度。

明确了合成和聚合关系,再来理解合成复用原则应该就清楚了:我们要尽量找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。

工厂模式

工厂模式是一种常见的设计模式,在Objective-C中也常常被使用。它可以将对象的创建和使用分离,使得同一接口下的不同实现可以在不修改客户端代码的情况下被替换。

工厂模式主要分为三种类型:

  1. 简单工厂模式(Simple Factory Pattern):也被称为静态工厂方法模式,它定义一个具体的工厂类负责创建一些类的实例。这个工厂类基于给定的信息生成对应的实例。简单工厂模式适合需求相对稳定的情况。
  2. 工厂方法模式(Factory Method Pattern):在工厂方法模式中,我们不再由一个单一的工厂类来创建所有的对象,而是具体的对象由相应的具体工厂来创建。工厂方法模式是一种典型的面向对象设计模式,强调了面向对象设计的原则:对象通过接口进行交互,具备扩展性,符合开闭原则。
  3. 抽象工厂模式(Abstract Factory Pattern):抽象工厂模式提供了一个创建一系列相关或互相依赖对象的接口,而无需指定它们具体的类。这个设计模式是为了应对产品族概念的,比如每个汽车公司可能要同时生产轿车,货车,客车,那么每个公司就可能要有一系列的汽车生产线,而不同的汽车生产线决定了实际产出的汽车型号。

简单工厂模式

在这里插入图片描述

简单工厂模式包括以下几个部分:

  1. 抽象产品:定义产品的接口,描述产品的主要特性和功能。
  2. 具体产品:实现抽象产品中定义的接口,由工厂方法生成,对应具体的产品实例。
  3. 工厂:用来创建产品的实例。根据输入的参数,决定创建哪种产品的实例。

例:

// 抽象产品
@protocol Fruit <NSObject>
- (void)show;
@end

// 具体产品
@interface Apple : NSObject <Fruit>
@end

@implementation Apple
- (void)show {
    NSLog(@"I'm an apple");
}
@end

@interface Banana : NSObject <Fruit>
@end

@implementation Banana
- (void)show {
    NSLog(@"I'm a banana");
}
@end

// 工厂
@interface FruitFactory : NSObject
+ (id<Fruit>)fruitWithType:(NSString *)type;
@end

@implementation FruitFactory
+ (id<Fruit>)fruitWithType:(NSString *)type {
    if ([type isEqualToString:@"apple"]) {
        return [Apple new];
    } else if ([type isEqualToString:@"banana"]) {
        return [Banana new];
    } else {
        return nil;
    }
}
@end

在这个例子中,Fruit 协议就是抽象产品,AppleBanana 就是具体产品,FruitFactory 就是工厂。客户端代码可以使用 FruitFactory 来创建产品实例,而不需要关心具体的产品类型。

优点

  • 将对象的创建和对象本身业务处理分离可以降低系统的耦合度,使得两者修改起来都相对容易。
  • 当你需要什么,只需要传入一个正确的参数,就可以获取你所需要的对象,而无须知道其创建细节。
  • 在调用工厂类的工厂方法时,由于工厂方法是静态方法,使用起来很方便,可通过类名直接调用,而且只需要传入一个简单的参数即可,修改参数时无须修改任何源代码

缺点

  • 简单工厂模式最大的问题在于工厂类的职责相对过重,增加新的产品需要修改工厂类的判断逻辑,这一点与开闭原则是相违背的。

工厂方法模式

在这里插入图片描述

工厂方法模式是一种设计模式,通过定义工厂父类负责定义创建对象的公共接口,而子类则负责生成具体的对象。这种设计模式主要包括以下几个部分:

  • 抽象工厂:定义创建对象的公共接口
  • 具体工厂:实现抽象工厂的创建方法,负责生成具体的对象
  • 抽象产品:定义产品的公共接口
  • 具体产品:实现抽象产品的接口,由具体工厂来创建

工厂方法模式的关键在于,客户端不直接创建对象,而是调用工厂的方法来创建。这样做的好处是,客户端不需要知道具体的产品类,只需要知道所使用的工厂即可,从而达到降低耦合度,提高代码的可扩展性和可维护性的目的。
工厂方法模式的核心在于将实例化对象推迟到子类中进行,这样就可以在不修改原来代码的情况下,方便地添加新的子类进来。

例:首先,我们需要定义一个抽象的产品协议(Protocol):

@protocol Fruit <NSObject>
- (void)show;
@end

然后,我们创建两个具体的产品类(Class),比如Apple和Banana,它们都遵循Fruit协议:

@interface Apple : NSObject <Fruit>
@end

@implementation Apple
- (void)show {
    NSLog(@"I'm an apple");
}
@end

@interface Banana : NSObject <Fruit>
@end

@implementation Banana
- (void)show {
    NSLog(@"I'm a banana");
}
@end

接着,我们创建一个工厂的抽象类:

@interface FruitFactory : NSObject
- (id<Fruit>)createFruit;
@end

然后我们创建两个具体的工厂类,AppleFactory和BananaFactory,它们都继承自FruitFactory:

@interface AppleFactory : FruitFactory
@end

@implementation AppleFactory
- (id<Fruit>)createFruit {
    return [[Apple alloc] init];
}
@end

@interface BananaFactory : FruitFactory
@end

@implementation BananaFactory
- (id<Fruit>)createFruit {
    return [[Banana alloc] init];
}
@end

最后,在客户端代码中,我们可以使用工厂类来创建产品的实例,而不需要直接创建产品:

FruitFactory *factory = [[AppleFactory alloc] init];
id<Fruit> apple = [factory createFruit];
[apple show];

factory = [[BananaFactory alloc] init];
id<Fruit> banana = [factory createFruit];
[banana show];

在这个例子中,FruitFactory是抽象工厂,AppleFactory和BananaFactory是具体工厂,Fruit是抽象产品,Apple和Banana是具体产品。客户端代码只需要知道具体工厂,就可以创建相应的产品。这就是工厂方法模式的核心思想。
在这里插入图片描述

抽象工厂模式

在这里插入图片描述
在这里插入图片描述

工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个抽象产品类。抽象工厂模式里每个工厂都会生产多种产品,但不同工厂生产的产品属于不同的系列。抽象工厂模式可以用来解决多产品族的问题。

缺点

  • 增加新的产品种类困难,它需要修改抽象工厂的接口。
  • 代码结构比较复杂。

主要作用:

  • 类想让其子类决定在运行时创建什么,无法在编译时准确确定
  • 类有若干个辅助类为其子类,而你想将返回某个子类这一信息局部化

例: 首先,定义一个抽象的产品接口,例如,定义一个Drink接口:

@protocol Drink <NSObject>
- (void)drink;
@end

然后,创建两个具体的产品类,比如Cola和Coffee,它们都实现了Drink接口:

@interface Cola : NSObject <Drink>
@end

@implementation Cola
- (void)drink {
    NSLog(@"Drinking Cola");
}
@end

@interface Coffee : NSObject <Drink>
@end

@implementation Coffee
- (void)drink {
    NSLog(@"Drinking Coffee");
}
@end

接着,创建一个抽象的工厂接口,例如,定义一个DrinkFactory接口:

@protocol DrinkFactory <NSObject>
- (id<Drink>)createDrink;
@end

然后,创建两个具体的工厂类,比如ColaFactory和CoffeeFactory,它们都实现了DrinkFactory接口:

@interface ColaFactory : NSObject <DrinkFactory>
@end

@implementation ColaFactory
- (id<Drink>)createDrink {
    return [[Cola alloc] init];
}
@end

@interface CoffeeFactory : NSObject <DrinkFactory>
@end

@implementation CoffeeFactory
- (id<Drink>)createDrink {
    return [[Coffee alloc] init];
}
@end

最后,在客户端代码中,我们可以使用工厂类来创建产品的实例,而不需要直接创建产品:

id<DrinkFactory> factory = [[ColaFactory alloc] init];
id<Drink> cola = [factory createDrink];
[cola drink];

factory = [[CoffeeFactory alloc] init];
id<Drink> coffee = [factory createDrink];
[coffee drink];

我们通过工厂方法创建了Cola和Coffee对象,而不需要直接创建这两个对象。这样就可以在不修改客户端代码的情况下添加新的产品,比如添加一个新的产品Tea,只需要创建一个Tea类和一个TeaFactory类即可。

  • 20
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值