在开始说设计模式之前,让我们先聊点别的东西,相信每个人都有自己难忘的童年时光,在那时有很多有趣好玩的事物陪伴着我们。我记得小时候,很喜欢看一部动画片--《四驱兄弟》,,,好吧暴露年纪了。。受动画片的影响,还经常和小伙伴们一起买四驱玩具车玩。除了玩具车外,我还喜欢玩游戏机来打发时间,当然不是你想的那种游戏主机什么的,而是这种:

手持游戏机

。。可能现在有些小伙伴不认识这家伙了,这其实就是一个手持的小型游戏机,里面内置了几种游戏,我能够想起的几种游戏一个是比较经典的俄罗斯方块,还有个是很简单的赛车游戏,就是在游戏中不断躲避障碍物,并且速度还会不断加快。种类还是比较少的。好了言归正传,一般工厂生产产品时,都需要一个模具,或者说一套标准,在生产具体的产品时,都得照着这个标准做。好了,那么生产这个游戏机的标准是怎样的呢,我们可以定义一个类来描述这个标准:

/*** 工厂中制作游戏机的一个模型标准(类似于模具)*/
public abstract class GamePlayerModel {
//    每个游戏机都内置一款游戏,具体游戏类型在生产具体的游戏机时装入abstract void game();
//    游戏机外观,具体在生产时决定abstract void display();
//    点击游戏机上的开始游戏按钮进入游戏public void startGame(){game();}
}

可以看到,在这个游戏机模具中,内置了一款游戏(这里假设每个游戏机中只有一款游戏),当然开始什么也没装,只有在生产具体类型的游戏机时才会装入相应的游戏,还有个开始游戏的方法,当点击开始游戏就会调用内置的游戏。里面还有个display方法,表示游戏机的外观,具体是什么颜色,也只有在生产时才能决定。当然这里的模型我们是经过简化的,事实上要复杂很多。

好了有了这个游戏机模型,我们生产一个游戏机就很方便了,比如我们需要生产一个红色的内置俄罗斯方块游戏的游戏机,我们定义一个类来描述:

public class RedTetrisPlayer extends GamePlayerModel{@Overridevoid game() {System.out.print("正在俄罗斯方块游戏中...");}@Overridevoid display() {System.out.print("一台红色的游戏机");}
}

可以看到,有了之前游戏机模型标准的基础,我们需要一台有俄罗斯方块游戏的游戏机时,在生产时装入这款游戏并给游戏机上了颜色。

接下来我们就试试这款游戏机好不好用:

