当前位置: 首页 > news >正文

敏捷开发笔记(第14章节)--TEMPLATE METHOD模式和STRATEGY模式:继承与委托

目录

1:PDF上传链接

14.1 TEMPLATE METHOD模式

14.1.1 滥用模式

14.2 STRATEGY模式

14.3结论


1:PDF上传链接

【免费】敏捷软件开发(原则模式与实践)资源-CSDN文库

         “业精于勒”。
                                                                                                        一中国谚语

        早在20世纪90年代初期一也就是面向对象发展的初期一人们就非常看重继承这个概念。继承关系蕴涵的意义是非常深远的。使用继承我们可以基于差异编程(program by difference)!也就是说,对于某个满足了我们大部分需要的类,可以创建一Jerrilee M.Koheke个它的子类,并只改变其中我们不期望的部分。只是继承一个类,就可以重用该类的代码!通过继承,我们可以建立完整的软件结构分类,其中每一层都可以重用该层次以上的代码。这是一个美丽的新世界。 

        像大多数美丽新世界一样,它最终也被证明有些不切实际。直到1995年,人们才清楚地认识到继承非常容易被过度使用,而且过度使用的代价是非常高的。Gamma,,Helm,Johnson和Vlissides甚至强调,“优先使用对象组合(object composition)而不是类继承(class inheritance)。”①所以我们减少了对继承的使用,常常使用组合或者委托来代替它。
        本章讲述了两个模式,并归纳了继承和委托之间的区别。TEMPLATE METHOD模式和STRATEGY模式所要解决的问题是类似的,而且常常可以互换使用。不过,TEMPLATE METHOD模式使用继承来解决问题,而STRATEGY模式使用的则是委托。
        TEMPLATE METHOD模式和STRATEGY模式都可以分离通用的算法和具体的上下文。在软件设计中经常会看到这样的需求。我们有一个通用的算法。为了遵循依赖倒置原则(DP),我们想确保这个通用的算法不要依赖于具体的实现。我们更想使这个通用的算法和具体的实现都依赖于抽象。

14.1 TEMPLATE METHOD模式

Initialize();
while(!done())    //main loop 
{Idle();    //do something useful.
}Cleanup();

        首先进行初始化。接着进入主循环。在主循环中完成需要做的工作,这些工作或许是处理GUI事件,或许是处理数据库记录。最后,一旦完成了工作,程序就退出主循环,并且在程序终止前做些清除工作。
        这种结构非常常见,所以可以把它封装在一个名为Application的类中。之后我们就可以在每个想要编写的新程序中重用这个类。想想!我们再也不需要去编写这个循环了!

        例如,在程序14.1中,我们看到了这种标准程序的所有组成部分。其中,初始化了InputStreamReader和BufferedReader,.并且有-一个主循环从BufferedReader中读取华氏温度,并把该温度转换成摄氏温度打印出来。最后,打印出一条退出信息。

程序14.1 ftoc rawimport java.io.*;
public class ftocraw
{public static void main(String[] args) throws Exception{InputstreamReader isr new InputStreamReader(System.in);BufferedReader br new BufferedReader(isr);boolean done = false;while (!done){String fahrstring br.readLine();if (fahrstring == null || fahrString.length() == 0)done true;else{double fahr = Double.parseDouble(fahrString);double celcius = 5.0 /9.0 * (fahr - 32);System.out.printin("F=" + fahr + "C=" + celcius);}}System.out.println("ftoc exit");}
}

        这个程序完全符合主循环结构。它先做一些初始化,接着在主循环中完成要做的工作,最后做一些清理工作并退出。
        我们可以应用TEMPLATE METHOD模式把这个基本结构从oc程序中分离出来。该模式把所有通用代码放入一个抽象基类(abstract base class)的实现方法中。这个实现方法完成了这个通用算法,但是将所有的实现细节都交付给该基类的抽象方法。
        这样,例如,我们可以把这个主循环结构封装在一个名为Application的抽象基类中。(参见程序14.2。)

程序14.2 Application.javapublic abstract class Application
{private boolean isDone = false;protected abstract void init ()protected abstract void idle();protected abstract void cleanup ();protected void setDone ()(isDone true;}protected boolean done ()(return isDone;}public void run (){	init();while (!done ())idle();cleanup ();}
}

        该类描绘了一个通用的主循环应用程序。从实现的u函数中,可以看到主循环。也可以看到
所有的工作都被交付给抽象方法int、idle以及cleanup.。init方法处理任何所需的初始化工作;idle方法处理程序的主要工作,并且在setDone方法被调用之前被重复调用:cleanup方法处理程序退出前所需的所有清理工作。
        我们可以通过继承Application来重写toc类,只需要实现Application中的抽象方法即可。程序14.3展示了重写后的程序。

程序14.3 ftocTemplateMethod.javaimport java.io.*
public class ftocTemplateMethod extends Application
{private InputStreamReader isr;private BufferedReader br;public static void main(String[] args)throws Exception{(new ftocTemplateMethod()).run();}protected void init(){isr = new InputstreamReader (System.in);br = new BufferedReader (isr);}protected void idle(){String fahrstring = readLineAndReturnNullIfError ()if (fahrString == null || fahrString.length ()== 0)setDone ();else{double fahr = Double.parseDouble(fahrstring);double celcius = 5.0 / 9.0 *(fahr-32);System.out.println("F=" + fahr + ", C=" + celcius);}}protected void cleanup(){System.out.println("ftoc exit");}private String readLineAndReturnNullIfError(){String s;try{s = br.readLine();}catch(IOException e){s = null;}return s;}
}

        由于进行了一些异常处理,程序显得略微长了些,但是还是能很容易地看出原先的o心应用程序是如何适配到TEMPLATE METHOD模式上去的。

