策略模式,顾名思意,针对不同的要求采用不同的策略处理问题。
实际的“策略”通常都是算法簇,处理同一个问题或者执行同一动作可能有多种策略,而这些策略之间的切换如果以硬编码的方式写在代码中,则相当丑陋,策略模式提供了策略切换的一个动态的机制,即可以运行时指定。
比如,现在有一个关于鸭子系统,有一个抽象父类Duck, 里面声明了几个鸭子的动作,如 叫、飞、游泳、展示(在这里鸭子动作即是算法簇),针对这个抽象类有多种继承的子类,如MallarDuck(绿头鸭)、RedheadDuck(红头鸭)、RubberDuck(橡胶鸭), 现在问题出来了:并不是每种鸭子都会飞,例子橡胶鸭;每种鸭子的叫声可能并不一样;后一个问题可以通过在子类中重写“叫”这个方法来解决,但前一个问题并不能解决,因为继承是代码复用,导致每种鸭子都包含“飞”这个动作。为了解决这个问题,试将“飞”这个动作从Duck抽象类中分离出去,抽象成一个Flyable接口,需要“飞”这个动作的鸭子则实现这个接口,不需要的不实现这个接口~~表面上好像解决了问题,实现严重破坏了代码复用。因为接口只声明方法,并无实现,这样每种鸭的实现类中都必须重写“飞”这个方法,即使这个实现方式可能是完全一样的,更大的问题在于,如果以后要修改“飞”这个方法,又不得不到每个鸭实现中去一个一个的修改“飞”方法,这显然很不灵活。
软件设计的基本原则:
一、找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。
二、针对接口编程,而不是针对实现编程。
三、多用组合,少用继承。
显然“飞”和“叫”这两个方法是Duck类中变化的部分(假如其他方法都是通用的),运用第一个原则,将它们两个都分离出来,分离成什么呢? 运用第二个原则可得出结论,分离成接口。
//飞
public interface FlyBehavior {
void fly();
}
//叫
public interface QuackBehavior {
void quack();
}
然后是具体的策略,分别实现这两个接口:
//不会飞
public class FlyNoWay implements FlyBehavior{
public void fly(){
System.out.println("Can't fly!");
}
}
//用翅膀飞
public class FlyWithWings implements FlyBehavior {
public void fly() {
System.out.println("fly with wings!");
}
}
//呱呱叫
public class QuackGuagua implements QuackBehavior {
public void quack() {
System.out.println("呱呱叫");
}
}
//不会叫
public class QuackNoWay implements QuackBehavior {
@Override
public void quack() {
System.out.println("不会叫...");
}
}
//吱吱叫
public class QuackZhizhi implements QuackBehavior {
@Override
public void quack() {
System.out.println("吱吱叫!");
}
}
客户需要使用策略,这里遵循第三条原则,我们采用组合的方式,在Duck中添加这两个接口的引用,分别在performQuack()和performFly()方法中使用上述接口的引用,调用“叫”动用和“飞”动作,同时声明两个set方法,用来动态的设置这两个引用的运行时对象:
public abstract class Duck {
FlyBehavior flyBehavior;
QuackBehavior quackBehavior;
public void setFlyBehavior(FlyBehavior flyBehavior) {
this.flyBehavior = flyBehavior;
}
public void setQuackBehavior(QuackBehavior quackBehavior) {
this.quackBehavior = quackBehavior;
}
public void swim(){
System.out.println("我在游泳...");
}
public abstract void display();
public void performQuack(){
quackBehavior.quack();
}
public void performFly(){
flyBehavior.fly();
}
}
测试:
public class Main {
public static void main(String[] args) {
Duck duck1 = new MallarDuck();
//动态设置策略
duck1.setFlyBehavior(new FlyWithWings());
duck1.setQuackBehavior(new QuackZhizhi());
duck1.display();
duck1.performFly();
duck1.performQuack();
System.out.println();
Duck duck2 = new RubberDuck();
//动态设置策略
duck2.setFlyBehavior(new FlyNoWay());
duck2.setQuackBehavior(new QuackGuagua());
duck2.display();
duck2.performFly();
duck2.performQuack();
}
}
总结:
策略模式的关键在于:分离变化部分、面向接口编程、包含策略接口类型引用变量、运行时动态确定具体策略对象
分享到:
相关推荐
设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设计模式于己于他人于系统...
非常好的设计模式介绍资料,通俗易懂,适用于编程人员参考。采用了大量图片介绍系统的展示了编程当中常用的各种模式设计
白话说电气_相电压和线电压的分析 白话说明 比较容易理解
白话说电气_电机制动的几种常见方式.pdf
深入浅出设计模式 pdf 深入浅出设计模式 中文版 设计模式 下载说明: 因个人上传资源大小只能是20M,而该书的PDF格式过大,所以只能分开上传。如有不便请谅解。【该书一共13章,在上传的时候我尽量按章节顺序打包...
设计模式中的策略模式,template模式详细讲解。
写在前面 分享一些设计模式的笔记。陆续整理,按照设计模式类型,创建型,结构型,行为型发布 博文会用通俗的话梳理一些自己的理解,结合开发中的实际场景, 理解不足小伙伴帮忙指正,虚心接受 ^_^ 傍晚时分
为了更系统的学习设计模式,特地开了这样一个基于Java的设计模式【集中营】,都是笔者在实际工作中用到过或者学习过的一些设计模式的一些提炼或者总检。慢慢地初见规模,也有几个朋友给我点鼓励,给了star。本文工程...
1、设计模式的一些总结思考, 2、用白话总结了设计模式的精要, 3、帮助大家理解记忆一些常用的设计模式。
java课程设计大作业,java、算法练手项目,适合初学java、数据结构的同学拿来学习研究,基于java、GUI开发的小游戏,程序都经过测试,可以直接运行,资源含程序运行所需的源码、资源文件等全部数据,有需要的可放心...
java课程设计作业——模仿大富翁游戏,使用Java Swing (GUI) 实现的单机游戏,遵循MVC设计模式 A Java Swing (GUI) game. 单机版的大富翁游戏,纯Java实现,采用MVC设计模式。 所有素材来自 大富翁客户端+冒险岛...
白话中台战略-中台是个什么鬼.pdf白话中台战略-中台是个什么鬼.pdf白话中台战略-中台是个什么鬼.pdf白话中台战略-中台是个什么鬼.pdf白话中台战略-中台是个什么鬼.pdf白话中台战略-中台是个什么鬼.pdf白话中台战略-...
作者Eric Freeman 和Elisabeth Freeman,使用白话文的形式在讨论中介绍23中设计模式,有异与原《设计模式》更加通俗易懂。通过实际事例来讲解每一个设计模式,生动有趣,不会感觉到枯燥。
作者Eric Freeman 和Elisabeth Freeman,使用白话文的形式在讨论中介绍23中设计模式,有异与原《设计模式》更加通俗易懂。通过实际事例来讲解每一个设计模式,生动有趣,不会感觉到枯燥。
这本书作者Eric Freeman 和Elisabeth Freeman使用白话文的方式,清楚的介绍了全部23种设计模式。简洁易懂。共13章节。此为封面、目录
作者Eric Freeman 和Elisabeth Freeman,使用白话文的形式在讨论中介绍23中设计模式,有异与原《设计模式》更加通俗易懂。通过实际事例来讲解每一个设计模式,生动有趣,不会感觉到枯燥。
白话c++.pdf 个人收集电子书,仅用学习使用,不可用于商业用途,如有版权问题,请联系删除!
java餐饮管理系统源码加数据库 designmodel 设计模式 六大原则 1.单一职责原则:只做一...开发人员A碰到了一个问题,就找开发B,开发B说用"xxxx设计模式就行了",如果这个时候开发A不懂设计模式,那他们就无法交流了。就
白话windows编程.rar
白话C++编程.rar