这里介绍一下设计模式中的桥接模式在iOS中的实现。
一、由什么问题引出来的?
假设我们要做的事情是烧烤,烤鸡翅、烤羊肉串等有烤这个函数,辣味程度有微辣、特辣函数,这样烧烤这个事情就有2个独立维度的函数。
如何组织调用各个维度的函数,实现需要的烤肉出炉?
因为各个方法是独立的,所以我们需要建立桥接。
二、桥接模式是怎么做的?
- 烤鸡翅、烤羊肉串、烤牛肉串等类中都需要有make方法,因此这个方法需要作为基类方法----> 抽取基类。
- make方法需要用到辣味程度,因此基类中需要有辣味程度属性。
- 辣味程度的微辣、特辣都需要有辣味加工方法,因此需要抽取基类,基类有辣味加工方法。
- 在make方法中,让辣味程度属性调用辣味加工方法,即实现了功能。
- 所以桥接是什么?
答:通过抽取的这个辣味程度基类(也可以说是抽象类)作为烤肉的属性,然后在make中调用辣味程度类的加工方法,这样就相当于建立了一座桥(烤肉基类的子类能够与辣味程度基类的子类实现排列组合),在扩展一个新的辣味-中辣时,只需要建立一个中辣子类,将这个子类的对象作为属性,这样在调用make方法时,内部会调用中辣的加工方法,做出来的就是中辣的鸡翅! - 适用情况:2个维度或多个维度下,各个维度都可能会有变化的这么一种情况。
三、一个桥接模式例子
- 辛辣味的类
@objc(Spicy)
protocol Spicy {//辛辣味
func taste() -> String;
}
@objcMembers
class SlightSpicy: NSObject,Spicy {
func taste() -> String {
return "微辣";
}
}
@objcMembers
class ExtraSplicy: NSObject,Spicy {
func taste() -> String {
return "特辣";
}
}
2.烤肉类的情况
@objcMembers
class Barbecue : NSObject {
var mySpicy : Spicy?;
init(mySpicy : Spicy) {
self.mySpicy = mySpicy;
}
}
@objcMembers
class ChickenWing: Barbecue {
func eat() {
let string = self.mySpicy?.taste() ?? "味道桥接失败!";
print("吃鸡翅:\(string)");
}
}
@objcMembers
class MuttonShashlikWing: Barbecue {// 羊肉串
func eat() {
let string = self.mySpicy?.taste() ?? "味道桥接失败!";
print("吃羊肉串:\(string)");
}
}
- 具体使用,OC调用Swift
ExtraSplicy *extra = [[ExtraSplicy alloc] init];
MuttonShashlikWing *mutton = [[MuttonShashlikWing alloc] initWithMySpicy:extra];
[mutton eat];
网友评论