public class TestClient {public static void main(String[] args){
//       一台新鲜出炉的红色的游戏机RedTetrisPlayer tetrisGamePlayer = new RedTetrisPlayer();
//        点击游戏机上的开始游戏按钮tetrisGamePlayer.startGame();}
}代码执行结果:
---------------------------------------------------------------------------------------------------------------------
正在俄罗斯方块游戏中...
---------------------------------------------------------------------------------------------------------------------

可以看到,俄罗斯方块游戏已经启动,是不是有点激动。。。

从此以后,我便迷上了这个游戏,只要一有空我就会掏出游戏机撸上几局。然而。。。一直玩这个游戏,慢慢我也产生厌倦了,我想换个游戏玩,可是这个游戏机里就一个游戏,怎么办呢。。此时,商店里还有很多装了不同游戏类型的游戏机,我的第一反应就是再去买一个,可是一想,再买一个又得花钱,当时的价格对于我来说简直是天价,毕竟有个5毛一快的,那时候在小伙伴中都可以算个“有钱人”。。。再说即使买了,要是一个两个还好,要是好几个放家里,也是碍事。这时,我突然想到邻居一位大哥哥平时挺喜欢捣鼓这些电子器件的,就想着能不能让他帮我把游戏改改,果然,他说可以,不过操作上还是比较麻烦的需要把机子拆开,然后把游戏代码重新写到设备上,最后还得组装起来。虽然这花了几天时间,但好歹我又有新游戏可以玩了。然而再好玩的游戏也会有玩腻的一天,一段时间后,我又想玩新的游戏了,我第一反应就是去找哪位大哥哥,可是转念一想,改个游戏没想象中的那么简单,每次都需要把机子拆了,重新写程序,再重新组装,想到这些,我又打消了念头。就这样,我把游戏机扔在了一旁,专心看起了我的动画片。直到有一天,我看见小伙伴中有人在玩这个:

正面

我们当时管这叫“gameboy”,也是一种手持游戏机,不过要比之前的那种高端,他的背部有个插槽,可以插入不同的游戏卡。

背面

卧槽!这不正是我需要的吗,想要玩什么游戏,就插入什么卡就行了,简直不要太爽好吧。。

好了,既然出现了个新家伙,我们来看看用代码怎么描述这个它,我们刚才看到比起之前的游戏机它的背部多了个插槽或者叫做接口,用于插入游戏卡。厂家在制作游戏卡时,也会准从一套标准,最主要的标准就是游戏卡上的接口类型要和游戏机上的一致,比如游戏机插槽有几个管脚,那么游戏卡的接口处就得做几个管脚,总不能在这游戏机上插入小霸王的卡把。。除了游戏卡的接口处要和游戏机上的插槽一致外,游戏卡中最重要的就是要有游戏啦,不然要这卡干嘛。这样,只要制作游戏卡的时候都遵循这个标准,那么含有不同游戏的卡就都能插入到游戏机上。好了我们来看下代码:

/*** 游戏卡制作的标准,插槽接口处类型为GameBoyKard*/
public interface GameBoyKard {
//    卡里装的游戏,生产时才装入void game();
}

同理,生产GameBoy也有一套标准:

public abstract class GameBoyPlayerModel {//    游戏机上装有一个类型为GameBoyKard的插槽,表示只允许GameBoy的卡插入private GameBoyKard mGameKard;
//    游戏机的外观,有生产过时决定public abstract void display();//    用于插入游戏卡public void setGameKard(GameBoyKard gameKard){this.mGameKard = gameKard;}//    开始游戏按钮public void startGame(){mGameKard.game();}
}

我们可以看到,比起之前的那个游戏机,这个gameboy游戏机已经没有内置的游戏了,而是多了一个插槽,用于插入游戏卡。有了这套标准,我们生产一台gameboy游戏机就方便多了,比如我们也想生产一台红色的:

public class RedGameBoyPlayer extends GameBoyPlayerModel{@Overridepublic void display() {System.out.print("这是一台红色的GameBoy");}
}

也是很简单,基于之前定义的标准,我们只要生产时给定颜色就可以了。

这样,我们的游戏机就有了,不过里面可没装任何游戏,我们还需要一张游戏卡:

public class TetrisGameCard implements GameBoyKard {@Overridepublic void game() {System.out.print("正在俄罗斯方块游戏中...");}
}

可以看到我们定义了一张装有俄罗斯方块的游戏卡,当然这张卡的设计标准都是遵循GameBoyKard的标准。

好了,游戏机和游戏卡都已经就绪,赶紧来试下吧:

public class TestClient {public static void main(String[] args){
//       生产一台红色gameboyRedGameBoyPlayer redGameBoyPlayer = new RedGameBoyPlayer();
//        生产一张俄罗斯方块游戏卡TetrisGameCard tetrisGameCard = new TetrisGameCard();
//        向游戏机中插入游戏卡redGameBoyPlayer.setGameKard(tetrisGameCard);
//        开始游戏redGameBoyPlayer.startGame();}
}代码执行结果:
---------------------------------------------------------------------------------------------------------------------
正在俄罗斯方块游戏中...
---------------------------------------------------------------------------------------------------------------------

怎么样,游戏跑起来,还不错把,可能你想玩点其他游戏,没关系,我们只用换张卡就行了,比如有一张赛车的游戏卡:

public class CarGameCard implements GameBoyKard {@Overridepublic void game() {System.out.print("正在赛车游戏中...");}
}

只要把这张卡插入游戏机中,就可以更换游戏了:

//        生产一张赛车游戏卡CarGameCard carGameCard = new CarGameCard();
//        向游戏机中插入游戏卡redGameBoyPlayer.setGameKard(carGameCard);
//        开始游戏redGameBoyPlayer.startGame();代码执行结果:
---------------------------------------------------------------------------------------------------------------------
正在赛车游戏中...
---------------------------------------------------------------------------------------------------------------------

怎么样,是不是感觉gameboy游戏机的这种设计比之前要方便很多。其实这种设计方法正是运用了我们今天的主角--策略模式。好了来看下它的定义:

策略模式 -- 定义算法族,分别封装起来,让它们之间可以相互替换,此模式让算法的变化独立于使用算法的客户。

定义可能有点抽象,不过想想我们这个游戏机的例子,这里的算法族可以理解为某个游戏,我们用游戏卡封装游戏,这样游戏就从游戏机中独立出来,并且不同的游戏卡可以互相切换,这样你再看下定义是不是就好理解多了呢?

那么这种设计模式对我们代码来讲有哪些优势呢?在上文一开始介绍的游戏机,如果我们想换个游戏玩,有两种方式,第一种,就是再去买个游戏机,但是为了换个游戏,我又多了个游戏机,,我们可以看到游戏机的类都是GamePlayerModel这个抽象类的子类,采用这种方式,必定会造成大量的子类以及重复代码。第二种方式就是直接改写游戏机中的游戏,这种方式也是不推荐的。如果直接在代码中修改,一来比较麻烦,再者,这样频繁修改很容易会影响其他功能模块,对项目的维护性和扩展性大打折扣。相反,我们在看看使用了策略模式的游戏机,我们不再需要定义大量不同的游戏机子类,我们要改变的是游戏,只用创建不同游戏卡类就行了,而且不同的卡之间可以互相切换,对原来的功能模块也不会产生任何影响。

另外在策略模式中我们也可以看出几条设计原则,什么是设计原则呢?我们都知道,每种编程语言都有语法,如果你在编程时不遵守语法,那么编译器就会报错。就好比法律,如果你不守法,那么就会得到制裁。除了守法外,我们都是讲道德的,这是要高于法律的。这里的设计原则就像是我们的品德,当然你可以不遵守这些设计原则,只要编译器不报错就好了,不过我相信大家都是讲道德的人,为了不让我们的代码去坑别人,我们还是来看看设计原则吧。在策略模式中,包含了这几条设计原则:

1.在代码中把那些可能变化的地方分离开来,别让它和不变的代码混在一起。
2.针对接口编程,而不是针对实现编程。
3.多用组合,少用继承。

相信从字面上也是很好理解,我们再结合上面的例子简单讲下。第一条,在最开始的游戏机类中,有两个方法,游戏和外观,一般游戏机生产出来外观就不会有变化了,而我们想改变的是里面的游戏,所以在gameboy游戏机中,游戏从游戏机中分离了出来。第二,在之前的游戏机中,游戏是直接实现在游戏机类中,而gameboy则是用到游戏的接口。第三条,顾名思义,每个gameboy游戏机都能和不同的游戏卡任意组合,当然这个游戏卡,要实现相应的接口。而之前的游戏机类都是继承于父类,里面的游戏也就写死了。

我有一个qq群:671900195,经常会分享一些Java技术相关的干货;如果你喜欢我的分享记得加群哦!!!

好了,这篇文章到这也就差不多了,相信你已经很好的掌握了策略模式以及其中体现的几点设计原则。如果哪天突然忘了什么是策略模式,就想想小时候玩的游戏机吧!

设计模式- 策略模式相关推荐

