首页 > 其他分享 >软件设计模式

软件设计模式

时间:2023-02-07 15:04:02浏览次数:40  
标签:NokiaPhone 软件设计 模式 callNumber NSString sendMessage AbstractCellPhone Decorator


有人说设计模式大致总结为23种,有人说29种,各式各样。我们讨论的不限于23种,关键掌握的是一些常用的设计模式。编程时一种技术,更加是一门艺术。不能只满足于写完代码运行结果正确就完事,时常考虑如何让那个代码更加简练,更加容易维护,容易扩展和复用,只有这样才能真正提高。

一 简单工厂设计模式

用单独的一个类来做这个创造实力的过程,这就是工厂类。父类A,子类B和C,子类B和C都用工厂类创建 出来,并赋值给父类A。再用父类A调用父类的方法Operation。当然子类B和C都重写了A,这个时候,如果是实例化的是谁真正调用的就是谁的operation。而不会因为是父类A接收就调用A的operation。简单来说简单工厂模式就是创建实例的一个过程。【简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现】

二.策略模式

定义一系列的算法,把每一个算法封装起来,写成一个单独的类。本模式使得算法可独立于使用它的客户而变化(也成为政策模式)。策略模式把对象本身和运算规则区分开来。

说一个使用场景可以更容易帮大家理解:我们在验证用户输入的表单的时候,加入包括电话输入框的验证和邮件输入框的验证,这两部分的验证算法是不同的,如果把这个算法看成一个函数,他几乎有相同的输入参数和返回参数。我们可以把这个相同的函数可以抽象为基类(InputValidator)的一个方法(bool validateInput(input,error)),然后抽象出两个具体的策略类:电话验证类(PhoneValidator)和邮件验证类(EmailValidator),他们需要在各自的实现里面去复写父类的验证方法(多态)。为了能够正常的调用到验证类的验证方法,我们需要自定义一个UITextField的子类CustomTextField,其中有一个InputValidator类型的引用和一个validate方法,该方法里面调用InputValidator的验证方法,然后在textFieldDidEndEditing代理方法里面调用CustomTextField的validate方法,这样就不用我们在判断输入是否合法的时候通过if else去处理每种逻辑,而且这样做方便扩展,提高可复用性。

如下图所示contetxInterface就如同是UITextField的接口,而AlgorithInterface是InputValidator这个基类,内部一个用于计算的实例方法,而ConcreteStrategyA,ConcreteStrategyB和ConcreteStrategyC都是抽象出来的子类,内部分别重写父类的用于计算的实例方法,利用多态特性,在需要的地方,生成对应的子类实例,再调用自身重写的用于计算的方法。完美的实现了策略模式。体现了面向对象的封装,继承,多态三大特性。

软件设计模式_#import

项目中下个版本要对签证的联系人姓名输入做一些b比较复杂的限制功能,可以尝试写一个策略模式来玩玩。

三,装饰模式


装饰模式是在不修改原来代码的情况下动态的给对象增加新的行为和职责,它通过一个对象包装被装饰对象的方法来修改类的行为,这种方法可以做为子类化的一种替代方法。


在Objective-C中,存在两种非常常见的实现:Category(类别)。 


Category(类别)是一种不需要子类化就可以让你能动态的给已经存在的类增加方法的强有力的机制。新增的方法是在编译期增加的,这些方法执行的时候和被扩展的类的其它方法是一样的。它可能与装饰设计模式的定义稍微有点不同,因为Category(类别)不会保存被扩展类的引用。



软件设计模式_子类_02

实例


接下来,通过Object-C来实践一下,我设想一个场景,用Decorator模式来实现一下对某个手机的GPS和蓝牙功能扩展 首先,我们需要一个手机的接口或者抽象类,我这里就用抽象类来实现,代码如下:


@interface AbstractCellPhone : NSObject

- (NSString *)callNumber;

- (NSString *)sendMessage;

@end

#import "AbstractCellPhone.h"

@implementation AbstractCellPhone

- (NSString *)callNumber

{

return @"phone call somebody";

}

- (NSString *)sendMessage

{

return @"phone send a message to somebody";

}

@end


AbstractCellPhone也就是结构图中的Component,然后,我再来实现Nokia和Moto的手机类,这类要继承AbstractCellPhone,也就是图中ConcreteComponent类要继承Component,实现代码如下:


#import "AbstractCellPhone.h" 

@interface NokiaPhone : AbstractCellPhone

@end


#import "NokiaPhone.h"

@implementation NokiaPhone

- (NSString *)callNumber

{

return @"NokiaPhone call somebody";

}

- (NSString *)sendMessage

{

return @"NokiaPhone send Message to Somebody";

}

@end


接下来我需要一个Decorator接口或者抽象类,实现代码如下:


#import "AbstractCellPhone.h"

@interface Decorator : AbstractCellPhone

{

@protected AbstractCellPhone *abstractCellPhone;

}

