模板方法模式实现探讨

合集下载

模板方法模式

模板方法模式

模板方法模式模板方法模式是一种行为设计模式,它定义了一个算法的骨架,并允许子类为一个或多个步骤提供实现。

模板方法模式使得子类可以在不改变算法结构的情况下重新定义算法的某些步骤。

在本文中,我们将深入探讨模板方法模式的原理、结构、应用场景以及优缺点。

原理。

模板方法模式的核心思想是定义一个算法的骨架,将算法中不变的部分抽象出来,而将可变的部分交由子类来实现。

这样可以保持算法的结构不变,同时允许子类根据需要重新定义算法的某些步骤。

在模板方法模式中,通常会定义一个抽象类,其中包含一个模板方法和若干个基本方法。

模板方法用于定义算法的骨架,而基本方法用于实现算法的各个步骤。

结构。

模板方法模式包含以下几个角色:1. 抽象类(Abstract Class),定义了一个模板方法,其中包含算法的骨架,以及若干个基本方法用于实现算法的各个步骤。

2. 具体类(Concrete Class),实现了抽象类中的基本方法,以完成算法的各个步骤。

应用场景。

模板方法模式通常适用于以下场景:1. 当算法的整体结构已经确定,但各个步骤的具体实现可能各不相同时,可以使用模板方法模式。

这样可以避免重复编写相似的代码,提高代码的复用性。

2. 当需要在不同的情况下使用相似的算法时,可以使用模板方法模式。

这样可以将算法的公共部分抽象出来,而将不同的部分交由子类来实现。

优缺点。

模板方法模式的优点包括:1. 提高代码的复用性。

模板方法模式将算法的骨架抽象出来,可以在不改变算法结构的情况下重定义算法的某些步骤,从而提高代码的复用性。

2. 提高扩展性。

模板方法模式允许子类重新定义算法的某些步骤,从而提高了系统的灵活性。

模板方法模式的缺点包括:1. 增加了系统的抽象性和理解难度。

模板方法模式将算法的骨架抽象出来,可能会增加系统的抽象性和理解难度。

2. 不适合所有情况。

模板方法模式适用于算法的整体结构已经确定,但各个步骤的具体实现可能各不相同的情况,不适合所有情况。

设计模式在游戏框架设计中的应用

设计模式在游戏框架设计中的应用

设计模式在游戏框架设计中的应用摘要:设计模式在软件设计中起着非常重要的作用,使用设计模式可以提高软件的可维护性和复用性。

模板方法模式是设计模式中常用的一种模式,本文应用该模式设计了一个windows游戏程序框架,可在不同的视频游戏程序中使用。

关键词:设计模式;模板方法模式;windows游戏;框架中图分类号tp31 文献标识码a 文章编号 1674-6708(2011)53-0171-010 引言“模式”这个词来源于克里斯托夫·亚历山大的《模式语言》(a pattern language)一书,书中提到:“每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的解决方案的核心。

这样,你就能一次又一次地使用该方案而不必做重复劳动”。

后来,“模式”一词被引入到计算机科学领域,成为软件设计者一直在追求的普遍性原则。

设计模式并不是直接用来完成代码的编写,而是描述在各种不同的情况下,要怎么解决问题的一种方案。

使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。

面向对象设计离不开设计模式,游戏开发自然也离不开设计模式。

本文应用设计模式中的模板方法模式为不同的windows视频游戏搭建了一个可复用的框架。

1 模板方法模式介绍模板方法模式是《设计模式:可复用面向对象软件的基础》一书中描述的23种设计模式中的其中一种,也是最常见的几种模式之一。

它在框架设计中得到了广泛的应用。

通常我们会遇到这样一个问题:我们知道一个算法所需的关键步骤,并确定了这些步骤的执行顺序。

但是某些步骤的具体实现是未知的,或者说某些步骤的实现与具体的环境相关。

模板方法模式把我们不知道具体实现的步骤封装成抽象方法,提供一个按正确顺序调用它们的具体方法,构成一个抽象基类。

子类通过继承这个抽象基类去实现各个步骤的抽象方法,而工作流程却由父类控制。

换句话说,模板方法模式是定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。

作业设计模式构建方案

