1.需求分析:

  1. 有一款《Duck》的游戏,游戏中存在很多的鸭子,主要会
  2. 鸭子有很多种,比如野鸭家禽鸭木头鸭小黄鸭(一种放在浴室中的玩具)。
  3. 也许以后还会有更多的奇怪的鸭子,比如火箭鸭等等。

2.程序设计(此处主要关心fly()和quack()操作):

1.使用继承来实现对于更改操作的灵活程度:

在一个Duck基类中考虑一个鸭子应该具有的所有的通用的功能,实现鸭子们确定的共有的功能,非共有的部分,要求交给子类实现。
image.png
存在的问题:

  1. 所有的子类都被强加了通用的fly()quack()等操作了。
  2. 对于a,为了让WoodenDuck等,不能fly()quack(),只能在子类中重写方法,覆盖基类中的方法。
  3. 部分代码将在多个子类中重复。例如,WoodenDuckToyDuck都不会飞,但要重写两次fly()
  4. 难以在运行时改变鸭子们的行为。
  5. 对基类的改变将影响所以子类。

    2.抽象出部分功能成为接口以实现更加灵活的更改操作:

    让“某些”而不是“全部”的鸭子可飞、可叫。在此,
    image.png
    存在的问题:

  6. 部分代码将在多个子类中重复。所以仍然难以复用。例如WildDuckHomeDuck都会quack()且相同,但是其代码将会重复两次。

    3.将抽象出的部分功能封装起来,尝试使得他们可以相互组合和替换。

    ⭐设计原则:找出应用中可能变化之处,把他们独立出来,以便以后可以轻易地改动或扩充此部分,而不影响不需要变化的其他部分。

    对于本次需求,已知鸭子的fly()quack()会随着具体是什么鸭子的不同而不同。
    所以应该将他们从基类Duck里剥离。基于面向对象原则,被剥离的部分将作为 类 或者 接口 以存在

    ⭐设计原则:面向接口(或抽象)编程,而不是针对具体实现编程。

    fly()quack()是操作,他们变成 类 或者 接口 后没有属性,因此,本次需求使用接口。
    image.png
    fly()就此变成接口Fly,它具体的实现是NormalFlyBriskFlyCanNotFly
    此时,鸭子的 飞 和 叫 已经独立于Duck,所以,Duck需要委托原来的两个操作给现在的FlyQuack接口:

  7. 首先,在Duck类中添加两个 操作的实例变量,以便于后期指定操作接口的具体实现。

  8. Duck中写好调用 操作的实例变量 中方法的方法。
  9. 考虑是否设置setFlyAction()等函数来使得鸭子能动态的改变 飞 等具体操作。

image.png
现在的Duck

  1. public abstract class Duck {
  2. protected Fly howToFly;
  3. protected Quack howToQuack;
  4. public abstract void display();
  5. public void flyPerform(){ //实现fly
  6. howToFly.flyAction();
  7. }
  8. public void quackPerform(){ //实现quack
  9. howToQuack.quackAction();
  10. }
  11. public void setFlyAction(Fly now){
  12. this.howToFly=now;
  13. }
  14. public void setQuackAction(Quack now){
  15. this.howToQuack=now;
  16. }
  17. }

抽象出来的、频繁变动的接口Fly

  1. public interface Fly {
  2. public void flyAction();
  3. }

具体的Fly实现、真正的 飞 操作的执行者、Duck最终委托的对象:

  1. public class BriskFly implements Fly {
  2. @Override
  3. public void flyAction() {
  4. System.out.println("BriskFly");
  5. }
  6. }

⭐设计原则:多用组合,少用继承。

在本次需求中鸭子的真正操作,由最终DuckFly howToFly=具体的Fly对象;决定,还可以使用Duck中提供的public void setFlyAction(Fly now);,来动态改变具体的Fly。而不再是使用继承来一个个重写。也许,写具体的Fly实现也会有些许麻烦,但是,我“有选择”一定比我“已经是”更好。