一、六大设计原则
- 单一职责原则:一个类只负责一件事
- 依赖倒置原则:抽象不该依赖于具体实现,具体实现可以依赖抽象
- 开闭原则:对修改关闭,对扩展开放
- 里氏替换原则:父类可以被子类无缝替换,且原有功能不受影响(例如:KVO)
- 接口隔离原则:使用多个专门的协议、而不是一个庞大臃肿的协议(例如:UITableViewDelegate,UITableViewDataSource)
- 迪米特法则:一个对象应当对其他对象尽可能少的了解(高内聚、高耦合)
关于设计原则可以看这篇文章面向对象设计的六大设计原则(附 Demo 及 UML 类图)
二、责任链模式
主要思想:对象引用了同一类型的另一个对象,形成一条链。链中的每个对象实现了相同的方法,处理对链中第一个对象发起的同一请求,如果一个对象不知道如何处理,就把请求传给下一个响应器。
代码示例:
@class BusinessObject;
typedef void(^CompletionBlock)(BOOL handled);
typedef void(^ResultBlock)(BusinessObject *handler, BOOL handled);
@interface BusinessObject : NSObject
// 下一个响应者(响应链构成的关键)
@property (nonatomic, strong) BusinessObject *nextBusiness;
// 响应者的处理方法
- (void)handle:(ResultBlock)result;
// 各个业务在该方法当中做实际业务处理
- (void)handleBusiness:(CompletionBlock)completion;
@end
@implementation BusinessObject
// 责任链入口方法
- (void)handle:(ResultBlock)result
{
CompletionBlock completion = ^(BOOL handled){
// 当前业务处理掉了,上抛结果
if (handled) {
result(self, handled);
}
else{
// 沿着责任链,指派给下一个业务处理
if (self.nextBusiness) {
[self.nextBusiness handle:result];
}
else{
// 没有业务处理, 上抛
result(nil, NO);
}
}
};
// 当前业务进行处理
[self handleBusiness:completion];
}
- (void)handleBusiness:(CompletionBlock)completion
{
/*
业务逻辑处理
如网络请求、本地照片查询等
*/
}
@end
三、桥接模式
桥接模式的目的是把抽象层次结构从其实现中分离出来,使其能够独立变更。
Class A 和Class B都是抽象类。ClassA中一个成员变量是ClassB的对象。ClassB中作为抽象类,只提供了默认的接口,并没有实现。B1、B2、B3是ClassB的三个子类,重写父类的接口方法,提供不同的实现,此时对于ClassB使用方来说,是感知到不使用了哪个实现。ClassA中有一个handle处理方法,默认调用成员变量ClassB对象中的接口方法。A1、A2、A3三个是ClassA的子类,对于子类来说可以覆写父类的handle方法,做一些自定义的操作。
代码示例:
ClassA
#import <Foundation/Foundation.h>
#import "BaseObjectB.h"
@interface BaseObjectA : NSObject
// 桥接模式的核心实现
@property (nonatomic, strong) BaseObjectB *objB;
// 获取数据
- (void)handle;
@end
#import "BaseObjectA.h"
@implementation BaseObjectA
/*
组合方式:
A1 --> B1、B2、B3 3种
A2 --> B1、B2、B3 3种
A3 --> B1、B2、B3 3种
*/
- (void)handle
{
// override to subclass
// 处理objB中的方法。
[self.objB fetchData];
}
@end
ClassA的子类A1、A2、A3重写父类中handle方法。
#import "ObjectA1.h"
@implementation ObjectA1
- (void)handle
{
// before 业务逻辑操作
[super handle];
// after 业务逻辑操作
}
@end
ClassB 实现
#import <Foundation/Foundation.h>
@interface BaseObjectB : NSObject
- (void)fetchData;
@end
#import "BaseObjectB.h"
@implementation BaseObjectB
// 默认逻辑实现
- (void)fetchData
{
// override to subclass
}
@end
ClassB的子类进行具体的逻辑实现。
#import "ObjectB1.h"
@implementation ObjectB1
- (void)fetchData{
// 具体的逻辑处理
}
@end
使用方代码实现
@interface BridgeDemo()
@property (nonatomic, strong) BaseObjectA *objA;
@end
@implementation BridgeDemo
/*
根据实际业务判断使用那套具体数据
A1 --> B1、B2、B3 3种
A2 --> B1、B2、B3 3种
A3 --> B1、B2、B3 3种
*/
- (void)fetch
{
// 创建一个具体的ClassA
_objA = [[ObjectA1 alloc] init];
// 创建一个具体的ClassB
BaseObjectB *b1 = [[ObjectB1 alloc] init];
// 将一个具体的ClassB1 指定给抽象的ClassB
_objA.objB = b1;
// 获取数据
[_objA handle];
}
@end
使用方中定义了ClassA对象,可以使用A1、A2、A3来创建不同的对象,获取不同的实现组合。BaseObjectB也可以有不同的实现组合。通过桥接模式不同的组合可以实现对象之间的解耦。
桥接模式的优点:
-
分离抽象接口及其实现部分。
-
桥接模式有时类似于多继承方案,但是多继承方案违背了类的单一职责原则(即一个类只有一个变化的原因),复用性比较差,而且多继承结构中类的个数非常庞大,桥接模式是比多继承方案更好的解决方法。
-
桥接模式提高了系统的可扩充性,在两个变化维度中任意扩展一个维度,都不需要修改原有系统。
-
实现细节对客户透明,可以对用户隐藏实现细节。
-
参考:
桥接模式
网友评论