问题描述:模拟鸭子游戏

鸭子分为绿头鸭子、红头鸭子、橡皮鸭子、诱饵鸭子,鸭子有的会游泳,有的会飞、有的会呱呱叫、有的会吱吱叫、外表不一样。

问题解决:

问题中所有的鸭子都会叫quack也会游泳swing,通过超类负责处理这部分代买,每种鸭子的外表都不一样,所以display()方法是抽象方法。

现在我们让鸭子飞起来:

我们在duck类中加上fly()方法,然后所有的鸭子都会继承fly()。

通过这样的设计,发生了可怕的问题:

并不是所有的鸭子都会飞(如橡皮鸭),在超类中加上fly(),就导致了所有的子类都具备fly(),连那些不具备fly()的子类也无法免除,说明了继承并不是一个实现的很好方法。

当然我们可以覆盖父类中的方法,如橡皮鸭类RubberDuck中的fly()方法覆盖掉(什么都不做);诱饵鸭类DecoyDuck要不具有其他的行为,只需要disply()方法。

继承不可以我们可以考虑使用接口吗?

从分析来看,使用继承来实现鸭子模拟游戏,当然也可以实现,但是这将会是对方法的多次覆盖,如fly()、quack().........................对一个程序员来来说,简直是一个无穷尽的恶梦!!!

然而,我们可以考虑使用接口,将fly()、quack()等存在变化的方法取出来。fly()放进一个Flyable接口中,只有会飞的鸭子才会实现此接口,同样的方式qucak()等方法也一样。从而得到如下的设计:

很明显,重复的代码变得更多了。使用接口解决了一部分问题(如不会有会飞的橡皮鸭),但是无法达到代码的复用,达不到设计的目的。只能再重新设计。。。。。。

问题解决的思想:

设计原则:找出可能需要变化的地方,把他们独立出出来,不要和那些不需要变化的代码混在一起。把会变化的部分取出来并封装好,让其他部分不会受到影响。这样一来代码变化之后,出其不意的部分变得很少,系统变得更加有弹性。

设计鸭子的行为:

设计原则:针对接口编程,而不是针对实现编程。

也就是说,鸭子的行为将被放在分开的类中,此类专门提供某行为的实现。这样,鸭子就不需要知道行为的实现细节。

我们利用接口代表每个行为,比方说,FlyBehavior与QuackBehavior,而行为的每个实现都必须实现这些接口之一。鸭子类Duck就不会负责实现Fly和Quack接口,反而是由其他类专门实现FlyBehavior和QuackBehavior,也就是行为类实现行为接口,二不是由Duck类实现行为接口。

部分实现代码:

  • FlyBehavior接口:
public interface FlyBehavior {public void fly();
}
  • FlyWithWings行为类实现会飞的行为:
package son;import bb.FlyBehavior;//会飞的行为
public class FlyWithWings implements FlyBehavior {public void fly() {System.out.println("I can fly");}
}
  • FlyNoWay行为类实现不会飞的行为:
package son;import bb.FlyBehavior;//不会飞的行为
public class FlyNoWay implements FlyBehavior {public void fly() {System.out.println("I can't fly");}}
  • QuackBehavior接口:
package bb;public interface QuackBehavior {public void quack();
}
  • Quack行为类,实现呱呱叫行为:
package son;import bb.QuackBehavior;public class Quack implements QuackBehavior {public void quack() {System.out.println("我能呱呱叫!!");}
}
  • Squack行为类,实现吱吱叫行为:
package son;import bb.QuackBehavior;
public class Squeak implements QuackBehavior{public void quack() {System.out.println("我能吱吱叫!!");}
}
  • MuteQuack行为类,不会叫的行为:
package son;import bb.QuackBehavior;
public class Squeak implements QuackBehavior{public void quack() {System.out.println("我不能叫!!");}
}

通过这样的设计,可以让鸭子的动作被其他对象复用,因为这些对象已经和鸭子类无关了。

整合鸭子的行为:

首先在鸭子类中加入两个实例变量flyBehavior和quackBehavior,声明为借口类型。

 public FlyBehavior flyBehavior; //飞的行为public QuackBehavior quackBehavior;//叫的行为

