关于java设计模式与极品飞车游戏的思考
对像我一样正在学习java的人来讲,对设计模式的学习是个很重要的环节。而我们在学习设计模式时,不仅仅应该知道它们的思想,还要学会将设计模式与实际开发中需要解决的具体问题相联系,这是成为一名优秀程序员的很重要的一点。
大多数玩游戏的我们都应该玩过“极品飞车”这款游戏,对于游戏中的各种效果和功能,我想把它们结合到我们学习的设计模式中来。
首先说说我们在IO流中学到的装饰模式:
在玩“极品飞车”这款游戏,游戏中有对汽车进行喷涂鸦的功能,而且这个喷涂鸦是可以覆盖的,并且覆盖的顺序也影响到最后车身的显示效果,假设现在喷涂鸦具有2种样式:(1)红色火焰 (2)紫色霞光。
装饰模式代码:
新建一个抽象汽车父类:
package car_package; public abstract class car_parent { // 汽车抽象父类 private String make_address; private int speed; public String getMake_address() { return make_address; } public void setMake_address(String make_address) { this.make_address = make_address; } public int getSpeed() { return speed; } public void setSpeed(int speed) { this.speed = speed; } public abstract void print_face(); } |
然后新建一个奥迪汽车子类
package car_package; public class audi_sub extends car_parent { // 奥迪汽车子类 @Override public void print_face() { System.out.println("audi车默认的颜色为 黑色"); } } |
然后再新建一个装饰者父类:
package decorator_package; import car_package.car_parent; public abstract class decorator_parent extends car_parent { // 装饰者父类 protected car_parent car_parent_ref; public void setCar_parent_ref(car_parent car_parent_ref) { this.car_parent_ref = car_parent_ref; } @Override public void print_face() { car_parent_ref.print_face(); } } |
然后再新建装饰者子类:红色火焰装饰者类:
package decorator_package; public class decorator_audi_red extends decorator_parent { @Override public void print_face() { super.print_face(); System.out.println("给 奥迪 喷涂鸦 - 颜色为 红色火焰"); } } |
然后再新建装饰者子类:紫色霞光装饰者类:
package decorator_package; public class decorator_audi_purple extends decorator_parent { @Override public void print_face() { super.print_face(); System.out.println("给 奥迪 喷涂鸦 - 颜色为 紫色霞光"); } } |
新建一个运行类
package main_run; import car_package.audi_sub; import decorator_package.decorator_audi_purple; import decorator_package.decorator_audi_red; public class main_run { public static void main(String[] args) { audi_sub audi_sub_ref = new audi_sub(); audi_sub_ref.setMake_address("北京市朝阳区"); audi_sub_ref.setSpeed(200); decorator_audi_red decorator_audi_red_ref = new decorator_audi_red(); decorator_audi_red_ref.setCar_parent_ref(audi_sub_ref); decorator_audi_purple decorator_audi_purple_ref = new decorator_audi_purple(); decorator_audi_purple_ref.setCar_parent_ref(decorator_audi_red_ref); decorator_audi_purple_ref.print_face(); } } |
程序运行结果如下:
audi车默认的颜色为 黑色 给 奥迪 喷涂鸦 - 颜色为 红色火焰 给 奥迪 喷涂鸦 - 颜色为 紫色霞光 |
再讲讲高新技术里提到的代理模式:
在玩“极品飞车”这款游戏,如果游戏者手中的金钱达到了一定的数量就可以到车店买一部性能更高的赛车,那么这个卖车的“车店”就是一个典型的“汽车厂家”的“代理”,他为汽车厂家“提供卖车的服务”给有需求的人士。从面向对象的方面考虑,“销售汽车的代理”也是一个对象,那么这个对象也具有一定的状态,在软件项目中这个对象也具有管理财务进销存的基本功能,那么在设计时就要以面向OOP编程的思想来考虑软件的类结构,这个销售汽车的代理也是一个类了。
代理模式代码:
新建一个买车的接口:
package buy_car_package; public interface buy_car_package { public void buy_car(); } |
新建一个people人类,具有买车的行为,所以实现接口buy_car_package:
package buy_car_imple; import buy_car_package.buy_car_package; public class people implements buy_car_package { private int cash; private String username; public int getCash() { return cash; } public void setCash(int cash) { this.cash = cash; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public void buy_car() { System.out.println(username + "买了一台新车"); } } |
people类不能拥有车,必须经过proxy代理类的认证,符合条件之后才可以拥有车辆,新建一个代理,这个代理类来考察当前的people是否有资格进行买车:
package buy_car_imple; import buy_car_package.buy_car_package; public class proxy_buy_car_imple implements buy_car_package { private people people; public people getPeople() { return people; } public void setPeople(people people) { this.people = people; } public void buy_car() { if (people.getCash() > 3000) { System.out.println(people.getUsername() + "花" + people.getCash() + "块 买了新车 交易结束"); } else { System.out.println(people.getUsername() + "金钱不够,请继续比赛!"); } } } |
最后创建一个客户端,用来模拟买车的行为:
package run_main; import buy_car_imple.people; import buy_car_imple.proxy_buy_car_imple; public class run_main { public static void main(String[] args) { people people_ref1 = new people(); people_ref1.setCash(4000); people_ref1.setUsername("黑马学员"); people people_ref2 = new people(); people_ref2.setCash(2000); people_ref2.setUsername("java冬冬"); proxy_buy_car_imple proxy_buy_car_imple = new proxy_buy_car_imple(); proxy_buy_car_imple.setPeople(people_ref1); proxy_buy_car_imple.buy_car(); proxy_buy_car_imple.setPeople(people_ref2); proxy_buy_car_imple.buy_car(); } } |
程序运行结果如下:
黑马学员花4000块 买了新车 交易结束 java冬冬金钱不够,请继续比赛! |
这样people就不可能自由的拥有车辆,必须经过proxy的认证之后才可以。
而代理模式在GOF四人帮的介绍中大体有4种使用情景:
(1)远程代理。典型的就是客户端与webservice使用的情况,客户端由于是针对OOP编程,而不是针对webservice中的方法进行编程,所以得在客户端模拟一下webservice的环境,用proxy来对webservice进行包装,这样就可以使用proxy代理类来远程操作webservice了。
(2)虚拟代理。比如你要开发一个大文档查看软件,大文档中有大的图片,有可能一个图片有100MB,在打开文件时不可能将所有的图片都显示出来,这样就可以使用代理模式,当需要查看图片时,用proxy来进行大图片的打开。
(3)安全代理。其实也就是本例中所举的买车的例子,金钱不够不可以买车!
(4)智能指引。比如在访问一个对象时检测其是否被锁定等情况。
再说一下模板方法模式:
在玩“极品飞车”这款游戏,每辆车都有显示速度的仪表盘,但有可能A车显示的是蓝色的仪表盘,B车显示的是红色的仪表盘,分析中可以发现,他们都有车速度的值,但显示的方式不太一样。其实模板方法就是最典型的“继承”的使用,大家平时百分百都可以用到,只是不知道叫模板方法模式:)!
模板方法模式代码:
新建赛车的父类:
package car_package; public class car_parent { private int speed; public int getSpeed() { return speed; } public void setSpeed(int speed) { this.speed = speed; } public void print_speed() { System.out.println("将速度" + this.getSpeed() + "取出来!"); } } |
新建红色仪表盘的赛车实现类:
package car_imple; import car_package.car_parent; public class car_imple_red extends car_parent { @Override public void print_speed() { super.print_speed(); System.out.println("将速度" + this.getSpeed() + "用红色的仪表盘显示车的速度"); } } |
新建蓝色仪表盘的赛车实现类:
package car_imple; import car_package.car_parent; public class car_imple_blue extends car_parent { @Override public void print_speed() { super.print_speed(); System.out.println("将速度" + this.getSpeed() + "用蓝色的仪表盘显示车的速度"); } } |
新建客户端运行类:
package run_main; import car_imple.car_imple_blue; import car_imple.car_imple_red; import car_package.car_parent; public class run_main { public static void main(String[] args) { car_parent car_ref_red = new car_imple_red(); car_ref_red.setSpeed(300); car_ref_red.print_speed(); car_parent car_ref_blue = new car_imple_blue(); car_ref_blue.setSpeed(400); car_ref_blue.print_speed(); } } |
程序运行结果如下:
将速度300取出来! 将速度300用红色的仪表盘显示车的速度 将速度400取出来! 将速度400用蓝色的仪表盘显示车的速度 |
这就是模板方法模式,一个最常用,最容易理解的一个模式,将相同的功能抽象出来成一个父类,然后用子类做不同功能的实现。
关于java设计模式与极品飞车游戏的思考的更多相关文章
- Java设计模式11:常用设计模式之代理模式(结构型模式)
1. Java之代理模式(Proxy Pattern) (1)概述: 代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问. 在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象 ...
- 添加 Windows 8.1 无虚拟机启动项 解决极品飞车的不支持虚拟机报错
在Windows 8.1 64位环境下,安装完极品飞车17后,运行程序会出现错误对话框: Sorry, this application cannot run under a Virual Machi ...
- 浅析JAVA设计模式(一)
第一写技术博客,只是想把自己一天天积累的东西与大家分享.今天在看<大型网站架构和java中间件>这本书时,其中提到代理模式的动态代理.作为java中间件的一个重要基础,我觉的有必要整理和分 ...
- JAVA设计模式--装饰器模式
装饰器模式 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创建了一个装饰 ...
- Java设计模式学习记录-状态模式
前言 状态模式是一种行为模式,用于解决系统中复杂的对象状态转换以及各个状态下的封装等问题.状态模式是将一个对象的状态从该对象中分离出来,封装到专门的状态类中,使得对象的状态可以灵活多变.这样在客户端使 ...
- Java设计模式学习记录-备忘录模式
前言 这次要介绍的是备忘录模式,也是行为模式的一种 .现在人们的智能手机上都会有备忘录这样一个功能,大家也都会用,就是为了记住某件事情,防止以后自己忘记了.那么备忘录模式又是什么样子的呢?是不是和手机 ...
- JAVA设计模式——代理(动态代理)
传送门:JAVA设计模式——代理(静态代理) 序言: 在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring ...
- Java设计模式之十 ---- 访问者模式和中介者模式
前言 2018年已经过去,新的一年工作已经开始,继续总结和学习Java设计模式. 在上一篇中我们学习了行为型模式的解释器模式(Interpreter Pattern)和迭代器模式(Iterator P ...
- Java设计模式菜鸟系列(一)策略模式建模与实现
转载请注明出处:http://blog.csdn.net/lhy_ycu/article/details/39721563 今天開始咱们来谈谈Java设计模式. 这里会结合uml图形来解说,有对uml ...
随机推荐
- linux之间连接—使用SSH
菜鸟学linux笔记.本机是linux,需要远程连接linux,使用SSH (1)在终端,输入命令:ssh root@110.110.100.100 root为用户名,110.110.100.100为 ...
- 服务器之间建立oracle之间的关联语句
create public database link DBLINK_WZGTAMS CONNECT TO WZGTAMS identified by WZGTAMS using ' (DESCRIP ...
- CodeForces 534C Polycarpus' Dice (数学)
题意:第一行给两个数,n 和 A,n 表示有n 个骰子,A表示 n 个骰子掷出的数的和.第二行给出n个数,表示第n个骰子所能掷出的最大的数,这些骰子都有问题, 可能或多或少的掷不出几个数,输出n个骰子 ...
- android 开源 + 一些素材网站
ui 设计工具:http://www.sketchcn.com/ 分类汇总: https://github.com/Trinea/android-open-project 直接拿来用!最火的Andro ...
- linxu php连接sqlserver
今天linux的yum也不能用,用的是第三方的yum源,yum安装好后更新header又花了很长时间. 记得安装指定安装目录要用 --with-php-config=PATH命令. CentOS 6安 ...
- cocos2dx 手势识别
转自:http://blog.csdn.net/qq634416025/article/details/8685187 g_rGemertricRecognizer = new GeometricRe ...
- c++ 中文字符串处理方法
转自:http://hi.baidu.com/hehehehello/item/dcc44a4a6afc690e6dc2f08b C++处理中文的问题困扰我很久了.之前一旦遇到中文基本就投诸java怀 ...
- PostQuitMessage, PostThreadMessage( WM_QUIT )
http://blogs.msdn.com/b/oldnewthing/archive/2005/11/04/489028.aspx Why is there a special PostQuitMe ...
- HDU 4757 Tree 可持久化字典树
Tree Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=4757 Des ...
- 搭建Spring + SpringMVC + Mybatis框架之三(整合Spring、Mybatis和Spring MVC)
整合Spring和SpringMVC 之前已经整合了spring和mybatis,现在在此基础上整合SSM. 项目目录: 思路:SpringMVC的配置文件独立,然后在web.xml中配置整合. (1 ...