设计模式-策略模式(strategy)
4.1. 策略(Strategy)模式

抽象和一般化
把行为想成是「一族算法」。在SimUDuck的设计中,算法 代表能做的事(不同的叫法和飞行法),可以换成其它任 意的算法。 –再次注意逻辑类和工具类:工具类总是容易替换的。逻 辑类却与具体的案例有关。 –另一个理解的角度:抽象的部分与实现的部分。我们努 力把抽象的部分与实现的部分分开。 –配合其它的模式,可以可以设计出更复杂、更灵活的运 用。
策略(Strategy)模式 策略(Strategy)模式
康凯
例
一套模拟鸭子游戏:SimUDuck。游戏中出现各种Duck,鸭 子会游泳(swim) ,也会叫(quack)。
需求总是变化的
现在得让鸭子能飞
一种自然的想法
只需要在Duck类中加上fly()方法,所有Duck就都会继承 fly()。
设计原则:封装变化 设计原则:封装变化
找出应用中可能需要变化之处,把它们单独封装起来,与 不需要变化的代码隔离开。 这个原则并不仅仅是针对类而言。 几乎每个设计模式模式都体现了「系统中的某部分改变不 会影响其他部分」。
把会变化的部分取出并封装起来,以便以后可以轻易地扩 充此部分,而不影响不需要变化的其他部分。 几乎是每个设计模式背后的精神所在。所有的模式都提供 了一套方法让「系统中的某部分改变不会影响其他部分」。 架构、模块、代码。。。
继承的常见用途
基类已经实现的东西可以被派生类复用--要小心。 多态。 –部分的多态--模板等 表示传递关系。
什么时候才应当使用继承复用?
继承代表“一般化/特殊化”关系,其中基类代表一般,而 派生类代表特殊,派生类将基类特殊化或者扩展化。只有 当以下的Coad条件全部被满足时,才应当使用继承关系: 1)派生类是基类的一个特殊种类,而不是基类的一个角色, 也就是要区分“Has-A”与“Is-A”两种关系的不同。Has-A 关系应当使用聚合关系描述,而只有Is-A关系才符合继承关 系。
软件开发中的设计模式有哪些

软件开发中的设计模式有哪些在软件开发的领域中,设计模式就像是一套经过实践检验的解决方案,帮助开发者更高效、更优雅地解决常见的问题。
它们是软件开发中的宝贵经验总结,为构建可维护、可扩展和灵活的软件系统提供了有力的支持。
接下来,让我们一起探索一下软件开发中常见的设计模式。
一、创建型设计模式1、单例模式(Singleton Pattern)单例模式确保一个类只有一个实例存在,并提供一个全局访问点来获取该实例。
这在某些情况下非常有用,比如一个系统中只需要一个数据库连接池或者一个日志记录器。
想象一下,如果多个线程同时创建多个数据库连接池实例,不仅会浪费资源,还可能导致混乱。
通过单例模式,我们可以保证只有一个实例存在,有效地管理资源。
2、工厂模式(Factory Pattern)当我们需要创建对象,但又不想让客户端直接与具体的类进行交互时,工厂模式就派上用场了。
它定义了一个用于创建对象的接口,让子类决定实例化哪一个类。
比如,在一个汽车生产厂中,有不同类型的汽车(轿车、SUV 等),我们可以通过一个工厂类根据需求来创建相应类型的汽车对象,而客户端只需要向工厂请求即可,无需关心具体的创建细节。
3、抽象工厂模式(Abstract Factory Pattern)抽象工厂模式提供了一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
例如,一个家具厂可能生产多种风格的家具(现代风格、古典风格),每种风格都有配套的椅子、桌子和沙发。
通过抽象工厂模式,我们可以根据用户选择的风格创建一整套家具,保证了风格的一致性和协调性。
4、建造者模式(Builder Pattern)建造者模式将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
比如构建一个电脑配置,我们可以有不同的 CPU、内存、硬盘等组件选择,通过建造者模式,可以清晰地定义构建的步骤和顺序,同时能够灵活地组合不同的组件来创建出各种不同配置的电脑。
设计模式之策略模式浅谈以及简单例子

