设计模式之模板方法模式&&迪米特法则(代码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中模版文件”等,在现实生活中,模板的概念就是——有一个规定的格式,然后每个人都可以根据自己的需求或情况去更新它,例如简 ...
随机推荐
- Log4j 基本配置示例
1.log4j.properties log4j.rootLogger=INFO, stdout, fileout log4j.logger.TestProject=INFO log4j.append ...
- webpack window下配置的hello world
峰回路转 一区九折 先看效果:(此效果是webpack执行完之后会生成build文件夹已经它下面的index.html,点击index.html就是下图的效果)
- 代码管理(二)sourcetree 安装与使用
一 .SourceTree简介 SourceTree 是 Windows 和Mac OS X 下免费的 Git 和 Hg 客户端,拥有可视化界面,容易上手操作.同时它也是Mercurial和Subve ...
- centos6.4安装GitLab
参考文章: http://www.pickysysadmin.ca/2013/03/25/how-to-install-gitlab-5-0-on-centos-6/ yum安装redis的方法: h ...
- mysqld Can’t start server : Bind on unix socket: Permission denied
启动mysql报错: mysqld Can’t start server : Bind on unix socket: Permission denied 原因: mysql.sock无法建立,权限问 ...
- process credentials(二)
一.前言 为什么要写一个关于进程如何创建的文档?其实用do_fork作为关键字进行索引,你会发现网上的相关文档数以万计.作为一个内核工程师,对进程以及进程相关的内容当然是非常感兴趣,但是网上的资料并不 ...
- CListCtrl的LVN_KEYDOWN事件中怎么捕捉不到回车键?
原文链接: http://computer-programming-forum.com/81-vc/c92ab6e6d6ac92bc.htm 楼主 How to handle the return k ...
- java播放wav文件
import java.io.File; import java.io.IOException; import javax.sound.sampled.AudioFormat; import java ...
- android Jni NDK开发环境搭建及其简单实例的编写
android Jni NDK开发环境搭建及其简单实例的编写 由于工作需要,需要采用开发想要的JNI,由于之前没有接触过安卓的开发,所以更加网上的帖子,学习了下.遇到了些问题,然后总结下学习过程中 ...
- talend 连接mysql数据库没有权限
使用talend连接一个mysql数据库,提示没有权限,最后发现mysql服务器的配置中只监听了127.0.0.1的端口,拒绝非本地的请求.通过将/etc/mysql/my.cnf中的bind_add ...