摘自:https://juejin.cn/post/7222642085405229114
设计模式分类
创建型模式
结构型模式
行为型模式(太恶心了,巨复杂没写完)
1.创建型模式
创建型模式:提供了一种创建对象的最佳方式。这些模式涉及到如何实例化对象,并且隐藏了实例化的细节
工厂模式(Factory Pattern)
抽象工厂模式(Abstract Factory Pattern)
建造者模式(Builder Pattern)
原型模式(Prototype Pattern)
单例模式(Singleton Pattern)
1.1工厂模式:
在这种模式中,一个类用于创建另一个类的实例。这种模式适用于在不知道具体实现细节的情况下创建对象的场景。
需要创建一个产品接口,它定义了所有具体产品必须实现的方法:
@protocol ProductProtocol
- (void)operation;
@end
创建两个具体产品类,它们实现了产品接口:
@interface ProductA : NSObject<ProductProtocol>
@end
@implementation ProductA
- (void)operation {
NSLog(@"ProductA operation");
}
@end
@interface ProductB : NSObject<ProductProtocol>
@end
@implementation ProductB
- (void)operation {
NSLog(@"ProductB operation");
}
@end
创建一个工厂类,它用于创建产品实例:
@interface ProductFactory : NSObject
+ (id<ProductProtocol>)createProductWithType:(NSString *)type;
@end
@implementation ProductFactory
+ (id<ProductProtocol>)createProductWithType:(NSString *)type {
if ([type isEqualToString:@"ProductA"]) {
return [[ProductA alloc] init];
} else if ([type isEqualToString:@"ProductB"]) {
return [[ProductB alloc] init];
} else {
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Invalid product type" userInfo:nil];
}
}
@end
使用工厂类来创建产品实例:
id<ProductProtocol> productA = [ProductFactory createProductWithType:@"ProductA"];
id<ProductProtocol> productB = [ProductFactory createProductWithType:@"ProductB"];
[productA operation]; // Output: ProductA operation
[productB operation]; // Output: ProductB operation
1.2抽象工厂模式:
这种模式提供了一种方法来创建相关或依赖对象的家族,而不需要指定它们的具体类。它适用于需要创建多个不同类型的对象的场景。
需要定义两个抽象产品接口,它们分别定义了所有具体产品必须实现的方法:
@protocol ProductAProtocol
- (void)operationA;
@end
@protocol ProductBProtocol
- (void)operationB;
@end
创建两个具体产品类,它们实现了抽象产品接口:
@interface ConcreteProductA1 : NSObject<ProductAProtocol>
@end
@implementation ConcreteProductA1
- (void)operationA {
NSLog(@"ConcreteProductA1 operationA");
}
@end
@interface ConcreteProductA2 : NSObject<ProductAProtocol>
@end
@implementation ConcreteProductA2
- (void)operationA {
NSLog(@"ConcreteProductA2 operationA");
}
@end
@interface ConcreteProductB1 : NSObject<ProductBProtocol>
@end
@implementation ConcreteProductB1
- (void)operationB {
NSLog(@"ConcreteProductB1 operationB");
}
@end
@interface ConcreteProductB2 : NSObject<ProductBProtocol>
@end
@implementation ConcreteProductB2
- (void)operationB {
NSLog(@"ConcreteProductB2 operationB");
}
@end
创建一个抽象工厂接口,它定义了创建具体产品的方法:
@protocol AbstractFactoryProtocol
- (id<ProductAProtocol>)createProductA;
- (id<ProductBProtocol>)createProductB;
@end
创建两个具体产品类,它们实现了抽象产品接口:
@interface ConcreteProductA1 : NSObject<ProductAProtocol>
@end
@implementation ConcreteProductA1
- (void)operationA {
NSLog(@"ConcreteProductA1 operationA");
}
@end
@interface ConcreteProductA2 : NSObject<ProductAProtocol>
@end
@implementation ConcreteProductA2
- (void)operationA {
NSLog(@"ConcreteProductA2 operationA");
}
@end
@interface ConcreteProductB1 : NSObject<ProductBProtocol>
@end
@implementation ConcreteProductB1
- (void)operationB {
NSLog(@"ConcreteProductB1 operationB");
}
@end
@interface ConcreteProductB2 : NSObject<ProductBProtocol>
@end
@implementation ConcreteProductB2
- (void)operationB {
NSLog(@"ConcreteProductB2 operationB");
}
@end
接下来创建一个抽象工厂接口,它定义了创建具体产品的方法:
@protocol AbstractFactoryProtocol
- (id<ProductAProtocol>)createProductA;
- (id<ProductBProtocol>)createProductB;
@end
两个具体工厂类,它们分别实现了抽象工厂接口:
@interface ConcreteFactory1 : NSObject<AbstractFactoryProtocol>
@end
@implementation ConcreteFactory1
- (id<ProductAProtocol>)createProductA {
return [[ConcreteProductA1 alloc] init];
}
- (id<ProductBProtocol>)createProductB {
return [[ConcreteProductB1 alloc] init];
}
@end
@interface ConcreteFactory2 : NSObject<AbstractFactoryProtocol>
@end
@implementation ConcreteFactory2
- (id<ProductAProtocol>)createProductA {
return [[ConcreteProductA2 alloc] init];
}
- (id<ProductBProtocol>)createProductB {
return [[ConcreteProductB2 alloc] init];
}
@end
使用具体工厂类来创建具体产品:
id<AbstractFactoryProtocol> factory1 = [[ConcreteFactory1 alloc] init];
id<AbstractFactoryProtocol> factory2 = [[ConcreteFactory2 alloc] init];
id<ProductAProtocol> productA1 = [factory1 createProductA];
id<ProductBProtocol> productB1 = [factory1 createProductB];
id<ProductAProtocol> productA2 = [factory2 createProductA];
id<ProductBProtocol> productB2 = [factory2 createProductB];
[productA1 operationA]; // Output: ConcreteProductA1 operationA
[productB1 operationB]; // Output: ConcreteProductB1 operationB
[productA2 operationA]; // Output: ConcreteProductA2 operationA
[productB2 operationB]; // Output: ConcreteProductB2 operationB
1.3建造者模式:
这种模式允许将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。它适用于需要生成复杂对象的场景。
创建一个产品类,它包含了多个属性:
@interface Product : NSObject
@property (nonatomic, strong) NSString *partA;
@property (nonatomic, strong) NSString *partB;
@property (nonatomic, strong) NSString *partC;
@end
@implementation Product
@end
创建一个建造者接口,它定义了创建产品的方法:
@protocol BuilderProtocol
- (void)buildPartA;
- (void)buildPartB;
- (void)buildPartC;
- (Product *)getResult;
@end
接下来,创建一个具体建造者类,它实现了建造者接口:
@interface ConcreteBuilder : NSObject<BuilderProtocol>
@property (nonatomic, strong) Product *product;
@end
@implementation ConcreteBuilder
- (instancetype)init {
self = [super init];
if (self) {
_product = [[Product alloc] init];
}
return self;
}
- (void)buildPartA {
self.product.partA = @"Part A";
}
- (void)buildPartB {
self.product.partB = @"Part B";
}
- (void)buildPartC {
self.product.partC = @"Part C";
}
- (Product *)getResult {
return self.product;
}
@end
现在,创建一个指挥者类,它负责调用建造者创建产品:
```objectivec
@interface Director : NSObject
+ (Product *)constructProductWithBuilder:(id<BuilderProtocol>)builder;
@end
@implementation Director
+ (Product *)constructProductWithBuilder:(id<BuilderProtocol>)builder {
[builder buildPartA];
[builder buildPartB];
[builder buildPartC];
return [builder getResult];
}
@end
最后,我们可以使用指挥者和建造者来创建产品:
```objectivec
ConcreteBuilder *builder = [[ConcreteBuilder alloc] init];
Product *product = [Director constructProductWithBuilder:builder];
NSLog(@"Part A: %@", product.partA); // Output: Part A
NSLog(@"Part B: %@", product.partB); // Output: Part B
NSLog(@"Part C: %@", product.partC); // Output: Part C
1.4原型模式:
这种模式是通过复制一个现有对象来生成新对象的。它适用于需要快速创建大量同类对象的场景。
创建一个原型类,它实现了 NSCopying 协议:
@interface Prototype : NSObject<NSCopying>
@property (nonatomic, strong) NSString *name;
@property (nonatomic, assign) NSInteger age;
@end
@implementation Prototype
- (instancetype)copyWithZone:(NSZone *)zone {
Prototype *prototype = [[[self class] allocWithZone:zone] init];
prototype.name = self.name;
prototype.age = self.age;
return prototype;
}
@end
可以创建一个原型对象,并通过拷贝来创建新的对象:
Prototype *prototype = [[Prototype alloc] init];
prototype.name = @"John";
prototype.age = 30;
Prototype *newPrototype = [prototype copy];
newPrototype.name = @"Mary";
newPrototype.age = 25;
NSLog(@"Original Prototype - Name: %@, Age: %ld", prototype.name, (long)prototype.age); // Output: Original Prototype - Name: John, Age: 30
NSLog(@"New Prototype - Name: %@, Age: %ld", newPrototype.name, (long)newPrototype.age); // Output: New Prototype - Name: Mary, Age: 25
1.5单例模式:
这种模式确保某个类只有一个实例,并提供一个全局访问点来访问它。这种模式适用于需要控制实例数量的场景。
创建一个单例类,它只会被实例化一次:
@interface Singleton : NSObject
+ (instancetype)sharedInstance;
@end
@implementation Singleton
+ (instancetype)sharedInstance {
static Singleton *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[self alloc] init];
});
return sharedInstance;
}
@end
通过单例类来获取实例:
Singleton *singleton1 = [Singleton sharedInstance];
Singleton *singleton2 = [Singleton sharedInstance];
NSLog(@"Singleton 1: %@", singleton1); // Output: Singleton 1: <Singleton: 0x60000012a340>
NSLog(@"Singleton 2: %@", singleton2); // Output: Singleton 2: <Singleton: 0x60000012a340>
NSLog(@"Are they the same object? %d", singleton1 == singleton2); // Output: Are they the same object? 1
2.结构型模式
结构型模式:主要关注类和对象的组合。结构型模式描述如何将类或对象按某种布局组成更大的结构。结构型模式包括:
适配器模式(Adapter Pattern)
桥接模式(Bridge Pattern)
组合模式(Composite Pattern)
装饰器模式(Decorator Pattern)
外观模式(Facade Pattern)
享元模式(Flyweight Pattern)
代理模式(Proxy Pattern)
2.1适配器模式:
这种模式允许将一个类的接口转换成另一个接口,以便于不兼容的类可以一起工作。它适用于需要让两个不兼容的类一起工作的场景。
定义一个目标接口(Target Interface),它是客户端代码所期望的接口:
@protocol TargetProtocol
- (void)request;
@end
创建一个适配器类(Adapter Class),它实现了目标接口:
@interface Adapter : NSObject<TargetProtocol>
@property (nonatomic, strong) Adaptee *adaptee;
- (instancetype)initWithAdaptee:(Adaptee *)adaptee;
@end
@implementation Adapter
- (instancetype)initWithAdaptee:(Adaptee *)adaptee {
self = [super init];
if (self) {
_adaptee = adaptee;
}
return self;
}
- (void)request {
[self.adaptee specificRequest];
}
@end
适配器类中包含了一个适配者对象(Adaptee Object),它是需要被适配的类:
@interface Adaptee : NSObject
- (void)specificRequest;
@end
@implementation Adaptee
- (void)specificRequest {
NSLog(@"Adaptee's specific request.");
}
@end
现在,我们可以在客户端代码中使用适配器来调用适配者的方法:
Adaptee *adaptee = [[Adaptee alloc] init];
Adapter *adapter = [[Adapter alloc] initWithAdaptee:adaptee];
[adapter request]; // Output: Adaptee's specific request.
2.2桥接模式:
这种模式将抽象部分和实现部分分离,以便它们可以独立变化。它适用于需要将一个类的抽象部分和实现部分独立改变的场景。
定义一个实现类接口(Implementor Interface),它声明了实现类所必须的方法:
@protocol ImplementorProtocol
- (void)operationImpl;
@end
创建一个实现类(Implementor Class),它实现了实现类接口:
@interface ConcreteImplementorA : NSObject<ImplementorProtocol>
@end
@implementation ConcreteImplementorA
- (void)operationImpl {
NSLog(@"Concrete Implementor A operation.");
}
@end
@interface ConcreteImplementorB : NSObject<ImplementorProtocol>
@end
@implementation ConcreteImplementorB
- (void)operationImpl {
NSLog(@"Concrete Implementor B operation.");
}
@end
现在定义一个抽象类(Abstraction Class),它包含一个指向实现类的指针,以及一个抽象方法:
@interface Abstraction : NSObject
@property (nonatomic, strong) id<ImplementorProtocol> implementor;
- (void)operation;
@end
@implementation Abstraction
- (void)operation {
[self.implementor operationImpl];
}
@end
最后,我们创建一个扩充抽象类(Refined Abstraction Class),它扩展了抽象类,并重写了抽象方法:
@interface RefinedAbstraction : Abstraction
@end
@implementation RefinedAbstraction
- (void)operation {
NSLog(@"Refined Abstraction operation.");
[self.implementor operationImpl];
}
@end
在代码中使用桥接模式:
ConcreteImplementorA *implementorA = [[ConcreteImplementorA alloc] init];
Abstraction *abstraction = [[Abstraction alloc] init];
abstraction.implementor = implementorA;
[abstraction operation]; // Output: Concrete Implementor A operation.
ConcreteImplementorB *implementorB = [[ConcreteImplementorB alloc] init];
RefinedAbstraction *refinedAbstraction = [[RefinedAbstraction alloc] init];
refinedAbstraction.implementor = implementorB;
[refinedAbstraction operation]; // Output: Refined Abstraction operation. Concrete Implementor B operation.
2.3组合模式:
这种模式允许将对象组成树形结构来表现“整体/部分”层次结构。它适用于需要表示树形结构的场景。
首先,定义一个组件抽象类(Component Abstract Class),它定义了组件的通用接口:
@interface Component : NSObject
@property (nonatomic, strong) NSString *name;
- (instancetype)initWithName:(NSString *)name;
- (void)add:(Component *)component;
- (void)remove:(Component *)component;
- (void)display;
@end
@implementation Component
- (instancetype)initWithName:(NSString *)name {
self = [super init];
if (self) {
_name = name;
}
return self;
}
- (void)add:(Component *)component {
NSLog(@"Cannot add to a leaf component.");
}
- (void)remove:(Component *)component {
NSLog(@"Cannot remove from a leaf component.");
}
- (void)display {
NSLog(@"%@", self.name);
}
@end
然后,创建一个组合类(Composite Class),它包含了多个组件对象:
@interface Composite : Component
@property (nonatomic, strong) NSMutableArray<Component *> *children;
@end
@implementation Composite
- (instancetype)initWithName:(NSString *)name {
self = [super initWithName:name];
if (self) {
_children = [NSMutableArray array];
}
return self;
}
- (void)add:(Component *)component {
[self.children addObject:component];
}
- (void)remove:(Component *)component {
[self.children removeObject:component];
}
- (void)display {
NSLog(@"%@", self.name);
for (Component *component in self.children) {
[component display];
}
}
@end
现在,我们创建两个叶子类(Leaf Class),它们是组合类中的子节点:
@interface LeafA : Component
@end
@implementation LeafA
- (void)display {
NSLog(@" - %@", self.name);
}
@end
@interface LeafB : Component
@end
@implementation LeafB
- (void)display {
NSLog(@" - %@", self.name);
}
@end
最后,我们可以在代码中使用组合模式:
Composite *root = [[Composite alloc] initWithName:@"Root"];
Composite *branch1 = [[Composite alloc] initWithName:@"Branch 1"];
Composite *branch2 = [[Composite alloc] initWithName:@"Branch 2"];
LeafA *leafA = [[LeafA alloc] initWithName:@"Leaf A"];
LeafB *leafB = [[LeafB alloc] initWithName:@"Leaf B"];
[root add:branch1];
[root add:branch2];
[branch1 add:leafA];
[branch2 add:leafB];
[root display];
2.4装饰模式:
这种模式允许在不改变现有对象的情况下动态地给它们添加新的职责。它适用于需要动态地为对象添加新职责的场景。
定义一个组件抽象类(Component Abstract Class),它定义了组件的通用接口:
@interface Component : NSObject
- (void)operation;
@end
@implementation Component
- (void)operation {
NSLog(@"Component operation");
}
@end
然后,我们创建一个具体组件类(Concrete Component Class),它是一个基础的组件,没有任何装饰:
@interface ConcreteComponent : Component
@end
@implementation ConcreteComponent
- (void)operation {
NSLog(@"ConcreteComponent operation");
}
@end
接下来,创建一个装饰器抽象类(Decorator Abstract Class),它也实现了组件的通用接口:
@interface Decorator : Component
@property (nonatomic, strong) Component *component;
- (instancetype)initWithComponent:(Component *)component;
@end
@implementation Decorator
- (instancetype)initWithComponent:(Component *)component {
self = [super init];
if (self) {
_component = component;
}
return self;
}
- (void)operation {
[self.component operation];
}
@end
最后,我们创建一个具体装饰器类(Concrete Decorator Class),它包装了一个具体组件类,并且可以在其上添加额外的行为:
@interface ConcreteDecorator : Decorator
@end
@implementation ConcreteDecorator
- (void)addedBehavior {
NSLog(@"ConcreteDecorator addedBehavior");
}
- (void)operation {
[super operation];
[self addedBehavior];
}
@end
在客户端代码中使用装饰器模式:
ConcreteComponent *component = [[ConcreteComponent alloc] init];
ConcreteDecorator *decorator = [[ConcreteDecorator alloc] initWithComponent:component];
[decorator operation];
/*
ConcreteComponent operation
ConcreteDecorator addedBehavior
*/
2.5外观模式:
这种模式提供了一个统一的接口,用来访问子系统中的一群接口。它适用于需要为一个复杂的子系统提供一个简单的接口的场景。
首先,我们定义一个外观类(Facade Class),它提供了一个简单的接口,用于访问一个或多个子系统的功能:
@interface Facade : NSObject
- (void)performOperation;
@end
@implementation Facade
- (void)performOperation {
SubsystemA *subsystemA = [[SubsystemA alloc] init];
SubsystemB *subsystemB = [[SubsystemB alloc] init];
[subsystemA operationA];
[subsystemB operationB];
}
@end
然后,创建多个子系统类(Subsystem Class),它们实现了各自的功能:
@interface SubsystemA : NSObject
- (void)operationA;
@end
@implementation SubsystemA
- (void)operationA {
NSLog(@"SubsystemA operationA");
}
@end
@interface SubsystemB : NSObject
- (void)operationB;
@end
@implementation SubsystemB
- (void)operationB {
NSLog(@"SubsystemB operationB");
}
@end
最后,在代码中使用外观模式,通过调用外观类的简单接口来使用子系统的功能:
Facade *facade = [[Facade alloc] init];
[facade performOperation];
2.6享元模式:
这种模式允许共享对象,以便最大限度地减少内存占用。它适用于需要在多个地方共享大量细粒度对象的场景。
定义一个享元抽象类(Flyweight Abstract Class),它定义了享元的通用接口:
@interface Flyweight : NSObject
- (void)operation:(NSString *)extrinsicState;
@end
@implementation Flyweight
- (void)operation:(NSString *)extrinsicState {
NSLog(@"Flyweight operation with extrinsic state: %@", extrinsicState);
}
@end
然后,我们创建多个具体享元类(Concrete Flyweight Class),它们实现了享元的具体功能,并且可以共享内部状态:
@interface ConcreteFlyweight : Flyweight
@property (nonatomic, strong) NSString *intrinsicState;
@end
@implementation ConcreteFlyweight
- (void)operation:(NSString *)extrinsicState {
NSLog(@"ConcreteFlyweight operation with intrinsic state: %@ and extrinsic state: %@", self.intrinsicState, extrinsicState);
}
@end
接下来,我们创建享元工厂类(Flyweight Factory Class),用于管理和创建享元对象:
@interface FlyweightFactory : NSObject
@property (nonatomic, strong) NSMutableDictionary *flyweights;
- (Flyweight *)flyweightForKey:(NSString *)key;
@end
@implementation FlyweightFactory
- (instancetype)init {
self = [super init];
if (self) {
_flyweights = [NSMutableDictionary dictionary];
}
return self;
}
- (Flyweight *)flyweightForKey:(NSString *)key {
Flyweight *flyweight = self.flyweights[key];
if (!flyweight) {
flyweight = [[ConcreteFlyweight alloc] init];
flyweight.intrinsicState = key;
self.flyweights[key] = flyweight;
}
return flyweight;
}
@end
最后使用享元模式,通过享元工厂类获取共享的享元对象,并调用其通用接口:
FlyweightFactory *factory = [[FlyweightFactory alloc] init];
Flyweight *flyweight1 = [factory flyweightForKey:@"key1"];
[flyweight1 operation:@"state1"];
Flyweight *flyweight2 = [factory flyweightForKey:@"key2"];
[flyweight2 operation:@"state2"];
Flyweight *flyweight3 = [factory flyweightForKey:@"key1"];
[flyweight3 operation:@"state3"];
/*
ConcreteFlyweight operation with intrinsic state: key1 and extrinsic state: state1
ConcreteFlyweight operation with intrinsic state: key2 and extrinsic state: state2
ConcreteFlyweight operation with intrinsic state: key1 and extrinsic state: state3
*/
2.7代理模式:
这种模式为另一个对象提供了一个替身或占位符,以便控制对这个对象的访问。它适用于需要在访问某个对象时增加额外控制的场景。
首先,定义一个代理协议(Proxy Protocol),它定义了代理的通用接口:
@protocol SubjectProxy <NSObject>
- (void)request;
@end
然后,创建一个实现代理协议的具体类(Real Subject Class),它定义了被代理的实际功能:
@interface RealSubject : NSObject <SubjectProxy>
@end
@implementation RealSubject
- (void)request {
NSLog(@"RealSubject handling request");
}
@end
接下来,创建一个代理类(Proxy Class),它同样实现了代理协议,但是在内部持有了一个被代理的对象,并且可以在代理方法中调用被代理对象的方法:
@interface Proxy : NSObject <SubjectProxy>
@property (nonatomic, strong) RealSubject *realSubject;
@end
@implementation Proxy
- (void)request {
if (!self.realSubject) {
self.realSubject = [[RealSubject alloc] init];
}
[self.realSubject request];
}
@end
在客户端代码中使用代理模式,通过代理类间接地调用被代理对象的方法:
Proxy *proxy = [[Proxy alloc] init];
[proxy request];
/*
RealSubject handling request
*/
客户端代码只调用了代理类的方法,但实际上被代理的对象也被调用了。通过代理类来控制对被代理对象的访问。
3.行为型模式
行为型模式:主要关注对象之间的通信。行为型模式描述了类和对象如何交互,以及他们的行为是怎样的。行为型模式包括:
职责链模式(Chain of Responsibility Pattern)
命令模式(Command Pattern)
解释器模式(Interpreter Pattern)
迭代器模式(Iterator Pattern)
中介者模式(Mediator Pattern)
备忘录模式(Memento Pattern)
观察者模式(Observer Pattern)
状态模式(State Pattern)
策略模式(Strategy Pattern)
模板方法模式(Template Method Pattern)
访问者模式(Visitor Pattern)
3.1责任链模式:
这种模式为请求创建了一个接收者对象的链,每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,它会把相同的请求传给下一个接收者,依此类推。它适用于需要在多个对象之间松散耦合的场景,并且希望在不明确指定接收者的情况下,向多个对象中的一个提交一个请求的场景。
首先,我们定义一个处理请求的抽象类(Handler Class),它有一个指向下一个处理器的引用,并且定义了处理请求的抽象方法:
@interface Handler : NSObject
@property (nonatomic, strong) Handler *nextHandler;
- (void)handleRequest:(NSString *)request;
@end
然后,创建多个具体处理器类(Concrete Handler Class),它们实现了处理请求的具体逻辑,并且根据需要可以将请求传递给下一个处理器:
@interface ConcreteHandlerA : Handler
@end
@implementation ConcreteHandlerA
- (void)handleRequest:(NSString *)request {
if ([request isEqualToString:@"A"]) {
NSLog(@"ConcreteHandlerA handling request %@", request);
} else {
[self.nextHandler handleRequest:request];
}
}
@end
@interface ConcreteHandlerB : Handler
@end
@implementation ConcreteHandlerB
- (void)handleRequest:(NSString *)request {
if ([request isEqualToString:@"B"]) {
NSLog(@"ConcreteHandlerB handling request %@", request);
} else {
[self.nextHandler handleRequest:request];
}
}
@end
@interface ConcreteHandlerC : Handler
@end
@implementation ConcreteHandlerC
- (void)handleRequest:(NSString *)request {
if ([request isEqualToString:@"C"]) {
NSLog(@"ConcreteHandlerC handling request %@", request);
} else {
[self.nextHandler handleRequest:request];
}
}
@end
接下来,将这些处理器链接起来形成责任链:
ConcreteHandlerA *handlerA = [[ConcreteHandlerA alloc] init];
ConcreteHandlerB *handlerB = [[ConcreteHandlerB alloc] init];
ConcreteHandlerC *handlerC = [[ConcreteHandlerC alloc] init];
handlerA.nextHandler = handlerB;
handlerB.nextHandler = handlerC;
最后,使用责任链模式,将请求发送给第一个处理器,然后责任链会自动选择合适的处理器处理请求:
[handlerA handleRequest:@"B"];
[handlerA handleRequest:@"C"];
[handlerA handleRequest:@"D"];
/*
ConcreteHandlerB handling request B
ConcreteHandlerC handling request C
*/
可以看到,第一个请求被处理器 B 处理了,第二个请求被处理器 C 处理了,第三个请求没有被任何处理器处理,说明责任链可以正确地选择合适的处理器来处理请求。
3.2命令模式:
这种模式将一个请求封装为一个对象,以便使用不同的请求、队列或日志来参数化其他对象。它适用于需要支持命令的撤销和恢复、延迟调用或日志操作的场景。
首先,定义一个抽象命令类(Command Class),它有一个执行命令的抽象方法:
@interface Command : NSObject
- (void)execute;
@end
接下来,我们定义一个命令接收者类(Receiver Class),它实现了具体的命令逻辑:
@interface Receiver : NSObject
- (void)doSomething;
@end
@implementation Receiver
- (void)doSomething {
NSLog(@"Receiver doing something");
}
@end
然后,我们创建多个具体命令类(Concrete Command Class),它们实现了具体的命令逻辑:
@interface ConcreteCommandA : Command
@end
@implementation ConcreteCommandA
- (void)execute {
NSLog(@"ConcreteCommandA executing command");
}
@end
@interface ConcreteCommandB : Command
@end
@implementation ConcreteCommandB
- (void)execute {
NSLog(@"ConcreteCommandB executing command");
}
@end
然后,我们创建多个具体命令对象,并将命令接收者传递给它们:
ConcreteCommandA *commandA = [[ConcreteCommandA alloc] initWithReceiver:[[Receiver alloc] init]];
ConcreteCommandB *commandB = [[ConcreteCommandB alloc] initWithReceiver:[[Receiver alloc] init]];
最后,我们创建一个命令调用者类(Invoker Class),它有一个命令队列和一个执行命令的方法。命令调用者可以将命令对象添加到队列中,然后依次执行它们:
@interface Invoker : NSObject
@property (nonatomic, strong) NSMutableArray<Command *> *commandQueue;
- (void)addCommand:(Command *)command;
- (void)executeCommands;
@end
@implementation Invoker
- (instancetype)init {
self = [super init];
if (self) {
_commandQueue = [[NSMutableArray alloc] init];
}
return self;
}
- (void)addCommand:(Command *)command {
[self.commandQueue addObject:command];
}
- (void)executeCommands {
for (Command *command in self.commandQueue) {
[command execute];
}
[self.commandQueue removeAllObjects];
}
@end
Invoker *invoker = [[Invoker alloc] init];
[invoker addCommand:commandA];
[invoker addCommand:commandB];
[invoker executeCommands];
/*
Receiver doing something
ConcreteCommandA executing command
Receiver doing something
ConcreteCommandB executing command
*/
可以看到,发送者对象可以通过命令对象来执行不同的业务逻辑,而不需要知道命令对象的具体实现细节。这样,命令模式可以有效地将请求与处理解耦,提高代码的可扩展性和可维护性。
3.3解释器模式:
这种模式定义了一个语言的文法,并且建立一个解释器来解释该语言中的句子。它适用于需要定义一个语言并为该语言实现一个解释器的场景。
首先,我们定义一个抽象表达式类(Expression Class),它有一个解释方法(interpret):
@interface Expression : NSObject
- (NSInteger)interpret;
@end
然后创建多个具体表达式类(Concrete Expression Class),它们实现了具体的解释逻辑:
@interface NumberExpression : Expression
@property (nonatomic, assign) NSInteger value;
- (instancetype)initWithValue:(NSInteger)value;
@end
@implementation NumberExpression
- (instancetype)initWithValue:(NSInteger)value {
self = [super init];
if (self) {
_value = value;
}
return self;
}
- (NSInteger)interpret {
return self.value;
}
@end
@interface AddExpression : Expression
@property (nonatomic, strong) Expression *leftExpression;
@property (nonatomic, strong) Expression *rightExpression;
- (instancetype)initWithLeft:(Expression *)leftExpression right:(Expression *)rightExpression;
@end
@implementation AddExpression
- (instancetype)initWithLeft:(Expression *)leftExpression right:(Expression *)rightExpression {
self = [super init];
if (self) {
_leftExpression = leftExpression;
_rightExpression = rightExpression;
}
return self;
}
- (NSInteger)interpret {
return [self.leftExpression interpret] + [self.rightExpression interpret];
}
@end
@interface SubtractExpression : Expression
@property (nonatomic, strong) Expression *leftExpression;
@property (nonatomic, strong) Expression *rightExpression;
- (instancetype)initWithLeft:(Expression *)leftExpression right:(Expression *)rightExpression;
@end
@implementation SubtractExpression
- (instancetype)initWithLeft:(Expression *)leftExpression right:(Expression *)rightExpression {
self = [super init];
if (self) {
_leftExpression = leftExpression;
_rightExpression = rightExpression;
}
return self;
}
- (NSInteger)interpret {
return [self.leftExpression interpret] - [self.rightExpression interpret];
}
@end
接下来,我们可以使用这些具体表达式类来构建表达式。例如,我们可以将 “2 + 3 - 1” 这个表达式构建成一个解释器对象:
Expression *expression = [[SubtractExpression alloc] initWithLeft:[[AddExpression alloc] initWithLeft:[[NumberExpression alloc] initWithValue:2] right:[[NumberExpression alloc] initWithValue:3]] right:[[NumberExpression alloc] initWithValue:1]];
最后,我们可以调用这个解释器对象的 interpret 方法,对这个表达式进行求值:
NSInteger result = [expression interpret];
NSLog(@"Result: %ld", result);
//这个模式这辈子都用不到… 吧(离谱)
3.4迭代器模式:
这种模式提供了一种方法来访问一个容器对象中各个元素,而又不暴露该对象的内部细节。它适用于需要为容器对象提供多种遍历方式的场景。
首先,我们定义一个可迭代的集合类(Collection):
@interface Collection : NSObject
- (void)addItem:(id)item;
- (id)itemAtIndex:(NSInteger)index;
- (NSInteger)count;
@end
@implementation Collection {
NSMutableArray *_items;
}
- (instancetype)init {
self = [super init];
if (self) {
_items = [NSMutableArray array];
}
return self;
}
- (void)addItem:(id)item {
[_items addObject:item];
}
- (id)itemAtIndex:(NSInteger)index {
return [_items objectAtIndex:index];
}
- (NSInteger)count {
return _items.count;
}
@end
接下来,我们定义一个迭代器接口(Iterator)和一个具体的迭代器实现类(CollectionIterator),其中迭代器类的职责是遍历集合类中的元素:
@protocol Iterator <NSObject>
- (id)next;
- (BOOL)hasNext;
@end
@interface CollectionIterator : NSObject <Iterator>
- (instancetype)initWithCollection:(Collection *)collection;
@end
@implementation CollectionIterator {
Collection *_collection;
NSInteger _index;
}
- (instancetype)initWithCollection:(Collection *)collection {
self = [super init];
if (self) {
_collection = collection;
_index = 0;
}
return self;
}
- (id)next {
id item = [_collection itemAtIndex:_index];
_index++;
return item;
}
- (BOOL)hasNext {
return _index < [_collection count];
}
@end
最后,我们可以使用迭代器来遍历集合中的元素,如下所示:
Collection *collection = [[Collection alloc] init];
[collection addItem:@"A"];
[collection addItem:@"B"];
[collection addItem:@"C"];
id<Iterator> iterator = [[CollectionIterator alloc] initWithCollection:collection];
while ([iterator hasNext]) {
NSLog(@"%@", [iterator next]);
}
输出结果为:
js复制代码A
B
C
3.5中介者模式:
这种模式用一个中介对象来封装一系列的对象交互,使各对象不需要显式地相互引用,从而使耦合松散,而且可以独立地改变它们之间的交互。它适用于需要在多个对象之间松散耦合的场景。
首先,我们定义一个中介者接口(Mediator):
@protocol Mediator <NSObject>
- (void)sendMessage:(NSString *)message fromUser:(id)sender;
@end
接下来,我们定义一个用户类(User),每个用户都有一个中介者和一个名称,并实现中介者接口中的方法:
@interface User : NSObject
@property (nonatomic, weak) id<Mediator> mediator;
@property (nonatomic, copy) NSString *name;
- (instancetype)initWithName:(NSString *)name mediator:(id<Mediator>)mediator;
- (void)sendMessage:(NSString *)message;
@end
@implementation User
- (instancetype)initWithName:(NSString *)name mediator:(id<Mediator>)mediator {
self = [super init];
if (self) {
_name = name;
_mediator = mediator;
}
return self;
}
- (void)sendMessage:(NSString *)message {
NSLog(@"%@ sends message: %@", self.name, message);
[self.mediator sendMessage:message fromUser:self];
}
@end
最后,我们定义一个具体的中介者类(ChatRoom),其中实现了中介者接口中的方法,并处理来自不同用户的消息:
@interface ChatRoom : NSObject <Mediator>
@end
@implementation ChatRoom
- (void)sendMessage:(NSString *)message fromUser:(id)sender {
NSLog(@"%@ sends message: %@", [sender name], message);
}
@end
我们可以创建几个用户和一个聊天室(中介者),并让他们发送消息:
ChatRoom *chatRoom = [[ChatRoom alloc] init];
User *alice = [[User alloc] initWithName:@"Alice" mediator:chatRoom];
User *bob = [[User alloc] initWithName:@"Bob" mediator:chatRoom];
User *charlie = [[User alloc] initWithName:@"Charlie" mediator:chatRoom];
[alice sendMessage:@"Hello, Bob!"];
[bob sendMessage:@"Hi, Alice!"];
[charlie sendMessage:@"Hey, everyone!"];
输出结果为:
yaml复制代码Alice sends message: Hello, Bob!
Bob sends message: Hi, Alice!
Charlie sends message: Hey, everyone!
可以看到,所有的消息都通过中介者类(聊天室)进行了中转和处理。
3.5状态模式:
这种模式允许一个对象在其内部状态改变时改变它的行为。它适用于需要根据对象的状态来改变它的行为的场景。
下面是一个使用状态模式的例子,假设有一个咖啡机类(CoffeeMachine),它可以根据不同的状态(State)来制作不同种类的咖啡。
首先,我们定义一个状态协议(State Protocol),该协议定义了咖啡机状态的基本行为:
@protocol CoffeeMachineState <NSObject>
- (void)brewCoffee;
@end
然后,我们定义不同状态下的具体实现类,例如制作浓缩咖啡(EspressoState)、制作拿铁咖啡(LatteState)等,这些类都实现了状态协议:
@interface EspressoState : NSObject <CoffeeMachineState>
@end
@implementation EspressoState
- (void)brewCoffee {
NSLog(@"制作浓缩咖啡");
}
@end
@interface LatteState : NSObject <CoffeeMachineState>
@end
@implementation LatteState
- (void)brewCoffee {
NSLog(@"制作拿铁咖啡");
}
@end
接下来,我们定义咖啡机类(CoffeeMachine),该类具有状态(State)属性:
@interface CoffeeMachine : NSObject
@property (nonatomic, strong) id<CoffeeMachineState> state;
- (void)brewCoffee;
@end
@implementation CoffeeMachine
- (void)brewCoffee {
[self.state brewCoffee];
}
@end
最后,我们可以使用上述类来制作不同种类的咖啡:
CoffeeMachine *coffeeMachine = [[CoffeeMachine alloc] init];
coffeeMachine.state = [[EspressoState alloc] init];
[coffeeMachine brewCoffee]; // 输出:制作浓缩咖啡
coffeeMachine.state = [[LatteState alloc] init];
[coffeeMachine brewCoffee]; // 输出:制作拿铁咖啡
在上述例子中,我们可以看到,使用状态模式可以有效地将不同状态下的行为进行封装,使得客户端可以简单地调用咖啡机对象的接口方法来制作不同种类的咖啡,而不需要关心具体的状态实现
3.6访问者模式:
这种模式把作用于某个对象结构中各元素的操作分离出来封装成独立的类,使其在不改变各元素的类的前提下可以添加作用于这些元素的新操作。它适用于需要在不改变各元素的类的前提下定义对这些元素的新操作的场景。
下面是一个使用访问者模式的例子,假设有一个社交媒体应用程序,其中有多个类(例如用户类、文章类等),每个类都有不同的数据结构和属性。现在我们想要实现一个访问者(Visitor)类,该类可以遍历这些类的对象并对它们进行操作。
首先,我们定义一个协议(Element Protocol)来定义不同类的基本行为:
@protocol Element <NSObject>
- (void)acceptVisitor:(id)visitor;
@end
然后,我们定义具体的类,例如用户类(User)、文章类(Article)等,这些类都实现了 Element 协议,并在 acceptVisitor: 方法中调用访问者的 visit 方法:
@interface User : NSObject <Element>
@property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) NSInteger age;
@end
@implementation User
- (void)acceptVisitor:(id)visitor {
[visitor visitUser:self];
}
@end
@interface Article : NSObject <Element>
@property (nonatomic, copy) NSString *title;
@property (nonatomic, copy) NSString *content;
@end
@implementation Article
- (void)acceptVisitor:(id)visitor {
[visitor visitArticle:self];
}
@end
接下来,我们定义访问者协议(Visitor Protocol),该协议定义了访问者的基本行为:
js复制代码@protocol Visitor
- (void)visitUser:(User *)user;
- (void)visitArticle:(Article *)article;
@end
然后,我们实现具体的访问者类(例如打印访问者),该类实现了 Visitor 协议:
@interface PrintVisitor : NSObject <Visitor>
@end
@implementation PrintVisitor
- (void)visitUser:(User *)user {
NSLog(@"访问用户:%@,年龄:%ld", user.name, (long)user.age);
}
- (void)visitArticle:(Article *)article {
NSLog(@"访问文章:%@,内容:%@", article.title, article.content);
}
@end
最后,我们可以使用上述类来遍历不同的类并进行访问:
User *user = [[User alloc] init];
user.name = @"John";
user.age = 25;
Article *article = [[Article alloc] init];
article.title = @"iOS开发";
article.content = @"iOS开发入门教程";
PrintVisitor *printVisitor = [[PrintVisitor alloc] init];
[user acceptVisitor:printVisitor]; // 输出:访问用户:John,年龄:25
[article acceptVisitor:printVisitor]; // 输出:访问文章:iOS开发,内容:iOS开发入门教程
在上述例子中,我们可以看到,使用访问者模式可以有效地将访问不同类的行为进行封装,使得客户端可以简单地调用对象的 acceptVisitor: 方法,并将访问者对象作为参数传入,来实现对不同类的访问操作。同时,访问者对象可以通过 visit 方法,实现对不同类的具体操作
3.7策略模式:
这种模式定义了一组算法,并将它们封装起来,使它们可以相互替换。它适用于需要在不同情况下使用不同算法的场景。
首先,定义一个策略协议(Strategy Protocol),它定义了策略的通用接口:
@protocol Strategy <NSObject>
- (void)doOperationWithNumber1:(NSInteger)number1 number2:(NSInteger)number2;
@end
然后,创建多个具体策略类(Concrete Strategy Class),它们实现了策略的具体功能:
@interface AddStrategy : NSObject <Strategy>
@end
@implementation AddStrategy
- (void)doOperationWithNumber1:(NSInteger)number1 number2:(NSInteger)number2 {
NSInteger result = number1 + number2;
NSLog(@"%ld + %ld = %ld", number1, number2, result);
}
@end
@interface SubtractStrategy : NSObject <Strategy>
@end
@implementation SubtractStrategy
- (void)doOperationWithNumber1:(NSInteger)number1 number2:(NSInteger)number2 {
NSInteger result = number1 - number2;
NSLog(@"%ld - %ld = %ld", number1, number2, result);
}
@end
接下来,创建策略上下文类(Strategy Context Class),它接受一个策略对象,并在执行时调用该策略的通用接口:
@interface StrategyContext : NSObject
@property (nonatomic, strong) id<Strategy> strategy;
- (instancetype)initWithStrategy:(id<Strategy>)strategy;
- (void)executeWithNumber1:(NSInteger)number1 number2:(NSInteger)number2;
@end
@implementation StrategyContext
- (instancetype)initWithStrategy:(id<Strategy>)strategy {
self = [super init];
if (self) {
_strategy = strategy;
}
return self;
}
- (void)executeWithNumber1:(NSInteger)number1 number2:(NSInteger)number2 {
[self.strategy doOperationWithNumber1:number1 number2:number2];
}
@end
代码中使用策略模式,根据不同的需求传入不同的策略对象:
StrategyContext *context1 = [[StrategyContext alloc] initWithStrategy:[[AddStrategy alloc] init]];
[context1 executeWithNumber1:5 number2:3];
StrategyContext *context2 = [[StrategyContext alloc] initWithStrategy:[[SubtractStrategy alloc] init]];
[context2 executeWithNumber1:5 number2:3];
/*
5 + 3 = 8
5 - 3 = 2
*/
可以看到,根据传入的不同策略对象,策略上下文类在执行时调用了不同的策略实现,实现了不同的计算功能。