设计模式之策略模式浅谈以及简单例⼦设计模式之策略模式策略模式定义了算法类,分别封装起来,让他们之间可以相互替换,此模式让算法的变化独⽴于使⽤算法的客户。
策略模式是对算法的包装,是把使⽤的责任和算法本⾝分割开来,委派给不同的对象管理。
策略模式通常把⼀个系列的算法包装到⼀系列的策略类⾥⾯,作为⼀个抽象策略类的⼦类。
策略模式涉及到三个⾓⾊:环境(Context)⾓⾊:持有⼀个Strategy的引⽤,也称策略上下⽂。
抽象策略(Strategy)⾓⾊:这是⼀个抽象⾓⾊,通常使⽤抽象类或者接⼝来实现。
此⾓⾊给出所有的具体策略类所需要的接⼝。
具体策略(ConcreteStrategy)⾓⾊:此⾓⾊包装了所有的算法和⾏为。
Eg:商场搞促销,促销⽅式有打折、满100减50等。
在本例中,抽象策略⾓⾊⽤⼀个结果实现,接⼝中有⼀个计算价格的⽅法。
接⼝实现如下:1namespace Strategy_Pattern23 {45///<summary>67///策略接⼝89///</summary>1011interface IPromotion1213 {1415///<summary>1617///根据原价和策略计算新价格1819///</summary>2021///<param name="originalPrice">原价</param>2223///<returns></returns>2425double GetPrice(double originalPrice);2627 }2829 }具体策略⾓⾊有两个,分别表⽰打折类和满100减50,都实现策略接⼝。
打折类实现如下:1 using System;2345 namespace Strategy_Pattern67 {89 /// <summary>1011 /// 打折策略类1213 /// </summary>1415 class Discount : IPromotion1617 {181920212223 #region Public Methods2425 public double GetPrice(double originalPrice) 2627 {2829 Console.WriteLine("打⼋折");3031 return originalPrice * 0.8;3233 }3435 #endregion36373839 }4041 }满100减50类实现如下:/// <summary>/// 返现策略类:满100返50/// </summary>class MoneyBack : IPromotion{#region Public Methodspublic double GetPrice(double originalPrice){Console.WriteLine("满100返50");return originalPrice - (int)originalPrice / 100 - 50; }#endregion}环境(Context)⾓⾊类如下:/// <summary>/// 策略上下⽂类/// </summary>class PromotionContext{#region Fieldsprivate IPromotion m_promotion = null;#endregion#region Constructorspublic PromotionContext(IPromotion iPromotion){this.m_promotion = iPromotion;}#endregion#region Public Methods/// <summary>/// 默认策略⽅法/// </summary>/// <param name="originalPrice"></param>/// <returns></returns>public double GetPrice(double originalPrice){if (this.m_promotion == null){this.m_promotion = new Discount();}return this.m_promotion.GetPrice(originalPrice);}/// <summary>/// 更改策略的⽅法/// </summary>/// <param name="iPromotion"></param>public void ChangePromotion(IPromotion iPromotion){this.m_promotion = iPromotion;}#endregion}然后再主类中调⽤相应的策略,主类实现如下:class Program{static void Main(string[] args){//默认策略:打⼋折的策略PromotionContext promotionContext=new PromotionContext(null);Console.WriteLine(promotionContext.GetPrice(300));//更改策略:满100减50的策略promotionContext.ChangePromotion(new MoneyBack()); Console.WriteLine(promotionContext.GetPrice(100));Console.ReadLine();}}。
设计模式Strategy_策略模式

Strategy(策略模式)Strategy(策略模式)属于行为型模式。
意图:定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换。
本模式使得算法可以独立于使用它的客户而变化。
策略是个形象的表述,所谓策略就是方案,我们都知道任何事情都有多种方案,而且不同方案都能解决问题,所以这些方案可以相互替换。
我们将方案从问题中抽象出来,这样就可以抛开问题,单独优化方案了,这就是策略模式的核心思想。
举例子如果看不懂上面的意图介绍,没有关系,设计模式需要在日常工作里用起来,结合例子可以加深你的理解,下面我准备了三个例子,让你体会什么场景下会用到这种设计模式。
地图导航我们去任何地方都可以选择步行、骑车、开车、公交,不同的方案都可以帮助我们到达目的地,那么很明显应该将这些方案变成策略封装起来,接收的都是出发点和目的地,输出的都是路线。
布局方式比如我们做一个报表系统,在 PC 使用珊格布局,在移动端使用流式布局,其实内容还是那些,只是布局方式会随着不同终端大小做不同的适配,那么布局的适配就是一种策略,它可以与报表内容无关。
我们可以将布局策略单独抽取出来,以后甚至可以适配电视机、投影仪等等不同尺寸的场景,而不需要对其他代码做任何改动,这就是将布局策略从代码中解耦出来的好处。
排序算法当我们调用.sort时,使用的是什么排序算法?可能是冒泡、快速、插入排序?其实无论何种排序算法,本质上做的事情都是一样的,我们可以事先将排序算法封装起来,针对不同特性的数组调用不同的排序算法。
意图解释意图:定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换。
本模式使得算法可以独立于使用它的客户而变化。
算法可以理解为策略,我们制定许多解决某个场景的策略,这些策略都可以独立的解决这个场景的问题,这样下次遇到这个场景时,我们就可以选择任何策略来解决,而且我们还可以脱离场景,单独优化策略,只要接口不变即可。
这个意图本质上就是解耦,解耦之后才可以分工。
设计模式习题

设计模式习题一、模式(Pattern)定义策略模式(Strategy)定义:策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。
策略模式让算法独立于使用它的客户而独立变化。
类图:Context(适用性):1) 需要使用ConcreteStrategy提供的算法。
2) 内部维护一个Strategy的实例。
3) 负责动态设置运行时Strategy具体的实现算法。
4) 负责跟Strategy之间的交互和数据传递。
Strategy(抽象策略类):定义了一个公共接口,各种不同的算法以不同的方式实现这个接口,Context使用这个接口调用不同的算法,一般使用接口或抽象类实现。
ConcreteStrategy(具体策略类):实现了Strategy定义的接口,提供具体的算法实现。
适用性:对于Strategy模式来说,主要有这些适用性:1、多个类只区别在表现行为不同,可以使用Strategy模式,在运行时动态选择具体要执行的行为。
(例如FlyBehavior和QuackBehavior)2、需要在不同情况下使用不同的策略(算法),或者策略还可能在未来用其它方式来实现。
(例如FlyBehavior和QuackBehavior的具体实现可任意变化或扩充)3、对客户(Duck)隐藏具体策略(算法)的实现细节,彼此完全独立。
策略模式顺序图:1.观察者模式(Observer Pattern)定义:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新。
类图:P52 主要解决问题:l 当一个抽象模型有两个方面的,其中一个方面依赖与另一个方面。
l 当一个对象的改变需要同时改变其他对象,而不知道具体有多对象有待改变l 当一个对象必须通知其他对象,而它又不能假定其他对象是谁。
生活中的例子:观察者定义了对象间一对多的关系,当一个对象的状态变化时,所有依赖它的对象都得到通知并且自动地更新。
设计模式中的多态——策略模式详解

