设计模式之模板方法模式&&迪米特法则(代码Objective-C展示)
- 模板方法模式
模板方法模式:定义一个操作中的算法骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变一个算法的结构即可重定义该算法的某些特定步骤。
比如说,小时候数学老师的随堂检测,都是在黑板上抄题目,要我们先抄题目,然后再做答案,有时候没看清就会把题目抄错,这就意味着,即使做得再好,也不会正确了。
题目抄错了,那就不是考试题目了,而考试试卷最大的好处就是大家题目都一样,比如说选择题或者判断题,大家都是ABCD或者打钩打叉,非对即错的结果。这其实可以引申出来一个设计模式。
抄题目的代码,版本一:
#import <Foundation/Foundation.h> @interface ZYTestPaperA : NSObject
@property (nonatomic, copy) NSString *name; - (void)testQuestion1;
- (void)testQuestion2;
@end #import "ZYTestPaperA.h" @implementation ZYTestPaperA - (void)testQuestion1
{
NSLog(@"%@: “大煮干丝”是哪个菜系的代表菜之一( )。\n A四川菜系 B山东菜系 C广东菜系 D淮扬菜系",self.name);
}
- (void)testQuestion2
{
NSLog(@"%@: 红茶属于( )茶。\n A半发酵 B发酵 C不发酵 D微发酵",self.name);
} @end
#import <Foundation/Foundation.h> @interface ZYTestPaperB : NSObject
@property (nonatomic, copy) NSString *name; - (void)testQuestion1;
- (void)testQuestion2;
@end #import "ZYTestPaperB.h" @implementation ZYTestPaperB
- (void)testQuestion1
{
NSLog(@"%@: “大煮干丝”是哪个菜系的代表菜之一( )。\n A四川菜系 B山东菜系 C广东菜系 D淮扬菜系",self.name);
}
- (void)testQuestion2
{
NSLog(@"%@: 红茶属于( )茶。\n A半发酵 B发酵 C不发酵 D微发酵",self.name);
}
@end
viewController里面的代码:
#import "ViewController.h"
#import "ZYTestPaperA.h"
#import "ZYTestPaperB.h"
@interface ViewController () @end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad]; ZYTestPaperA *paperA = [[ZYTestPaperA alloc] init];
paperA.name = @"Joke";
[paperA testQuestion1];
[paperA testQuestion2]; ZYTestPaperB *paperB = [[ZYTestPaperB alloc] init];
paperB.name = @"Jom";
[paperB testQuestion1];
[paperB testQuestion2];
}
@end
上面的代码,很容易就可以发现问题,两张试卷,除了答案不同,其他几乎都相似,像上面那样写,既麻烦、又容易出错,也不易维护。
如果老师突然要改题目,那么两个人就都需要改代码,如果某人抄写错误,那就是很糟糕的一种体验了。
老师出一份题目,打印多份,让学生填写答案就可以了,在这里应该就是试题和答案分享,抽出一个父类,让两个子类继承它,公共的试题代码写到父类中就可以了。
如此,有下面的代码:
#import <Foundation/Foundation.h> @interface ZYTestPaper : NSObject
@property (nonatomic, copy) NSString *name; - (void)testQuestion1;
- (void)testQuestion2;
@end #import "ZYTestPaper.h" @implementation ZYTestPaper
- (void)testQuestion1
{
NSLog(@"%@: “大煮干丝”是哪个菜系的代表菜之一( )。\n A四川菜系 B山东菜系 C广东菜系 D淮扬菜系",self.name);
}
- (void)testQuestion2
{
NSLog(@"%@: 红茶属于( )茶。\n A半发酵 B发酵 C不发酵 D微发酵",self.name);
}
@end
#import <Foundation/Foundation.h>
#import "ZYTestPaper.h" @interface ZYTestPaperA : ZYTestPaper @end #import "ZYTestPaperA.h" @implementation ZYTestPaperA
- (void)testQuestion1
{
[super testQuestion1]; NSLog(@"答案是B");
} - (void)testQuestion2
{
[super testQuestion2]; NSLog(@"答案是C");
}
@end
#import <Foundation/Foundation.h>
#import "ZYTestPaper.h"
@interface ZYTestPaperB : ZYTestPaper @end #import "ZYTestPaperB.h" @implementation ZYTestPaperB
- (void)testQuestion1
{
[super testQuestion1]; NSLog(@"答案是B");
} - (void)testQuestion2
{
[super testQuestion2]; NSLog(@"答案是C");
}
@end
我们既然用了类的继承,并且肯定这个继承有意义,就应该要成为子类的模板,所有重复的代码都应该要上升到父类里面去,而不是让每个子类都去重复。
当我们要完成在某一细节层次一致的某一个过程或者一系列的步骤,但其个别步骤在更详细的实现上不同时,我们通常考虑用模板方法模式来处理。
简单的说,模板方法模式,是通过将不变的行为移动到父类中去,然后去除子类中的重复代码来体现它的优势,它提供了一个很好的代码复用平台。
当不变的和可变的行为在方法的子类实现中混合到一起的时候,不变的行为就会在子类中重复出现。我们通过模板方法模式将这些行为搬移到单一的地方,这样就帮助子类摆脱了重复的不变行为的纠缠。
2. 迪米特法则
迪米特法则,也叫最少知识原则:如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用,如果其中一个类需要调用另一个类的某一个方法的话,可以通过第三者转发这个调用。
迪米特法则首先强调的前提是,在类的结构设计上,每一个类都应当尽量降低成员的访问权限。也就是说,一个类包装好自己的private状态,不需要让别的类知道的字段或者行为就不要公开,需要公开的字段,就用属性来体现。
迪米特法则根本思想,是强调了类的松耦合。类之间的耦合越弱,越有利于复用,一个处在弱耦合的类被修改,不会对有关系的类造成波及。
设计模式之模板方法模式&&迪米特法则(代码Objective-C展示)的更多相关文章
- 折腾Java设计模式之模板方法模式
博客原文地址:折腾Java设计模式之模板方法模式 模板方法模式 Define the skeleton of an algorithm in an operation, deferring some ...
- 乐在其中设计模式(C#) - 模板方法模式(Template Method Pattern)
原文:乐在其中设计模式(C#) - 模板方法模式(Template Method Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 模板方法模式(Template Method ...
- Python笔记:设计模式之模板方法模式
此模式通过一个模板方法来定义程序的框架或算法,通常模板方法定义在基类中,即原始的模板,然后子类就可以根据不同的需要实现或重写模板方法中的某些算法步骤或者框架的某部分,最后达到使用相同模板实现不同功能的 ...
- js设计模式——6.模板方法模式与职责链模式
js设计模式——6.模板方法模式与职责链模式 职责链模式
- Java设计模式之模板方法模式(Template Method)
一.含义 定义一个算法中的操作框架,而将一些步骤延迟到子类中.使得子类可以不改变算法的结构即可重定义该算法的某些特定步骤,不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现. 二 ...
- PHP设计模式之模板方法模式
模板方法模式,也是我们经常会在不经意间有会用到的模式之一.这个模式是对继承的最好诠释.当子类中有重复的动作时,将他们提取出来,放在父类中进行统一的处理,这就是模板方法模式的最简单通俗的解释.就像我们平 ...
- java设计模式之模板方法模式
模板方法模式 定义一个操作中的算法的骨架,而将一些步骤延迟到子类中. 模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤.通俗的说的就是有很多相同的步骤的,在某一些地方可能有一些差 ...
- Head First 设计模式 --8 模板方法模式 别找我,我会找你
模板方法模式:在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中.模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤.设计原则:1.封装变化2.多用组合少用集成3.针对接口变 ...
- C#设计模式(14)——模板方法模式(Template Method)
一.引言 提到模板,大家肯定不免想到生活中的“简历模板”.“论文模板”.“Word中模版文件”等,在现实生活中,模板的概念就是——有一个规定的格式,然后每个人都可以根据自己的需求或情况去更新它,例如简 ...
随机推荐
- Fastjson是一个Java语言编写的高性能功能完善的JSON库。
简介 Fastjson是一个Java语言编写的高性能功能完善的JSON库. 高性能 fastjson采用独创的算法,将parse的速度提升到极致,超过所有json库,包括曾经号称最快的jackson. ...
- python学习笔记——爬虫中提取网页中的信息
1 数据类型 网页中的数据类型可分为结构化数据.半结构化数据.非结构化数据三种 1.1 结构化数据 常见的是MySQL,表现为二维形式的数据 1.2 半结构化数据 是结构化数据的一种形式,并不符合关系 ...
- rsync的基本使用
1,本地同步文件: rsync -avz --delete /home/ /backups/ 注意:在指定复制源时,路径是否有最后的 “/” 有不同的含义,例如: /home: 表示将整个 /home ...
- cucumber java从入门到精通(1)初体验
cucumber java从入门到精通(1)初体验 cucumber在ruby环境下表现让人惊叹,作为BDD框架的先驱,cucumber后来被移植到了多平台,有cucumber-js以及我们今天要介绍 ...
- 安装和配置SharePoint 2013 Workflow
SharePoint 2013中的工作流概述 在SharePoint 2013中,Workflow(建立在Windows Workflow Foundation 4.5)和WCF承载在Workflow ...
- STM32定时器T2纯软件仿真时间准确,JTAG在线调试查看时间不准的问题
通过查看Sec的值和上次中断的差值计算的,虽然这个值是不准的 ,但实际上时间是准的, 原因如下:stm32在调试模式下虽然进断点之后程序停止了,但定时器的时钟还在走,计数器还在计数,若要在产生断点时计 ...
- Python把同一个对象循环赋值给另外一个变量
Python把同一个对象循环赋值给另外一个变量,修改一个对象,其他对象也修改了 >>> row=['_'] * 3 >>> board = [] >>& ...
- 最简单的一个java驱动jdbc链接mysql数据库
导入jar包:mysql.connector-java-5.0.8-bin.jar String driver = "com.mysql.jdbc.Driver"; String ...
- WPF 4 Ribbon 开发 之 快捷工具栏(Quick Access Toolbar)
转自 http://www.cnblogs.com/gnielee/archive/2010/05/10/wpf4-ribbon-quick-access-toolbar.html 在Office 2 ...
- 参数化查询 '(@ActualShipTime datetime' 需要参数 @AuthorizationNumber,但未提供该参数。
转自 http://www.cnblogs.com/cxd4321/archive/2012/08/09/2629716.html 在平时的C#项目开发中,当调用某个存储过程或函数的时候,我们可能经常 ...