  1. Python设计模式-策略模式

    Python设计模式-策略模式 代码基于3.5.2,代码如下; #coding:utf-8 #策略模式class sendInterface():def send(self,value):raise ...

  2. 关于设计模式——策略模式-Strategy Pattern

    文章目录 1 策略模式 1.1 模拟鸭子 1.2 设计原则 1.3 整合行为 1.4 模拟鸭子代码的代码 1.5 动态设定行为 1.6 重新查看整体 1.7 继承和组合 1.8 总结 1.9 优劣期间 ...

  3. [设计模式] ------ 策略模式

    策略模式 它定义了算法家族,分别封装起来,让他们直接可以互相替换,此模式让算法的变化,不会影响到使用算法的客户 其实很简单,可能很多人都用到了,只不过还不知道这就是策略模式而已. 比如定义一个接口A, ...

  4. java 策略模式 促销_java设计模式——策略模式

    一. 定义与类型 定义:针对一组算法,将每一种算法都封装到具有共同接口的独立的类中,从而是它们可以相互替换.策略模式的最大特点是使得算法可以在不影响客户端的情况下发生变化,从而改变不同的功能.当代码中 ...

  5. Springboot 使用设计模式- 策略模式

    前言 直白点,什么场景我们需要使用到设计模式- 策略模式. 在平常的springboot项目里面做CRUD,我们的习惯性基本是 一个mapper,一个service,一个serviceImpl. 但是 ...