设计模式中的多态——策略模式详解⽬录策略模式和java语⾔的多态特性有些像。
java的多态特性允许我们⾯向接⼝编程,不⽤关⼼接⼝的具体实现。
接⼝所指向的实现类,以及通过接⼝调⽤的⽅法的具体⾏为可以到运⾏时才绑定。
这么做最⼤的好处是在尽可能实现代码复⽤的前提下更好地应对具体实现类的变化。
⽐如我想增加⼀种接⼝的实现或者修改原有实现类的某个⾏为,那我⼏乎不⽤修改任何客户端代码。
策略模式可以说正是这种思想在设计模式上的运⽤。
它可以使我们更好的复⽤代码,同时使程序结构设计更有弹性,更好的应对变化。
2. 策略模式详解2.1 策略模式定义策略模式定义了⼀系列算法,并将每⼀个算法封装起来,⽽且使它们还可以相互替换。
策略模式让算法独⽴于使⽤它的客户端⽽独⽴的变化。
可以使⽤多态进⾏类⽐来理解策略模式的定义。
⼀系列算法可以理解成接⼝的不同实现类,因为不同实现类都实现了相同的接⼝,因⽽它们也可以相互替换。
策略模式让算法独⽴于客户端⽽变化与接⼝的实现类可以独⽴于使⽤接⼝的客户端变化类似。
2.2 策略模式的UML类图从UML类图上可以看出,策略模式中主要有3个⾓⾊抽象策略接⼝上图中的Strategy即抽象策略接⼝,接⼝中定义了抽象的策略算法algorithm()。
具体的策略实现类上图中的StrategyA和StrategyB即具体的策略实现。
不同的策略实现类都实现了抽象策略接⼝,并重写了其抽象策略⽅法。
因为都实现了相同的策略接⼝,因⽽算法可以相互替换,并且可以动态的改变具体的算法实现。
封装策略的上下⽂环境上图中的Context即策略的上下⽂环境。
它屏蔽了⾼层模块对策略算法的直接访问,封装了可能存在的变化。
⽽且提供了修改Strategy的setter⽅法,可以动态的改变算法的具体实现。
3.策略模式的优点我们可以结合使⽤策略模式的例⼦并与其它实现⽅案进⾏对⽐来看看策略模式到底有什么好处3.1 ⼀个使⽤策略模式的例⼦定义⼀个汽车类Car。
软件工程Strategy策略模式
strategy 策略行为型设计模式摘要:Strategy是属于设计模式中对象行为型模式,主要定义一系列的算法,把这些算法一个个封装成单独的类,并且使这些类可以相互替换,以达到能够使得算法的变化可独立于使用它的客户的目的。
关键字:设计模式,定义算法,封装引言:Strategy应用比较广泛,比如,公司经营业务变化图,可能有两种实现方式,一种是线条曲线,另一种是框图(bar),这两种算法可以使用Strategy实现。
还有一些使用如:Context,印刷图书,Strategy,使用某种技术的印刷设备,Algorithem,具体的印刷技术,如喷墨,胶印,IStrategy,印刷正文:行为型模式:1.职责链模式 Chain of Responsibility2.命令模式 Command3.解释器模式 Interpreter4.迭代器模式 Iterator5.中介者模式 Mediator6.备忘录模式 Memento7.观察者模式 Observer8.状态模式 State9.策略模式 Strategy10.模板方法模式 Template Method11.访问者模式 Visitor1.职责链模式Chain of Responsibility职责链模式使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。
将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
“击鼓传球”游戏就是职责链模式的一种应用,鼓起,球从人手中传递,鼓落,拿球的人要做某件事。
命令模式Command命令模式将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;可以对请求排队或记录请求日志,以及支持可撤销的操作。
命令模式是对“行为的请求者”和“行为的实现者”进行了解耦。
Invoker对象可以在不同的时刻指定、排列、执行操作,支持取消、重做的操作,支持事务,记录操作的日志.解释器模式Interpreter解释器模式,给定一个语言,定义它的问法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。
23种设计模式 详解
23种设计模式详解设计模式是指面向对象编程中,经过多次验证、被广泛接受的代码实现方法。
这些设计模式可以帮助开发者更快地解决问题,提高代码的可读性、可维护性、可扩展性。
目前,常用的设计模式有23种。
下面,我们来详细介绍一下这23种设计模式。
1. 单例模式(Singleton)单例模式是一种只允许生成一个实例的模式。
在实例化对象时,单例模式的生成过程比较特殊,需要先判断该类是否已经实例化过,如果已经实例化,则直接返回已有的实例对象,否则再进行实例化。
2. 工厂模式(Factory)工厂模式是一种生产对象实例的设计模式。
它将对象实例的生成过程封装在一个工厂类中,客户端需要对象时,只需要调用工厂类中对应的方法即可。
3. 抽象工厂模式(Abstract Factory)抽象工厂模式是一种扩展了工厂模式的模式。
它可以生成一系列相关或相互依赖的对象实例。
具体实现时,通常需要定义一个抽象工厂类和一些具体工厂类,来生产各种相关的对象实例。
4. 建造者模式(Builder)建造者模式是一种用于构建复杂对象的模式。
它将一个复杂对象的构建过程分解成多个简单的步骤,然后通过一个指挥者来管理这些步骤的执行,最终构建出一个复杂的对象。
5. 原型模式(Prototype)原型模式是一种通过复制已有对象来创建新对象的模式。
一般来说,系统中的对象包含大量相同或相似的部分,通过复制对象可以帮助我们节省生成对象的时间和资源。
6. 适配器模式(Adapter)适配器模式是一种将不兼容接口转换为兼容接口的模式。
具体实现时,需要定义一个适配器类,该类实现了客户端所期望的接口,而且还包装了原有不兼容的接口,使其能够兼容客户端期望的接口。
7. 桥接模式(Bridge)桥接模式是一种将抽象部分与其实现部分分离开来的模式。
具体实现时,需要定义抽象部分和实现部分的接口,然后定义一个桥接类,将抽象部分和实现部分联系起来。
8. 组合模式(Composite)组合模式是一种将具有相同属性和方法的对象组合成树形结构的模式。
浅谈游戏开发中常见的设计模式
浅谈游戏开发中常见的设计模式前⾔ 因为游戏开发在架构上要考虑性能和实际需求,在尽量不引⼊第三⽅库、框架的前提下进⾏开发,所以在编码时候会经常⽤到设计模式对代码进⾏复⽤,对业务逻辑架构解耦,尽量减少hard code。
单例模式(Singleton Pattern)单例模式经常会⽤在逻辑上唯⼀的对象(通常⽤于重量级资源)上,如Factory、Context、Resource、Pool和Service等,但在代码细节上需要注意开放出去的接⼝以及该接⼝的严格语义。
单例模式通常带有⽣命周期函数,有利于结合框架⾃⼰的⽣命周期管理进⾏初始化或销毁操作。
在开发过程中会遇到⼀些不好的例⼦,如变量都是类静态成员变量、⽅法都是静态⽅法,这样写的代码可能在调⽤上的结果符合“单例”这个语义,但是会让其他⼈感到困惑。
⼯⼚模式(Factory Pattern)使⽤⼯⼚模式来统⼀创建对象有利于管理对象的⽣命周期,通常会组合单例模式、代理模式、策略模式,对复杂的对象进⾏组装,对创建的对象进⾏统⼀管理。
统⼀对象⼊⼝的好处在开发初期可能不明显,但随着开发进度的推动,业务的越来越复杂,统⼀⼊⼝容易更好地跟踪对象的⽣命周期,也容易的对某类对象初始化时进⾏统⼀的操作。
策略模式(Strategy Pattern)对于⼀些逻辑相似但实现的细节不同粒度⼜⽐较细的业务,可以将保证语义粒度适中的接⼝提取出来,按不同的实现逻辑来封装成不同的策略,在通过策略容器(通常是⼯⼚容器)在上层业务中进⾏组合调⽤。
这样既可以保证逻辑结构的清晰⼜便于扩展。
在游戏开发中,状态机就是⼀个使⽤策略模式的例⼦,状态机本⾝就是⼀个策略容器,它将与状态相关的⾏为从⼤量的跳转中抽离处理,让代码结构更清晰明了。
代码结构越清晰,跳转越少意味着出现BUG机率越低,调试起来更容易。
个⼈觉得策略模式的关注点应该在接⼝的粒度上,它跟代理模式不同,要求粒度适中,根据具体的业务去动态选择策略使得封装的代码脱离于客户代码。
23种设计模式的经典运用
23种设计模式的经典运用介绍设计模式是解决软件设计中常见问题的可重复使用的解决方案。
本文将介绍23种经典的设计模式,并给出它们在实际开发中的应用示例。
通过学习这些设计模式,您将增加对软件设计的理解,并能够更好地解决问题。
创建型设计模式1.工厂方法模式(F a c t o r y M e t h o d)工厂方法模式通过定义一个创建对象的接口,但由子类决定实例化具体类。
这种方法可以延迟实例化过程,具有更高的灵活性和可扩展性。
应用场景:-在一个系统中,希望客户端与具体类的实例化解耦。
-希望通过增加具体类的扩展来增加系统的灵活性。
2.抽象工厂模式(A b s t r a c t F a c t o r y)抽象工厂模式提供一个接口,用于创建相关或依赖对象组。
这种模式将对象的实例化推迟到子类中,从而实现了解耦。
应用场景:-当一个系统独立于其产品的创建、组合和表示时。
-当需要一个系列的相互依赖的对象而无需指定其具体类时。
3.单例模式(S i n gl e t o n)单例模式确保一个类只有一个实例,并提供一个全局访问点。
这种模式常用于控制对资源的访问,例如数据库连接或日志文件。
应用场景:-当需要一个类的唯一实例,并且该实例需要被多个客户端共享时。
-当需要限制系统中特定类的实例数量时。
4.原型模式(P r o to t y p e)原型模式通过复制现有对象来创建新对象。
这种模式对于创建需要消耗大量资源的对象非常有用,可以通过克隆现有对象来提高性能。
应用场景:-当一个系统的某些对象的创建比较昂贵时。
-当需要避免构造函数调用,而直接通过复制现有对象来创建新对象时。
5.建造者模式(B ui l d e r)建造者模式将一个复杂对象的构建过程与其表现分离,使得相同的构建过程可以创建不同的表现。
应用场景:-当想要构建一些复杂对象时,如生成器。
-当需要创建对象的过程具有多个步骤,并且每个步骤都可以按需选择或省略时。
结构型设计模式6.适配器模式(A da p t e r)适配器模式将一个类的接口转换为客户端所期望的另一个接口。