-(void)SetComponents:(Components*)component;

@end



#import "Decorator.h"

@implementation Decorator

-(void)SetComponents:(Components*)component{

components = component;

}

- (NSString *)callNumber

{

return components.callNumber;

}

- (NSString *)sendMessage

{

return components.sendMessage;

}

@end


正如结构图中,这个Decorator即继承了AbstractCellPhone,又包含了一个私有的AbstractCellPhone的对象。这样做的意义是:Decorator类又使用了另外一个Component类。我们可以使用一个或多个Decorator对象来“装饰”一个Component对象,且装饰后的对象仍然是一个Component对象。在下来,我要实现GSP和蓝牙的功能扩展,它们要继承自Decorator,代码如下:

#import "Decorator.h"

@interface DecoratorGPS : Decorator

@end


#import "DecoratorGPS.h"

@implementation DecoratorGPS

- (NSString *)callNumber

{

return [NSString stringWithFormat:@"%@ with GPS", [super callNumber]];

}

- (NSString *)sendMessage

{

return [NSString stringWithFormat:@"%@ with GPS", [super sendMessage]];

}

@end

最后,用客户端程序验证一下:


int main(int argc, const char *argv[])

{

@autoreleasepool {

Components *phone = [[ConcreteComponent alloc] init];

NSLog(@"%@",phone.callNumber);

NSLog(@"%@",phone.sendMessage);

ConcreteDecoratorA *GPS = [[ConcreteDecoratorA alloc] init];

[GPS SetComponents:phone];

NSLog(@"%@",GPS.callNumber);

NSLog(@"%@",GPS.sendMessage);

ConcreteDecoratorB *bluetooth = [[ConcreteDecoratorB alloc] init];

[bluetooth SetComponents:phone];

NSLog(@"%@",bluetooth.callNumber);

NSLog(@"%@",bluetooth.sendMessage);

}

return 0;

}


执行结果:



NokiaPhone call somebody

NokiaPhone send Message to Somebody

NokiaPhone call somebody with GPS

NokiaPhone send Message to Somebody with GPS

NokiaPhone call somebody with BlueTooth

NokiaPhone send Message to Somebody with BlueTooth

标签:NokiaPhone,软件设计,模式,callNumber,NSString,sendMessage,AbstractCellPhone,Decorator
From: https://blog.51cto.com/u_15952281/6042133

相关文章

  • 开发技术(一)—— SpringBoot使用策略模式
    Spring实现策略模式策略模式简介引言:当程序中使用太多的if/else/switch来处理不同类型的业务时,会变得极难维护,通过策略模式可以更容易的实现业务扩展和维护。模式概述:......
  • 创建型:抽象工厂模式
    创建型:抽象工厂模式目录介绍01.模式简单介绍02.模式结构介绍03.抽象工厂模式04.抽象工厂优缺点05.如何选工厂模式06.问题答疑思考01.模式简单介绍1.1定义抽......
  • 设计模式-建造者模式
    建造者模式builderModle.h#pragmaonce#include<iostream>#include<string>usingnamespacestd;classPhone{public: Phone(){} ~Phone(){} voidsetB......
  • 设计模式-单例模式
    简易单例模型easysiglemodle.h#ifndefEASYSIGLEMODLE_H#defineEASYSIGLEMODLE_H#include<iostream>usingnamespacestd;classEasySingleModle{public:......
  • 设计模式-工厂模式/抽象工厂模式
    工厂模式#include<iostream>#include<string>usingnamespacestd;classShape{public: virtualvoiddraw()=0;};classRectangle:publicShape{pub......
  • 【Appium_python】启动app,出现多次打开关闭导致失败问题,driver用单例模式(_new_)进行解
    运用多设备,启动app多次出现打开又关闭问题,查看后是多次对driver进行实例化,就用单例的模式进行解决。单例模式(SingletonPattern)目的就是保证一个类仅有一个实例,每一次执行......
  • 工厂模式-go语言实现
    一、理论知识工厂模式的作用就是用来创建对象,细分为三种:简单工厂、工厂方法、抽象工厂。1.1应用场景工厂模式一般用于对于不同的场景,需要创建不同的对象,但是这些对象实......
  • 单例模式
      一个类永远只能创建一个对象,例如任务管理器我们只要一个就可以解决问题了,这样可以节省内存空间。单例的实现方式很多:比如饿汉单例模式和懒汉单例模式....................
  • 搞懂设计模式——代理模式 + 原理分析
    作者:京东零售秦浩然引子举个栗子,众所周知,我们是可以在京东上购买机票的。但机票是航司提供的,我们本质上是代理销售而已。那为什么航司要让我们代理销售呢?我们又是如帮他做......
  • java合成模式之神奇的树结构
    目录什么是合成模式安全式合成模式抽象构件(Component)角色树叶构件(Leaf)角色树枝构件(Composite)角色使用透明式合成模式抽象构件(Component)角色树叶构件(......