实现fly()和quack()应有的行为。不亲自处理,委托给借口对象来实现。

 public void performQuack() {//叫的行为quackBehavior.quack();}public void performFly() {//飞的行为flyBehavior.fly();}

整合MallardDuck类(其他鸭子类也是使用同样的方法):

package son;
import bb.Duck;
//绿头鸭---叫、飞、外表
public class MallarDuck extends Duck{public MallarDuck() {//构造函数,对鸭子的行为进行处理flyBehavior = new FlyWithWings();quackBehavior = new Quack();}public void display() {System.out.println("外观是绿头的");}
}

代码测试:

编写测试类并运行:

package Main;
import bb.Duck;
public class Main {public static void main(String arg[]) {Duck Mallar = new MallarDuck();Mallar.performQuack();Mallar.performFly();}
}

软件设计模式Day01--简单的模拟鸭子应用相关推荐

  1. 软件设计模式(观察者模式)——模拟股票价格变动并绘制分时图和K线图

    一.观察者模式简介: 首先看百度百科上对观察者模式的简介:观察者模式(Observer)完美的将观察者和被观察的对象分离开.举个例子,用户界面可以作为一个观察者,业务数据是被观察者,用户界面观察业务数 ...

  2. java 分时图_软件设计模式(观察者模式)——模拟股票价格变动并绘制分时图和K线图...

    一.观察者模式简介: 首先看百度百科上对观察者模式的简介:观察者模式(Observer)完美的将观察者和被观察的对象分离开.举个例子,用户界面可以作为一个观察者,业务数据是被观察者,用户界面观察业务数 ...

  3. 设计模式超简单的解释!

    设计模式超简单的解释!(本项目从 design-patterns-for-humans fork) 介绍 设计模式是反复出现问题的解决方案; 如何解决某些问题的指导方针.它们不是可以插入应用程序并等待 ...

  4. 软件设计模式“单例模式”和“工厂模式”

    软件设计模式"单例模式"和"工厂模式" 单例模式 什么是单例模式 单例模式的实现方式有哪些 单例模式的优缺点 单例模式的应用场景 总结 工厂模式 什么是工厂模式 ...

  5. 设计模式超级简单的解释

    推荐阅读 design-patterns-for-humans 中文版(github 仓库永久更新) MongoDB 资源.库.工具.应用程序精选列表中文版 有哪些鲜为人知,但是很有意思的网站? 一份 ...

  6. 一文带你通俗理解23种软件设计模式(推荐收藏,适合小白学习,附带C++例程完整源码)

    作者:翟天保Steven 版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处 一.设计模式是什么? 设计模式是为了解决在软件开发过程中遇到的某些问题而形成的思想.同一场景有多 ...

  7. .NET设计模式(1): 简单工厂模式

    .NET设计模式(1): 简单工厂模式 最近一直在看设计模式,想把自己的学习笔记与大家分享一下,如果能帮助大家的话,我会非常高兴,同时也欢迎大家指出里面的不足.园子里其实关于此类文章已经很多了,如果d ...

  8. JS常用的设计模式(2)——简单工厂模式

    JS常用的设计模式(2)--简单工厂模式 简单工厂模式是由一个方法来决定到底要创建哪个类的实例, 而这些实例经常都拥有相同的接口. 这种模式主要用在所实例化的类型在编译期并不能确定, 而是在执行期决定 ...

  9. 【系统架构设计师】软考高级职称,一次通过,倾尽所有,2016年下半年系统架构设计师考试论文真题(论述软件设计模式技术及应用)

    [系统架构设计师]软考高级职称,一次通过,倾尽所有,看完这篇就够了,学习方法和技巧这里全都有. 2016年下半年系统架构设计师考试论文真题(论述软件设计模式技术及应用) 论软件设计模式及其应用 软件设 ...

  10. 软件设计模式从何而来?------“抄袭来的” 设计模式

    博主:爱码叔 个人博客站点: icodebook 公众号:漫话软件设计 专注于软件设计与架构.技术管理.擅长用通俗易懂的语言讲解技术.对技术管理工作有自己的一定见解.文章会第一时间首发在个站上,欢迎大 ...

最新文章

  1. 一份完整的数据科学竞赛指南!
  2. Spring-整合多个配置文件
  3. 集合数百个常用工具类集合,V2.3.10.104
  4. Sqlserver高版本还原到低版本方法(Sqlserver2012到SqlServer2008 R2)
  5. EventBus设计与实现分析——事件的发布
  6. 迭代求斐波那契数列python_python中的迭代器(以斐波那契数列为主讲解)
  7. 【Redis】有序集合的交集与并集
  8. poi生成word不可以修改_操作不懂技术就可以做小程序无限生成平台的创业项目实操教程...
  9. 敏捷开发 我的经验(一)基本概念
  10. jsp网页实现自动刷新和自动跳转页面
  11. 更改appstore开发商名字
  12. RegSetValueEx 计算WCHAR字符长度 wcslen
  13. CSDN免费快速获得积分和直接获取下载码的几个办法,亲测有效区
  14. matlab2014a中输入中文显示不出来,显示的是方框
  15. wps软件打不开共享超链接_wps excel 超链接 打不开 怎么解决?
  16. 常用排序:冒泡排序与快速排序详解,看完这篇就够了!风马博客
  17. 计算机技术相关职业资格证书,关于对持有计算机信息高新技术考试合格证书人员配发国家职业资格证书的通知...
  18. 袁萌浅谈C919大飞机(二)
  19. LogStash 7.x com.mysql.cj.jdbc.Driver not loaded的解决方法
  20. 博览安全圈:中学教材现淫秽网站孰之过

热门文章

  1. 直角四面体面积公式推导
  2. 初学者学习哪种编程语言比较适合呢?
  3. 360桌面整理计算机图标,电脑界面上的图标被360清理掉了,怎么恢复呢?
  4. 计算机硬盘用u盘维修,硬盘坏道怎么修复-用U盘启动盘工具
  5. 寄昙说 剑子仙迹 天之佛
  6. matlab用直接三角分解法求解方程式,数值分析中直接三角分解法matlab程序.pdf
  7. 没有域名能不能申请企业邮箱?
  8. 巧用Excel函数进行数据转置
  9. 搜索引擎优化内容及方法
  10. macOS 桌面应用 图标制作教程