通过设计国际象棋游戏来了解策略模式

今天,我们将借助一个示例来尝试了解策略模式。

我们将考虑的示例是国际象棋游戏。 这里的目的是解释策略模式,而不是构建全面的国际象棋游戏解决方案。

策略模式:策略模式被称为行为模式-用于管理对象之间的算法,关系和职责。 策略模式的主要好处是在运行时选择算法/行为。



策略模式

让我们尝试通过实现设计棋盘游戏来理解这一点。

在国际象棋中,有不同的角色,例如国王,皇后,主教,并且所有角色都有不同的动作。 此设计可能有很多解决方案,让我们一个一个地探索:

  1. 第一种方法是在每个类中定义运动,每个字符都有其自己的move()实现。 这样就没有代码可重用性,并且我们无法在运行时更改实现。
  2. 制作一个单独的MovementController类,并为每种类型的对象放置一个if否则。
public class BadDesginCharacterMovementController {public void move(Character character){if(character instanceof King){System.out.print("Move One Step forward");}else if(character instanceof Queen){System.out.print("Move One Step forward");}else if(character instanceof Bishop){System.out.print("Move diagonally");}}
}

这是一个较差的设计,具有很强的耦合性,而且使用if / else使其难看。

因此,我们希望有一个设计,在其中我们可以有松散的耦合,可以在运行时决定运动算法,并且可以重复使用代码。

让我们看看使用策略模式的完整实现。

下面是我们的实现的类图:

棋

  • 完整的源代码可以从这里下载。

我们将有一个基本的抽象类作为Character Class,所有的角色都可以扩展并设置自己的MovementBehaviour实现。

public class Character {private MovementBehaviour movementBehaviour;String move(){return movementBehaviour.move();}public void setMovementBehaviour(MovementBehaviour movementBehaviour) {this.movementBehaviour = movementBehaviour;}
}

这个班级有一个运动行为:

public interface MovementBehaviour {String move();
}

因此,每个角色:国王,女王,主教都将扩展角色,并且他们可以有自己的运动行为实现。

public class King extends Character {public King() {setMovementBehaviour(new SingleForward());}
}

为了简单起见,在这里,我在King的构造函数中调用了setMovemementBehaviour方法。

同样,另一个字符Queen可以定义为:

public class Queen extends Character {public Queen() {setMovementBehaviour(new SingleForward());}
}

并且,Bishop为:

public class Bishop extends Character {public Bishop() {setMovementBehaviour(new DiagonalMovement());}
}

不同动作的实现可以如下:

单向前进:

public class SingleForward implements MovementBehaviour {@Overridepublic String move() {return "move one step forward";}
}

对角运动:

public class DiagonalMovement implements MovementBehaviour {@Overridepublic String move() {return "Moving Diagonally";}
}

通过这个例子,我们可以理解策略模式。

翻译自: https://www.javacodegeeks.com/2014/10/understanding-strategy-pattern-by-designing-game-of-chess.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/361972.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vs2010 问题 LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏

vs2010 问题 LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏 在安装 VS2010 后,再安装 VS2012 VS2015 等,原来的 .NET 4.0 会被替换为 .NET 4.5。不会恢复 .NET 4.0 。这时,VS2010的 cvtres.exe 就无法使用了。如果 PATH…

Nginx 使用try_files遇到的问题

背景: root /some/path; location / {try_files $uri $uri/ /dist/index.html; }使用React之类的的库来开发前端页面的时候,因为是单页应用所以需要上面的Nginx配置,用来在找不到html文件的时候内部重定向到/dist/index.html文件。 服务器上…

群发邮件

最近,通过两周的学习,对.net 的基础知识有了进一步的了解。觉得自己可以写个小程序了。于是花了两天时间写了一个 群发邮件的一个WinForm小程序。自己在这里小秀一下,表扬及鼓励一下自己。哈哈! 此小程序在发送邮件的基础上还添加…

深入研究ES6 Generators

ES6 Generators系列: ES6 Generators基本概念深入研究ES6 GeneratorsES6 Generators的异步应用ES6 Generators并发 如果你还不知道什么是ES6 generators,请看我的前一篇文章“ES6 Generators基本概念” 。如果你已经对它有所了解,本文将带你…

在JavaEE中使用CDI的简单面向方面的编程(AOP)

我们编写满足特定业务逻辑的服务API。 涵盖所有服务API(如安全性,日志记录,审核,度量延迟等)的跨领域问题很少。 这是一个重复的非业务代码,可以在其他方法之间重用。 重用的一种方法是将这些重复的代码移入…

sessionStorage什么时候失效

最近在调试程序的时候无意间看到 cookie 的过期时间是 session,这个 session 表示的是什么时候过期?牵扯出来另一个存储方案 sessionStorage 存储的数据又是什么时候过期呢? 在查找相关资料的时候总会看到会话结束的时候 cookie 会被清除&am…