14.1.1 滥用模式

        此时,你应该考虑这样的问题,“他是认真的吗?他真希望我在所有的新应用中都使用这个Application类吗?它没有带来任何有价值的东西,只是使问题复杂化了。”我之所以选择这个例子,是因为它简单,并且为展示TEMPLATE METHOD模式的机制提供了一个良好的平台。另一方面,我确实不推荐用这样的方法来构建c。
        这是滥用模式的一个好例子。在这个特定的应用程序中,使用TEMPLATE METHOD模式是荒谬的。它使程序变得复杂庞大。把每个应用程序的主循环以一种通用的方式封装起来,一开始这听起来很好,但是本例中的实际应用结果却是无益的。
        设计模式是很好的东西。它们可以帮助解决很多设计问题。但是它们的存在并不意味着必须要经常使用它们。本例中,虽然可以应用TEMPLATE METHOD模式,但是使用它是不明智的,因为使用该模式的代价要高于它所带来的好处。

        TEMPLATE METHOD模式展示了面向对象编程中诸多经典重用形式中的一种。其中通用算法被放置在基类中,并且通过继承在不同的具体上下文中实现该通用算法。但是这项技术是有代价的。继承是一种非常强的关系。派生类不可避免地要和它们的基类绑定在一起。

14.2 STRATEGY模式

        STRATEGY模式使用了一种非常不同的方法来倒置通用算法和具体实现之间的依赖关系。再来考虑一下滥用模式的Application问题。
        不是将通用的应用算法放进一个抽象基类中,而是将它放进一个名为ApplicationRunner的具体类中。我们把通用算法必须要调用的抽象方法定义在一个名为Application的接口中。我们从这个接口派生出ftocStrategy,并把它传给ApplicationRunner。之后,ApplicationRunner就可以把具体工作委托给这个接口去完成。

        STRATEGY模式比TEMPLATE METHOD模式多提供了一个额外的好处。尽管TEMPLATE METHOD模式允许一个通用算法操纵多个可能的具体实现,但是由于STRATEGY模式完全遵循DP原则,从而允许每个具体实现都可以被多个不同的通用算法操纵。

14.3结论

        TEMPLATE METHOD模式和STRATEGY模式都可以用来分离高层的算法和低层的具体实现细节。都允许高层的算法独立于它的具体实现细节重用。此外,STRATEGY模式也允许具体实现细节独立于高层的算法重用,不过要以一些额外的复杂性、内存以及运行时间开销作为代价。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【第四节】python面向对象
  • 基于 LangChain 开发应用程序第七章-代理
  • 781页 | 2024全国数据资产政策法规汇编(可下载)
  • 富唯智能转运机器人:高效、智能、未来的选择
  • 代码随想录算法训练营第二十六天|452. 用最少数量的箭引爆气球、435. 无重叠区间、763.划分字母区间
  • 11部门公布第二批国家数字乡村试点地区名单
  • uniapp微信小程序本地和真机调试文件图片上传成功但体验版不成功
  • K8S Service-NodePort:固定端口
  • 数据化项目中如何优化数据分析报表的响应速度
  • 宠物伴侣应用
  • Redisson中RSemaphore的使用场景及例子
  • 【微服务】微服务架构概念
  • 前端如何实现更换项目主题色的功能?
  • 全面整理人工智能(AI)学习路线图及资源推荐
  • 深度学习项目 -7-使用 Python 的手写数字识别
  • 4个实用的微服务测试策略
  • CSS中外联样式表代表的含义
  • gf框架之分页模块(五) - 自定义分页
  • Linux后台研发超实用命令总结
  • MySQL-事务管理(基础)
  • vue-cli在webpack的配置文件探究
  • windows-nginx-https-本地配置
  • 发布国内首个无服务器容器服务,运维效率从未如此高效
  • 干货 | 以太坊Mist负责人教你建立无服务器应用
  • 基于Javascript, Springboot的管理系统报表查询页面代码设计
  • 开年巨制!千人千面回放技术让你“看到”Flutter用户侧问题
  • 模仿 Go Sort 排序接口实现的自定义排序
  • 前端面试总结(at, md)
  • 你学不懂C语言,是因为不懂编写C程序的7个步骤 ...
  • #ubuntu# #git# repository git config --global --add safe.directory
  • #我与Java虚拟机的故事#连载11: JVM学习之路
  • (NSDate) 时间 (time )比较
  • (阿里云万网)-域名注册购买实名流程
  • (教学思路 C#之类三)方法参数类型(ref、out、parmas)
  • (蓝桥杯每日一题)love
  • (三)mysql_MYSQL(三)
  • (十三)Flink SQL
  • (一) springboot详细介绍
  • (一)SvelteKit教程:hello world
  • .gitignore文件设置了忽略但不生效
  • .NET 3.0 Framework已经被添加到WindowUpdate
  • .NET CLR Hosting 简介
  • .Net Remoting(分离服务程序实现) - Part.3
  • .Net(C#)自定义WinForm控件之小结篇
  • .NET6 命令行启动及发布单个Exe文件
  • .NET6使用MiniExcel根据数据源横向导出头部标题及数据
  • .Net6使用WebSocket与前端进行通信
  • .NetCore项目nginx发布
  • .net反混淆脱壳工具de4dot的使用
  • .NET框架类在ASP.NET中的使用(2) ——QA
  • .NET委托:一个关于C#的睡前故事
  • /usr/bin/python: can't decompress data; zlib not available 的异常处理
  • [ C++ ] template 模板进阶 (特化,分离编译)
  • [ CTF ]【天格】战队WriteUp- 2022年第三届“网鼎杯”网络安全大赛(青龙组)
  • [1127]图形打印 sdutOJ