作业设计模式构建方案

作业设计模式构建方案在软件开发过程中,设计模式是一种解决特定问题的经典架构的重复利用性方案。

设计模式可以提供可复用、可理解、可维护的代码,同时也能提高软件的兼容性和可拓展性。

本文将以作业设计为例,介绍如何运用设计模式来构建一个高效的作业设计方案。

在作业设计的过程中,可以使用以下几个常用的设计模式:1. 单例模式(Singleton pattern):在作业设计中,可能会涉及到共享资源的访问问题。

为了避免资源的多次创建和浪费,可以使用单例模式来创建一个全局唯一的对象。

这样可以保证该对象只会被创建一次,并且可以在整个作业设计过程中共享。

2. 工厂模式(Factory pattern):在作业设计中,可能会涉及到创建不同类型的对象。

为了避免代码的重复和依赖关系的耦合,可以使用工厂模式来创建对象。

通过一个工厂类来封装对象的创建过程,让客户端只关心如何使用对象,而不需要关心对象的具体创建过程。

3. 观察者模式(Observer pattern):在作业设计中,可能会涉及到不同组件之间的协作和通信问题。

为了实现组件之间的松耦合和相互通知,可以使用观察者模式。

通过定义一个主题对象和多个观察者对象,主题对象在状态发生变化时,会通知所有的观察者对象。

4. 适配器模式(Adapter pattern):在作业设计中,可能会涉及到不同接口之间的转换问题。

为了实现不同接口之间的兼容性和互操作性,可以使用适配器模式。

通过定义一个适配器对象,将不同接口的方法进行转换和封装,从而使得不同接口之间可以互相调用。

5. 模板方法模式(Template method pattern):在作业设计中,可能会涉及到一系列相似的流程和算法。

为了避免重复编写相似的代码和算法,可以使用模板方法模式。

通过定义一个抽象类,其中包含一个模板方法和一些具体的方法,模板方法中的具体实现可以由子类去实现。

6. 策略模式(Strategy pattern):在作业设计中,可能会涉及到同一种行为的多种实现方式。

C++策略模式和模板模式

C++策略模式和模板模式

所谓策略模式:是指定义一系列的算法,把它们一个个封装起来,并且使它们可以互相替换。

使得算法可以独立于使用它的客户而变化,也就是说这些算法所完成的功能是一样的,对外接口是一样的,只是各自现实上存在差异。

它主要解决在有多种算法相似的情况下,使用if...else 所带来的复杂和难以维护。

那么它有哪些优缺点呢?策略模式的优点:1. 每个算法单独封装,减少了算法和算法调用者之间的耦合。

2. 合理使用继承有助于提取出算法中的公共部分。

3. 简化了单元测试。

策略模式的缺点:1. 策略模式只适用于客户端知道所有算法或者行为的情况。

2. 策略模式造成很多的策略类,每个具体策略类都会产生一个新类,策略模式的适用场景1. 多个类有不同的表现形式,每种表现形式都可以独立成单独的算法。

2. 需要不同的情况下使用不同的算法,以后算法还可能会增加。

3. 对用户隐藏算法逻辑。

下边介绍具体的实现方法://传统策略模式实现class Hurt{public:virtual void redBuff() = 0;};class AdcHurt:public Hurt{public:void redBuff(){cout << "Adc hurt" << endl;}};class ApcHurt:public Hurt{public:void redBuff(){cout << "Apc hurt" << endl;}};//方法1:传入一个指针参数class Soldier{public:Soldier(Hurt* hurt):m_hurt(hurt){}~Soldier(){}void beInjured(){m_hurt->redBuff();}private:Hurt* m_hurt;};//方法2:传入一个参数标签typedef enum{adc,apc}HurtType;class Master{public:Master(HurtType type){switch(type){case adc:m_hurt = new AdcHurt;break;case apc:m_hurt = new ApcHurt;break;default:m_hurt = NULL;break;}}~Master(){}void beInjured(){if(m_hurt != NULL){m_hurt->redBuff();}else{cout << "Not hurt" << endl;}}private:Hurt* m_hurt;};//方法3:使用模板类template <typename T>class Tank{public:void beInjured(){m_hurt.redBuff();}private:T m_hurt;};//END//使用函数指针实现策略模式void adcHurt(int num){cout << "adc hurt:" << num << endl;}void apcHurt(int num){cout << "apc hurt:" << num << endl;}//普通函数指针class Aid{public:typedef void (*HurtFun)(int);Aid(HurtFun fun):m_fun(fun){}void beInjured(int num){m_fun(num);}private:HurtFun m_fun;};//使用std::function , 头文件:#include<functional>class Bowman{public:typedef std::function<void(int)> HurtFunc;Bowman(HurtFunc fun):m_fun(fun){}void beInjured(int num){m_fun(num);}private:HurtFunc m_fun;};//END所谓模板模式是指在一个基类中定义一个算法操作的骨架,而将一些步骤延迟到子类中去实现。