  6. 李建忠设计模式——策略模式Strategy

    目录 1.策略模式定义 1.动机 2.模式定义 3.结构 2.实现例子 1.问题描述 2.代码实现 3.要点总结 4.参考 1.策略模式定义 1.动机 软件构建过程中,某些对象使用的算法可能多种多样, ...

  7. 15. 星际争霸之php设计模式--策略模式

    题记 ============================================================================== 本php设计模式专辑来源于博客(jy ...

  8. Java设计模式-策略模式作业

    Java设计模式-策略模式作业,所有类和接口均在一个package内 文章目录 前言 一.作业内容 二.具体实现 1.类图 2.Strategy接口 3.PreCopyStrategy类 4.Post ...

  9. 设计模式-策略模式2.0

    设计模式-策略模式2.0 前面文章我们说过了传统的策略模式的实现,本文我们简单说下设计模式中的升级版的策略模式,策略模式2.0. 代码实现 talk is cheap show me the code ...

  10. 设计模式-策略模式(Strategy)-Java

    设计模式-策略模式(Strategy)-Java 目录 文章目录 1.前言 2.示例案例-电影票打折方案 3.策略模式概述 3.1.策略模式定义 3.2.策略模式结构 3.3.策略模式结构图中角色 3 ...

最新文章

  1. hadoop common 与 servlet 3冲突
  2. java 变量作用域 c语言_C语言深入理解 - 常量与变量
  3. 思杰VDI十终极结构图及总结
  4. leetcode23-合并K个升序链表
  5. AOJ 0525 Osenbei
  6. 泛化误差,交叉验证和特征选择
  7. C#区分中英文统计字符串的长度
  8. 简述springmvc过程_Springmvc执行流程
  9. 收到“【有奖话题】虚拟空间“筑梦师”,谈谈微软虚拟化 ”礼物一个
  10. AMS分析 -- 启动过程
  11. android录制视频设置分辨率,Android录制视频的全面屏适配
  12. JWT全面解读、使用步骤
  13. 重言式判定------参考了别人的代码。。
  14. 119.编写函数,该函数的功能是计算下列级数之和,和值返回调用函数,数据由主函数输入
  15. 2023 诚通网盘在线解析无广告高速下载网站源码
  16. 曾国藩语录[修养篇]
  17. 我们该如何度过自己的大学四年?
  18. shadertoy上手指南
  19. python36.dll下载_DWSPY36.dll,下载,简介,描述,修复,等相关问题一站搞定_DLL之家
  20. AI|再聊决策树模型

热门文章

  1. CF 295A - Greg and Array 差分數列
  2. weblogic服务器启动报错
  3. Java多线程(3) Volatile的实现原理
  4. 图的遍历DFS与BFS(邻接表)
  5. 评估创业项目的十大标准
  6. web.config 中SessionState的配置 [转]
  7. 【性能优化】 之10046 事件
  8. 一个修改RAC REDO引起的DATAGUARD错误 的处理
  9. MyBatis详细介绍
  10. WebKit DOM Event (一)