设计模式-策略模式(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)适配器模式将一个类的接口转换为客户端所期望的另一个接口。
软件设计常见的23种设计模式
软件设计常见的23种设计模式 在现代软件开发当中,设计模式起到⾄关重要的作⽤。
尤其是⾃从⾯向对象的语⾔普遍使⽤以后,促成了团队合作设计的热潮,⽽在此时,没有⼀个好的设计模式,软件设计⼏乎成了不可能完成的任务。
⼀般模式有4个基本要素:模式名称(pattern name)、问题(problem)、解决⽅案(solution)、效果(consequences)。
常见23种模式概述: 1)抽象⼯⼚模式(Abstract Factory):提供⼀个创建⼀系列相关或相互依赖对象的接⼝,⽽⽆需指定它们具体的类。
2)适配器模式(Adapter):将⼀个类的接⼝转换成客户希望的另外⼀个接⼝。
适配器模式使得原本由于接⼝不兼容⽽不能⼀起⼯作的类可以⼀起⼯作。
3)桥梁模式(Bridge):将抽象部分与它的实现部分分离,使它们都可以独⽴地变化。
4)建造模式(Builder):将⼀个复杂对象的构建与它的表⽰分离,使同样的构建过程可以创建不同的表⽰。
5)责任链模式(Chain of Responsibility):为解除请求的发送者和接收者之间耦合,⽽使多个对象都有机会处理这个请求。
将这些对象连成⼀条链,并沿着这条链传递该请求,直到有⼀个对象处理它。
6)命令模式(Command):将⼀个请求封装为⼀个对象,从⽽可⽤不同的请求对客户进⾏参数化;对请求排队或记录请求⽇志,以及⽀持可取消的操作。
7)合成模式(Composite):将对象组合成树形结构以表⽰“部分-整体”的层次结构。
它使得客户对单个对象和复合对象的使⽤具有⼀致性。
8)装饰模式(Decorator):动态地给⼀个对象添加⼀些额外的职责。
就扩展功能⽽⾔,它能⽣成⼦类的⽅式更为灵活。
9)门⾯模式(Facade):为⼦系统中的⼀组接⼝提供⼀个⼀致的界⾯,门⾯模式定义了⼀个⾼层接⼝,这个接⼝使得这⼀⼦系统更加容易使⽤。
10)⼯⼚⽅法(Factory Method):定义⼀个⽤于创建对象的接⼝,让⼦类决定将哪⼀个类实例化。
23种设计模式总结
23种设计模式总结设计模式是一种解决反复出现的设计问题的方案,它们被广泛应用于软件设计和架构中。
在这里,我们列举了23种常用的设计模式,分别属于创建型、结构型和行为型模式。
一、创建型模式1. 工厂方法模式(Factory Method Pattern)定义一个创建对象的接口,但让子类决定实例化哪个类。
工厂方法模式是让类来进行对象的创建,而不是由你的代码直接new 出来。
2. 抽象工厂模式(Abstract Factory Pattern)提供一个接口,用于创建一系列相关或相互依赖的对象。
3. 单例模式(Singleton Pattern)确保一个类只有一个实例,并提供一个全局访问点。
4. 建造者模式(Builder Pattern)将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
5. 原型模式(Prototype Pattern)用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。
二、结构型模式6. 适配器模式(Adapter Pattern)将一个类的接口转换成客户希望的另外一个接口。
适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作。
7. 桥接模式(Bridge Pattern)将抽象部分与它的实现部分分离,使它们都可以独立地变化。
8. 组合模式(Composite Pattern)将对象组合成树形结构以表示“部分-整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性。
9. 装饰器模式(Decorator Pattern)动态地给一个对象添加一些额外的职责,就增加功能来说,装饰器比生成子类更为灵活。
10. 外观模式(Facade Pattern)为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,使得这一子系统更加容易使用。
11. 享元模式(Flyweight Pattern)运用共享技术有效地支持大量细粒度的对象。
strategy 策略模式
3
为什么我们要使用设计模式?
• 设计模式帮助你从别人的成功经验而不是你自己的失 败那里学到更多东西 ;------- Mark Johnson • 设计模式提供了一种共享经验的方式,可以使团体• 面向接口编程的原则
– 面向接口编程,而不是面向实现编程。
Duck Behaviors
从Duck类中分离出这些行为, 我们将抽取所有duck类的行为 并创建相应的类来负责各自的 行为。
17
设计原则:面向接口编程,而非面向实现编程
我们将怎么样设计那组实现了飞行和呷呷叫行为的类呢? OK,我们再来看一个设计原则 从现在起,鸭子的行为将被 封装在被分离的类中,一个 类实现一个具体行为接口。
这是我们将要涉及到的众多设计原则中的第一个原则。 以后还有更多原则会陆续出现。
15
Identify the aspects of your application that vary and separate them from what stays the same. 识别在程序中的那些多变的特征,并且把它 们和稳定的特征分离开来
• 可变性封装的原则
– 在设计时应当考虑系统中什么可能会发生变化,或者什么特性具 备多变的特征。这种变化不应该散落在代码中的各个角落,而是 应该被适当的封装起来,以便于维护以及扩展;
• 开-闭原则
– 软件中的实体(包括类,模块,函数等等)应当是可扩展的 (开),而不应被修改(闭)。
• 里氏替换原则
– 子类可以扩展父类的功能,但不能改变父类原有的功能。 – 所有引用基类的地方必须能透明地使用其子类的对象.
Program to interface, not an implementation.
设计模式之策略模式详细介绍
设计模式之策略模式详细介绍嘿,大家好,今天咱们聊聊一个超级实用的设计模式——策略模式。
别担心,听起来复杂,但其实它就像生活中的调味料,适时加点,味道立马就不一样了!那么,什么是策略模式呢?简单来说,就是把算法封装起来,让它们可以互相替换,简直就是为程序设计量身定做的灵活性!1. 策略模式的基本概念1.1 策略模式的定义首先,咱们得搞明白什么是策略模式。
想象一下,你去餐馆点菜,菜单上有各种各样的选择,你可以根据自己的口味、心情甚至天气来决定。
策略模式就像这个菜单,让你可以在运行时自由选择用什么“策略”来完成任务。
也就是说,把实现某个功能的具体方法放在不同的策略类中,这样用的时候只要挑一个就行,省时省力,简单明了!1.2 策略模式的构成在策略模式中,主要有三个角色:环境(Context)、策略接口(Strategy)和具体策略(ConcreteStrategy)。
环境就像你去餐馆的服务员,策略接口就像菜单上所有的菜名,而具体策略就是菜品的具体做法。
比如,你要点一个“红烧肉”,那“红烧肉”的具体做法就是“具体策略”,而“红烧肉”这个名字就是“策略接口”。
哎呀,听起来是不是感觉肚子饿了呢?2. 策略模式的优缺点2.1 策略模式的优点说到优点,策略模式简直就是如鱼得水,优势多多。
首先,它提高了代码的灵活性和可读性。
你可以很方便地添加新的策略而不影响现有的代码,简直就像给你的程序加了新菜单一样!其次,策略模式能有效地减少条件语句,避免了“ifelse”地狱。
谁还想每天面对成堆的条件判断,真是烦死人了。
2.2 策略模式的缺点当然,策略模式也不是完美无瑕的,缺点也得提一提。
首先,策略类的数量可能会暴涨,管理起来就像打理一堆杂乱的花园,容易让人头疼。
其次,使用策略模式可能会增加系统的复杂性,特别是当策略类和环境类的关系比较复杂时。
就像有时候你不太确定自己点的是什么菜,搞得一头雾水。
3. 策略模式的应用场景3.1 策略模式在电商中的应用接下来,咱们聊聊策略模式在实际开发中的应用吧!以电商网站为例,购物车的计算就可以用策略模式来处理。
策略(Strategy)模式
设计模式(22)-Strategy Pattern一、策略(Strategy)模式策略模式的用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。
策略模式使得算法可以在不影响到客户端的情况下发生变化。
假设现在要设计一个贩卖各类书籍的电子商务网站的购物车(Shopping Cat)系统。
一个最简单的情况就是把所有货品的单价乘上数量,但是实际情况肯定比这要复杂。
比如,本网站可能对所有的教材类图书实行每本一元的折扣;对连环画类图书提供每本7%的促销折扣,而对非教材类的计算机图书有3%的折扣;对其余的图书没有折扣。
由于有这样复杂的折扣算法,使得价格计算问题需要系统地解决。
使用策略模式可以把行为和环境分割开来。
环境类负责维持和查询行为类,各种算法则在具体策略类(ConcreteStrategy)中提供。
由于算法和环境独立开来,算法的增减、修改都不会影响环境和客户端。
当出现新的促销折扣或现有的折扣政策出现变化时,只需要实现新的策略类,并在客户端登记即可。
策略模式相当于"可插入式(Pluggable)的算法"。
二、策略模式的结构策略模式是对算法的包装,是把使用算法的责任和算法本身分割开,委派给不同的对象管理。
策略模式通常把一个系列的算法包装到一系列的策略类里面,作为一个抽象策略类的子类。
用一句话来说,就是:"准备一组算法,并将每一个算法封装起来,使得它们可以互换。
"策略又称做政策(Policy)模式【GOF95】。
下面是一个示意性的策略模式结构图:这个模式涉及到三个角色:1.环境(Context)角色:持有一个Strategy类的引用。
2.抽象策略(Strategy)角色:这是一个抽象角色,通常由一个接口或抽象类实现。
此角色给出所有的具体策略类所需的接口。
3.具体策略(ConcreteStrategy)角色:包装了相关的算法或行为。
三、示意性源代码// pattern using System;//abstract{}//class{}//class{}//class{}//class{strategy;}}public{Context(c.ContextInterface();Context(d.ContextInterface();}四、何时使用何种具体策略角色在学习策略模式时,学员常问的一个问题是:为什么不能从策略模式中看出哪一个具体策略适用于哪一种情况呢?答案非常简单,策略模式并不负责做这个决定。
软件设计常见的23种设计模式
软件设计常见的23种设计模式 在现代软件开发当中,设计模式起到⾄关重要的作⽤。
尤其是⾃从⾯向对象的语⾔普遍使⽤以后,促成了团队合作设计的热潮,⽽在此时,没有⼀个好的设计模式,软件设计⼏乎成了不可能完成的任务。
⼀般模式有4个基本要素:模式名称(pattern name)、问题(problem)、解决⽅案(solution)、效果(consequences)。
常见23种模式概述: 1)抽象⼯⼚模式(Abstract Factory):提供⼀个创建⼀系列相关或相互依赖对象的接⼝,⽽⽆需指定它们具体的类。
2)适配器模式(Adapter):将⼀个类的接⼝转换成客户希望的另外⼀个接⼝。
适配器模式使得原本由于接⼝不兼容⽽不能⼀起⼯作的类可以⼀起⼯作。
3)桥梁模式(Bridge):将抽象部分与它的实现部分分离,使它们都可以独⽴地变化。
4)建造模式(Builder):将⼀个复杂对象的构建与它的表⽰分离,使同样的构建过程可以创建不同的表⽰。
5)责任链模式(Chain of Responsibility):为解除请求的发送者和接收者之间耦合,⽽使多个对象都有机会处理这个请求。
将这些对象连成⼀条链,并沿着这条链传递该请求,直到有⼀个对象处理它。
6)命令模式(Command):将⼀个请求封装为⼀个对象,从⽽可⽤不同的请求对客户进⾏参数化;对请求排队或记录请求⽇志,以及⽀持可取消的操作。
7)合成模式(Composite):将对象组合成树形结构以表⽰“部分-整体”的层次结构。
它使得客户对单个对象和复合对象的使⽤具有⼀致性。
8)装饰模式(Decorator):动态地给⼀个对象添加⼀些额外的职责。
就扩展功能⽽⾔,它能⽣成⼦类的⽅式更为灵活。
9)门⾯模式(Facade):为⼦系统中的⼀组接⼝提供⼀个⼀致的界⾯,门⾯模式定义了⼀个⾼层接⼝,这个接⼝使得这⼀⼦系统更加容易使⽤。
10)⼯⼚⽅法(Factory Method):定义⼀个⽤于创建对象的接⼝,让⼦类决定将哪⼀个类实例化。
软件设计常见的23种设计模式
软件设计常见的23种设计模式 在现代软件开发当中,设计模式起到⾄关重要的作⽤。
尤其是⾃从⾯向对象的语⾔普遍使⽤以后,促成了团队合作设计的热潮,⽽在此时,没有⼀个好的设计模式,软件设计⼏乎成了不可能完成的任务。
⼀般模式有4个基本要素:模式名称(pattern name)、问题(problem)、解决⽅案(solution)、效果(consequences)。
常见23种模式概述: 1)抽象⼯⼚模式(Abstract Factory):提供⼀个创建⼀系列相关或相互依赖对象的接⼝,⽽⽆需指定它们具体的类。
2)适配器模式(Adapter):将⼀个类的接⼝转换成客户希望的另外⼀个接⼝。
适配器模式使得原本由于接⼝不兼容⽽不能⼀起⼯作的类可以⼀起⼯作。
3)桥梁模式(Bridge):将抽象部分与它的实现部分分离,使它们都可以独⽴地变化。
4)建造模式(Builder):将⼀个复杂对象的构建与它的表⽰分离,使同样的构建过程可以创建不同的表⽰。
5)责任链模式(Chain of Responsibility):为解除请求的发送者和接收者之间耦合,⽽使多个对象都有机会处理这个请求。
将这些对象连成⼀条链,并沿着这条链传递该请求,直到有⼀个对象处理它。
6)命令模式(Command):将⼀个请求封装为⼀个对象,从⽽可⽤不同的请求对客户进⾏参数化;对请求排队或记录请求⽇志,以及⽀持可取消的操作。
7)合成模式(Composite):将对象组合成树形结构以表⽰“部分-整体”的层次结构。
它使得客户对单个对象和复合对象的使⽤具有⼀致性。
8)装饰模式(Decorator):动态地给⼀个对象添加⼀些额外的职责。
就扩展功能⽽⾔,它能⽣成⼦类的⽅式更为灵活。
9)门⾯模式(Facade):为⼦系统中的⼀组接⼝提供⼀个⼀致的界⾯,门⾯模式定义了⼀个⾼层接⼝,这个接⼝使得这⼀⼦系统更加容易使⽤。
10)⼯⼚⽅法(Factory Method):定义⼀个⽤于创建对象的接⼝,让⼦类决定将哪⼀个类实例化。
设计模式之策略模式(Strategy)详解及代码示例
设计模式之策略模式(Strategy)详解及代码⽰例⼀、策略模式的定义 策略(Strategy)模式的定义:该模式定义了⼀系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使⽤算法的客户。
策略模式属于对象⾏为模式,它通过对算法进⾏封装,把使⽤算法的责任和算法的实现分割开来,并委派给不同的对象对这些算法进⾏管理。
⼆、策略模式优缺点 策略模式的主要优点如下。
多重条件语句不易维护,⽽使⽤策略模式可以避免使⽤多重条件转移语句。
符合开闭原则,可以在不修改原代码的情况下,灵活增加新算法。
算法使⽤和实现隔离分离,提⾼算法的保密性和安全性。
策略模式提供了⼀系列的可供重⽤的算法族,恰当使⽤继承可以把算法族的公共代码转移到⽗类⾥⾯,从⽽避免重复的代码。
策略模式可以提供相同⾏为的不同实现,客户可以根据不同时间或空间要求选择不同的。
其主要缺点如下。
客户端必须理解所有策略算法的区别,以便适时选择恰当的算法类。
策略模式造成很多的策略类。
三、策略模式的结构与实现 策略模式是准备⼀组算法,并将这组算法封装到⼀系列的策略类⾥⾯,作为⼀个抽象策略类的⼦类。
策略模式的重⼼不是如何实现算法,⽽是如何组织这些算法,从⽽让程序结构更加灵活,具有更好的维护性和扩展性,现在我们来分析其基本结构和实现⽅法。
策略模式的主要⾓⾊如下。
抽象策略(Strategy)类:定义了⼀个公共接⼝,各种不同的算法以不同的⽅式实现这个接⼝,环境⾓⾊使⽤这个接⼝调⽤不同的算法,⼀般使⽤接⼝或抽象类实现。
具体策略(Concrete Strategy)类:实现了抽象策略定义的接⼝,提供具体的算法实现。
环境(Context)类:持有⼀个策略类的引⽤,最终给客户端调⽤。
其结构图如图所⽰: 代码实现如下:public class StrategyPattern{public static void main(String[] args){Context c=new Context();Strategy s=new ConcreteStrategyA();c.setStrategy(s);c.strategyMethod();System.out.println("-----------------");s=new ConcreteStrategyB();c.setStrategy(s);c.strategyMethod();}}//抽象策略类interface Strategy{public void strategyMethod(); //策略⽅法}//具体策略类Aclass ConcreteStrategyA implements Strategy{public void strategyMethod(){System.out.println("具体策略A的策略⽅法被访问!");}}//具体策略类Bclass ConcreteStrategyB implements Strategy{public void strategyMethod(){System.out.println("具体策略B的策略⽅法被访问!");}}//环境类class Context{private Strategy strategy;public Strategy getStrategy(){return strategy;}public void setStrategy(Strategy strategy){this.strategy=strategy;}public void strategyMethod(){strategy.strategyMethod();}} 测试结果如下:具体策略A的策略⽅法被访问!-----------------具体策略B的策略⽅法被访问! 如下补充⼀个促销策略模式:interface PromotionStrategy {void doPromotion();}class FanXianPromotionStrategy implements PromotionStrategy{@Overridepublic void doPromotion() {System.out.println("返现促销");}}class LiJianPromotionStrategy implements PromotionStrategy {@Overridepublic void doPromotion() {System.out.println("⽴减促销");}}class ManJianPromotionStrategy implements PromotionStrategy{@Overridepublic void doPromotion() {System.out.println("满减促销");}}class PromotionActivity {private PromotionStrategy promotionStrategy;public PromotionActivity(PromotionStrategy promotionStrategy) {this.promotionStrategy = promotionStrategy;}public void executePromotionStrategy(){promotionStrategy.doPromotion();}}public class Test {public static void main(String[] args) {PromotionActivity promotionActivity618 = new PromotionActivity(new LiJianPromotionStrategy());PromotionActivity promotionActivity1111 = new PromotionActivity(new FanXianPromotionStrategy());promotionActivity618.executePromotionStrategy();promotionActivity1111.executePromotionStrategy();}}四、策略模式的应⽤场景 策略模式在很多地⽅⽤到,如 Java SE 中的容器布局管理就是⼀个典型的实例,Java SE 中的每个容器都存在多种布局供⽤户选择。
JS设计模式——策略模式
JS设计模式——策略模式设计模式⾼⼤上,业务代码⽤不上...平时⽤不上我们就可以忽略了吗?⾮也,就像⾯试造⽕箭,⼯作拧螺丝⼀样。
万⼀我们公司哪天要造⽕箭了,你得⽴马能上⼿。
同时,有些复杂的业务代码也可以⽤设计模式的思想去写,如果你对设计模式不了解,到时怎么会想到呢?那你写出来的代码怕是很难去阅读和维护。
说了那么多,就是想说⼀点:设计模式很棒!你可以不⽤,但不能不会!下⾯来聊聊策略模式:策略模式的定义何为策略?⽐如我们要去西藏旅游,可以根据⾃⾝的实际情况来选择出⾏的路线。
如果没有时间但是不在乎钱,可以选择坐飞机。
如果没有钱,时间还算充⾜,可以选择坐⽕车。
如果再穷⼀点,时间充⾜,可以选择骑⾏。
在程序设计中,我们也常常遇到类似的情况,要实现某⼀个功能有多种选择⽅案。
⽐如⼀个压缩⽂件的程序,你可以根据⾃⼰的需求选择zip算法或者gzip算法。
定义:策略模式定义⼀系列的算法,分别封装起来,让他们之间可以相互替换,此模式让算法的变化独⽴于使⽤算法的客户。
废话不多说,下⾯直接show code...年终奖实例年底了,⼜到了发年终奖的时候。
有些公司的年终奖根据员⼯的⼯资基数和绩效等级来发放的。
例如,绩效为A的⼈年终奖有4倍⼯资,绩效为B的有3倍,绩效为C的只有2倍。
假如财务部要求我们提供⼀段代码来实现这个核算逻辑,我们要怎么实现呢?初级-⼀个函数搞定这不是很简单嘛,写⼀个函数,传⼊⼯资基数和绩效等级,返回最终计算的奖⾦。
代码如下:var calculateBonus = function( performanceLevel, salary ){if ( performanceLevel === 'A' ){return salary * 4;}if ( performanceLevel === 'B' ){return salary * 3;}if ( performanceLevel === 'C' ){return salary * 2;}};calculateBonus( 'B', 20000 ); // 输出:40000calculateBonus( 'S', 6000 ); // 输出:24000可以发现,这段代码⼗分简单,但是存在着明显的缺点:calculateBonus函数⽐较庞⼤,包含了很多if-else语句,这些语句需要覆盖所有的逻辑分⽀。
strategycontext 策略模式
strategycontext 策略模式策略模式(Strategy Pattern)是一种行为设计模式,它允许你在运行时更改对象的行为。
策略模式定义了一系列算法,并将每个算法封装起来,使它们可以互相替换。
策略模式让算法独立于使用它的客户端。
在策略模式中,通常有一个策略接口或抽象类,定义了所有支持的策略应实现的共同接口。
然后,具体策略类实现了这个接口或抽象类,提供了不同的算法或行为。
StrategyContext(策略上下文)通常是使用策略模式的客户端代码中的一个类,它负责根据当前情境或需求来选择和使用合适的策略。
StrategyContext通常持有一个对策略对象的引用,并提供一个方法来执行策略。
下面是一个简单的策略模式的例子,其中包含了StrategyContext:python复制代码from abc import ABC, abstractmethod# 策略接口class Strategy(ABC):@abstractmethoddef execute(self):pass# 具体策略Aclass ConcreteStrategyA(Strategy): def execute(self):return"执行策略A"# 具体策略Bclass ConcreteStrategyB(Strategy): def execute(self):return"执行策略B"# 策略上下文class StrategyContext:def__init__(self, strategy):self.strategy = strategydef set_strategy(self, strategy): self.strategy = strategydef execute_strategy(self):return self.strategy.execute()# 客户端代码def client_code(strategy_context):print(strategy_context.execute_strategy())# 使用示例if __name__ == "__main__":# 创建策略上下文并设置策略Acontext = StrategyContext(ConcreteStrategyA())client_code(context) # 输出: 执行策略A# 更改策略为策略Bcontext.set_strategy(ConcreteStrategyB())client_code(context) # 输出: 执行策略B在这个例子中,Strategy是策略接口,ConcreteStrategyA和ConcreteStrategyB是实现了这个接口的具体策略。