Spring中常见的设计模式——模板模式

Spring中常见的设计模式——模板模式

Spring中常见的设计模式——模板模式⼀、模板模式的应⽤场景 模板模式⼜叫模板⽅法模式(Template Method Pattern),指定义⼀个算法的⾻架,并允许⾃雷为⼀个或者多个步骤提供实现。

模板模式使得⼦类可以在不改变算法结果的情况下,重新定义算法的某些步骤,属于⾏为型设计模式。

模板模式适⽤于以下场景:⼀次性实现⼀个算法的不变部分,并将可变的⾏为留给⼦类来实现。

各⼦类中公共的⾏为被提取出来并集中到⼀个公共的⽗类中,从⽽避免代码重复。

把东西装冰箱的步骤模板:public abstract class PutThingIntoFrigCourse {protected final void createCourse() {//是否需要对⼤块的东西进⾏切割if (needCut()) {this.cut();}//打开冰箱门this.openDoor();//把东西放进去this.putThingIntoFrig();//关闭冰箱门this.closeDoor();}//钩⼦⽅法:对步骤进⾏微调protected boolean needCut() {return false;}//钩⼦⽅法:就是通过返回值对模板类内部进⾏修改abstract String thing();final void cut() {System.out.println("切碎" + thing());}final void openDoor() {System.out.println("打开冰箱门");}final void putThingIntoFrig() {System.out.println("把" + thing() + "放冰箱");}final void closeDoor() {System.out.println("关闭冰箱门");}} 这⾥⾯的钩⼦⽅法主要⽬的是⼲预执⾏流程,使得控制⾏为更加灵活,更符合实际业务需求,钩⼦⽅法通过返回值对主流程进⾏控制。

工程CAD中模板技术的应用探讨

工程CAD中模板技术的应用探讨

中国校外教育下旬刊 网络探究工程CAD 中模板技术的应用探讨◆蒋素娥工程设计中存在着大量约定俗成的模式。

这些设计套路是工程设计人员多年工程实践的积累与体现。

其合理有效地应用将大大提高设计效率。

本文根据工程模板的概念,对模板的运算与性质进行了分析和讨论。

并将该研究应用于工厂设计系统中。

收到了良好的效果。

模板 工程设计 CAD 工程CAD 是计算机辅助设计领域的一个重要分支,它涉及石油、化工、建筑、纺织、桥梁、公路等众多领域,具有广泛的应用价值。

目前,工程CAD 技术有了很大的发展,许多商品软件不断推出,我国引进的国外工作站版工程设计软件主要有PDMS ,Intergrap h 和CV 等;微机版工程设计软件则有Auto PL AN T ,B echt el3DM 和CADPIPE 等。

经过二十多年来的发展,一方面,工程CAD 系统不断吸收计算机行业最新的研究成果,逐渐向着集成化、自动化、智能化和网络化的方向发展;另一方面,硬件支撑平台中微机与工作站的区别逐渐变得模糊,基于微机的系统功能越来越强大,PDMS ,Int ergrap h 等软件纷纷推出了基于Micro sof t W i ndo ws N T 的微机版本,这一发展趋势必将进一步促进工厂设计软件的应用。

但越来越普遍和复杂化的应用要求,给一些传统的方法和理论带来了挑战。

一、模板在工程设计中还有许多问题是目前的设计方法不能很好解决的问题。

针对这些问题和工程设计的特点,本文考察了在计算机领域中应用十分广泛的模板技术,并在此基础上提出了工程模板的概念和基于工程模板的工程设计方法。

“模板”一词起源于铸造。

“模”的本义为铸造器物的模子。

“模板”一词的英文为:t empl at e ,s t encil 。

Template 的英文解释为:一块被裁成特定形状的薄板,用于引导对金属、木材、粘土等的裁剪。

St encil 的英文解释为:一块材料(如纸片、金属)的内部被裁出图案或字符,通过这些空隙将颜料或墨水涂在纸上形成图案和字符。

策略模式整合模板方法

策略模式整合模板方法

策略模式整合模板方法
策略模式和模板方法是两种常见的设计模式,它们在软件开发中起着重要的作用。

通过将它们整合在一起,可以更好地利用它们的优点,提高代码的灵活性和可维护性。

策略模式是一种行为型设计模式,它允许在运行时选择算法的行为。

它通过将不同的算法封装在独立的策略类中,使得它们可以互相替换,达到动态改变对象的行为的目的。

在策略模式中,我们定义了一个公共接口,所有的策略类实现这个接口,并根据不同的需求提供不同的实现。

而模板方法是一种行为型设计模式,它定义了一个算法的骨架,将一些步骤的实现交给子类来完成。

通过模板方法,可以在不改变算法结构的情况下,允许子类重新定义算法中的某些步骤。

模板方法模式常常用于实现一些公共的算法流程,提高了代码的复用性和可维护性。

通过整合策略模式和模板方法模式,我们可以将策略类作为模板方法模式中的一部分,允许在模板方法中动态切换策略。

这样可以使得模板方法更加灵活,可以根据不同的需求使用不同的策略。

在整合的过程中,我们可以将策略类作为模板方法类的一个属性,并在模板方法中根据需要选择合适的策略进行调用。

这种整合方式可以使得代码更加结构化和可维护,同时也符合设计原则中的单一职责原则和开闭原则。

综上所述,策略模式和模板方法是两种常见的设计模式,它们可以通过整合来实现更好的代码结构和灵活性。

在实际应用中,我们可以根据具体的需求来选择是否需要整合这两种模式,以达到最佳的设计方案。

模板方法模式和策略模式

模板方法模式和策略模式

模板方法模式和策略模式模板方法模式模板方法模式是一种对对象行为的抽象化,它是将某个对象的行为提取出来,封装在方法中,那么该模式就是将某类的行为的设计抽象化,通过抽象化可以简化该类调用时的复杂度。

模板方法模式定义了一个算法的步骤,并将这些步骤的实现延迟到子类中。

这样,即使子类实现了不同的行为,它们仍然可以按照抽象类中定义的步骤去执行。

模板方法模式有以下几个角色:(1)抽象类:抽象类可以定义算法的步骤,它将每一步定义为一个抽象方法,需要子类去实现,但是它不需要指定算法的具体实现步骤;(2)具体子类:由于算法的具体实现步骤由子类来完成,所以它可以完成算法中与特定操作相关而将封装在抽象类中的步骤,也可以重写父类定义的抽象方法;(3)客户端:通常是主函数,负责创建具体子类的实例,并调用其中的某些方法来实现算法的步骤。

模板方法模式的使用场景(1)在某些业务中,多个子类之间存在大量的公用代码,可以将这些公用的代码放到一个父类的模板方法中,以此来减少代码的重复性;(2)当处理某类型问题时,不同的子类可能会提供不同的解决方案,而抽象类可以把这些解决方案整合到一个模板方法中,从而利用这种抽象性去解决具体的问题。

策略模式策略模式是一种行为设计模式,它定义了可以互换的算法族,并且使它们之间可以相互替换。

该模式使得算法可独立于使用它的客户而变化。

策略模式可以看作是一种用于替换多重条件分支语句的更好方案。

(1)环境类:环境类是一个使用策略类的客户端,它可以对一个策略对象进行配置、用于在运行时选择算法;(2)抽象策略:抽象策略类是一类算法的抽象,功能和接口都可以在该抽象类中定义;(4)客户端:使用环境类的客户端,可以使用不同的算法来实现不同的业务,它可以根据实际情况替换策略。

(1)当一个系统具有多种处理某一个问题的算法,并且客户端需要动态地在这些算法中选择一种解决方案时,可以采用策略模式;(2)当系统需要根据外部条件来选择不同的算法时,可以使用策略模式;(3)当一个对象有很多的行为相似,可以采用策略模式,把相似的行为放到一个策略类中,使结构更加清晰。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
模板方法(Template Method)模式是 GOF 设计模式中最为常见几个模式之一。现在流行的很 多框架中(如 Spring,Struts 等),我们都可以看到模板方法模式的广泛应用。模板方法模式 主要应用于框架设计中,在日常的应用设计中也被经常使用。可是,我们在运用模板方法模 式来解决我们的需求而进行设计时,往往忽略了一些非常重要的细节。保证架构逻辑的正常 执行,不被子类破坏;怎么让子类扩展模板方法等。 1.模板方法设计模式的意图 通常我们会遇到这样的一个问题:我们知道一个算法所需的关键步骤,并确定了这些步骤的 执行顺序。但是某些步骤的具体实现是未知的,或者说某些步骤的实现与具体的环境相关。 模板方法模式把我们不知道具体实现的步骤封装成抽象方法,提供一个按正确顺序调用它们 的具体方法(这些具体方法统称为“模板方法”),这样构成一个抽象基类。子类通过继承这个抽 象基类去实现各个步骤的抽象方法,而工作流程却由父类控制。 考虑一个简单的订单处理需求:一个客户可以在一个订货单中订购多个货物(也称为订货单 项目),货物的销售价是根据货物的进货价进行计算的(不同货物有不同的售价计算方法)。有 些货物可以打折的,有些是不可以打折的。每一个客户都有一个信用额度,每张订单的总金 额不能超出该客户的信用额度。 根据上面的业务,我们可以知道处理一个订单所需要的步骤: 1.遍历订货单的订货单项目列表,累加所有货物的总价格(根据订货单项目计算出销售价); 2.根据客户号获得客户的信用额度; 3.把客户号,订单的总价格,及订单项目列表写入到数据库; 但是我们并不能确定怎么计算出货物的销售价,怎样根据客户号获得客户的信用额度及把订 单信息写入数据库这些方法的具体实现。 所以用一个抽象类 AbstractOrder 确定订单处理的逻辑,把不能确定的方法定义为抽象方法, 由子类去完成具体的实现。
public AbstractCacheContextTests extends TestCase...{
private static Map contextMap = new HashMap(); protected ConfigurableApplicationContext applicationContext;
protected abstract int getSpendingLimit(int customerId);
protected abstract int saveOrder(int customerId, int total, List orderItemList);
注意:模板方法模式中,迫使子类实现的抽象方法应该声明为 protected abstract。 6.模板方法模式与勾子方法(hookMethod) 上面讨论模板方法模式运用于一个业务对象。事实上,框架频繁使用模板方法模式,使得框 架实现对关键逻辑的集中控制。 思考这样的一个需求:我们需要为基本 Spring 的应用做一个测试类的基类,用于对类的方 法进行单元测试。我们知道 Spring 应用把需要关联的对象都定义在外部的 xml 文件中,也 称为 context。通常我们会把 context 分割成多个小的文件,以便于管理。在测试时我们需要 读取 context 文件,但是并不是每次都读取所有的文件。读取这些文件及实例化 context 中的 对象是很费时间的。所以我们想把它缓存起来,只要这个文件被读取过一次,我们就把它们 缓存起来。我们通过扩展 Junit 的 TestCase 类来定义一个测试基类。我们需要在这个基类中 实现缓存的逻辑,其它开发人员只需要实现读取配置文件的方法即可。它不用管是否具有缓 存功能。
在模板方法模式中有两个参与者进行协作。 抽象模板类:定义一个或多个抽象操作,由子类去实现。这些操作称为基本操作。 定义并实现一个具体操作,这个具体操作通过调用基本操作确定顶级逻辑。这个具体操作称 为模板方法。 具体类:实现抽象模板类所定义的抽象操作。 如上面的订单处理所示,AbstractOrder 就是抽象模板类,placeOrder 即是抽象模板方法。ge tOrderItemPrice,getSpendingLimit 和 saveOrder 三个抽象方法为基本操作。 具体子类能过需要去实现这三个抽象方法。不同的子类可能有着不同的实现方式。
Public class ConcreteOrder extends AbstractOrder...{ public int getOrderItemPrice(OrderItem orderItem)...{
//计算货物的售价 …… } public int getSpendingLimit(int customerId)...{ //读取客户的信用额度 ….. } public int saveOrder(int customerId, int total, List orderItem List)...{ //写入数据库 …… }
public abstract class AbstractOrder ...{
public Order placeOrder(int customerId , List orderItemList)...{
int total = 0;
for(int i = 0; i < orderItemList.size();i++)...{
protected boolean hasCachedContext(Object contextKey) ...{ return contextKeyToContextMap.containsKey(contextKey); } protected ConfigurableApplicationContext getContext(Object key) ...{ String keyString = contextKeyString(key); ConfigurableApplicationContext ctx = (ConfigurableApplicationContext) contextKeyToContextMap.get(keyString); if (ctx == null) ...{ if (key instanceof String[]) ...{ ctx = loadContextLocations((String[]) key); } contextKeyToContextMap.put(keyString, ctx);
}
ConcreteOrder 为 AbstractOrder 的具体子类,ConcreteOrder 需要去完成具体的三个基本操作。 同时它也具有了父类一样的处理逻辑。把具体的实现延迟到了子类去实现,这就是模板方法 模式的关键。 3.模板方法模式与控制反转 “不要给我们打电话,我们会给你打电话”这是著名的好莱坞原则。在好莱坞,把简历递交给 演艺公司后就只有回家等待。由演艺公司对整个娱乐项的完全控制,演员只能被动式的接受 公司的差使,在需要的环节中,完成自己的演出。模板方法模式充分的体现了“好莱坞”原则。 由父类完全控制着子类的逻辑,这就是控制反转。子类可以实现父类的可变部份,却继承父 类的逻辑,不能改变业务逻辑。 4.模板方法模式与开闭原则 什么是“开闭原则”? 开闭原则是指一个软件实体应该对扩展开放,对修改关闭。也就是说软件实体必须是在不被 修改的情况下被扩展。模板方法模式意图是由抽象父类控制顶级逻辑,并把基本操作的实现 推迟到子类去实现,这是通过继承的手段来达到对象的复用,同时也遵守了开闭原则。 父类通过顶级逻辑,它通过定义并提供一个具体方法来实现,我们也称之为模板方法。通常 这个模板方法才是外部对象最关心的方法。在上面的订单处理例子中,public Order placeO rder(int customerId , List orderItemList) 这个方法才是外部对象最关心的方法。所以它必须 是 public 的,才能被外部对象所调用。 子类需要继承父类去扩展父类的基本方法,但是它也可以覆写父类的方法。如果子类去覆写 了父类的模板方法,从而改变了父类控制的顶级逻辑,这违反了“开闭原则”。我们在使用模 板方法模式时,应该总是保证子类有正确的逻辑。所以模板方法应该定义为 final 的。所以 AbstractOrder 类的模板方法 placeOrder 方法应该定义为 final。
那么把它定义为 protected.否则应该为 private。 显而易见,模板方法模式中的声明为 abstract 的基本操作都是需要迫使子类去实现的,它们 仅仅是为模板方法 placeOrder 服务的。它们不应该被 AbstractOrder 所公开,所以它们应该 p rotected。
protected abstract int getOrderItemPrice(OrderItem orderIte m);
OrderItem orderItem = (OrderItem)orderItemList.get(i);
total += getOrderItemPrice(orderItem) * orderItem.getQuantity(); } if(total > getSpendingLimit(customerId))...{ throw new BusinessException(“超出信用额度” + getSpendingLimit(custo merId)); } int orderId = saveOrder(customerId, total, orderItemList); return new OrderImpl(orderId,total); } public abstract int getOrderItemPrice(OrderItem orderItem); public abstract int getSpendingLimit(int customerId);
public abstract int saveOrder(int customerId, int total, List orderItemLis t);
相关文档
最新文档