ES6 解构赋值详解

解构赋值是对赋值运算符的扩展,可以将属性/值从对象/数组中取出,赋值给其他变量。 一、数组的解构赋值 1、基本用法 只要等号两边的模式相同,左边的变量就会被赋予对应的值。 let [a, [[b], c]] [1, [[2], 3]]; a // 1 b // 2 c // 3 let [a…

软件著作权申请流程

一、填写计算机软件著作权登记申请表(表格1份)包括软件全称、简称、版本号、开发完成日期、软件开发情况(独立开发、合作开发、委托开发、下达任务开发)、原始取得权利情况、继受取得权利情况、权利范围、软件用途和技术特点&…

Npm install failed with “cannot run in wd”

Linux环境下,root账户,安装某些npm包的时候报下面的错误,例如安装grunt-contrib-imagemin时: Error: EACCES, mkdir /usr/local/lib/node_modules/coffee-scriptnpm ERR! { [Error: EACCES, mkdir /usr/local/lib/node_modules/c…

Java EE 7 Batch中传递属性/参数的2种方式

对于Java EE 7批处理工具,有两种将属性/参数传递给块和批处理的方法。 本快速指南向您展示了两种方式,在开发批处理Java EE 7方式时可能会经常使用它们。 1.运行前预定义的属性/参数 预定义属性是您在部署应用程序之前定义的属性(名称/值对&…

Csharp 打印Word文件默認打印機或選擇打印機設置代碼

//打印文檔object nullobj Missing.Value;//aDoc wordApp.Documents.Open(ref file,// ref nullobj, ref nullobj, ref nullobj,// ref nullobj, ref nullobj, ref nullobj,// ref nullob…

ESLint共享配置的两种方式eslint-plugin和eslint-config

使用ESLint很久了,也看了ESLint官方文档很多遍,但对于ESLint配置的规则还是不胜清楚,例如: {"extends": ["plugin:prettier/recommended"] }上面extends的值为什么要"plugin:"开头?这里…

使用aggregate在MongoDB中查找重复的数据记录

我们知道,MongoDB属于文档型数据库,其存储的文档类型都是JSON对象。正是由于这一特性,我们在Node.js中会经常使用MongoDB进行数据的存取。但由于Node.js是异步执行的,这就导致我们无法保证每一次的数据库save操作都是原子型的。也…

Gradle入门:创建二进制分发

创建有用的应用程序之后,很可能我们想与其他人共享它。 一种方法是创建一个可以从我们的网站下载的二进制发行版。 这篇博客文章描述了如何满足以下要求的二进制发行版: 我们的二进制分发绝对不能使用所谓的“胖子”方法。 换句话说,我们的…

我的Google Adsense帐户被关

一、 上周四,我收到Google的邮件,宣布关闭我的Adsense帐户。 "您好! 查看了相关记录后,我们确认您的 AdSense 帐户存在引起无效活动的风险。保护 AdWords 广告客户,使其免受无效活动的侵害是我们的责任&#xff0…

网格布局之网格元素放置算法

接下来的网格元素放置算法将网格元素的自动位置解析为确定位置,确保每个网格元素具有布局明确的网格区域。(Grid spans 不需要特别的解析;如果没有明确指定,默认是1) 注意:当显式网格中没有位置放置自动放置…

csharp: ODP.NET,System.Data.OracleClient(.net 4.0) and System.Data.OleDb读取Oracle g 11.2.0的区别...

ODP.NET: 引用: using Oracle.DataAccess; //Oracle g 11.2.0 using Oracle.DataAccess.Client; using Oracle.DataAccess.Types; //下载 http://www.oracle.com/technetwork/topics/dotnet/downloads/net-downloads-160392.html //引用:D:\app\geovindu…

AngularJS快速入门指南15:API

API即Application Programming Interface(应用程序接口)。 AngularJS全局API AngularJS全局API是一组全局JavaScript函数,用来进行一些常用的操作,例如: 比较两个对象迭代对象进行数据格式转换 全局API函数可以通过an…

Java 9幕后花絮:新功能从何而来?

找出Java幕后发生的事情,以及新功能如何实现 在上一篇文章中,我们介绍了即将发布的Java 9版本的新功能和尚待解决的功能,并简要提到了将新功能添加到下一个版本之前要经历的过程。 由于此过程几乎影响了所有Java开发人员,但大多数…

TypeScript 联合类型(union type)

TS是JS的超集,在JS的基础上添加了一套类型系统,这样的TS可以被静态分析带来的好处显而易见。 let val: string val;声明一个string类型的变量val。 let val: string val; val 1; // Type number is not assignable to type string.因为number类型和…