学习设计原则之前先了解java OO基础:
几个重要面向对象设计原则:
一. 一步步开始设计类图
针对鸭子 我们设计类结构及之间的关系 。
按照一般的想法,我们会设计一个超类Duck,方法有quack(),swim()等,其他子类鸭子统统继承这个超类Duck,这样子类就不用重新写相关方法,增加了代码复用性 。类图如下:
文章插图
此时如果想增加一个行为fly,把他添加到Duck超类,那么子类同样都可以继承 。但是如果有一只玩具鸭他不会飞,那么在超累Duck中添加fly方法,就会有问题了,玩具鸭不该具有的飞行fly行为,却被玩具鸭从Duck类继承了!
你又想到,可以使用继承然后覆盖重写超类的方法,玩具鸭重写fly方法,变成不会飞,这样确实可行!但如果有一只鸭子不会飞,但又会瓜瓜叫,又有一只鸭子会飞但不会瓜瓜叫…如果有类似的鸭子n只,岂不是每个类都需要重写覆盖一些方法么?可见使用继承Duck,这种方式有一些死板,超类Duck的行为,继承的子类不一定都具有Duck的行为,而且代码在子类中都会有重复,且子类鸭子的行为不能轻易改变 。
我们说到面向接口编程,少用继承,把变化的部分拿出来封装 。那么我们把可能会发生变化的行为 Fly行为和Quak叫的行为都从Duck超类拿出来,形成两个接口 。使各种各样的fly的行为,如,,或者叫的行为,如Quack方式叫,方式叫,去实现这两个接口 。
文章插图
这样一来,飞行的行为和叫的行为被单独拿出来了,已经与Duck类无关,弹性增加 。
上方已经把和从Duck超类中剥离,那么怎样让Duck类使用到这两个行为呢?采用委托代理的方式,在Duck类中添加这两个接口,通过这两个接口执行具体的fly行为或quack行为 。Duck类如图:
文章插图
子类鸭子如何设定和的实例呢?
通过构造的方式,来实例化具体的行为(这种方式有些死板,因为具体的行为是静态构造的,稍后我们通过其他方法使之能动态改变)
构造方式如下:
/*这是一直会吱吱叫和会飞行的鸭子*/public class OneFlyDuck2 extends Duck {public OneFlyDuck2() {quackBehavior = new QuackWithSqueak(); //flyBehavior = new FlyWithWings(); // 用翅膀飞行}}
二.代码编写: 2.1第一次编码实现:
【java 设计模式之2策略模式】Duck超类:
鸭子都有的固定的属性或者行为*/public class Duck {FlyBehavior flyBehavior;//声明两个行为QuackBehavior quackBehavior;//都会游泳public void swim(){System.out.println("I can swim");};// 游泳public void performFlyBehavior(){flyBehavior.fly();//使用flyBeahvior接口代理执行飞的具体行为}public void performQuackBehavior(){quackBehavior.quack();//使用QuackBehavior接口代理执行叫的具体行为}
:
/*各种飞的接口 */public interface FlyBehavior{void fly();//各种飞}
:
/*叫的接口*/public interface QuackBehavior {void quack();//叫}
实现接口:
public class FlyWithWings implements FlyBehavior {@Overridepublic void fly(){System.out.println("I fly with Wings!");}}
实现接口:
public class FlyWithNoWay implements FlyBehavior {@Overridepublic void fly(){System.out.println("I fly with noWay!");}}
- S32K144调用空指令NOP
- Java多线程之原子操作类
- 一 javaweb总结--文件上传和下载
- 【一笔画完】通关路径算法的Java代码实现V2.0
- 《从点子到产品》读书笔记之产品价值和用户痛点
- 二 Elasticsearch 基础之安装
- 10个ai算法常用库java版
- 【学习摘记】马士兵JAVASCRIPT_课时2-7_JS小例子大全
- 【CSDN博客之星】专访陈勇: 敏捷开发现状及发展之路
- LwIP 之二 网络接口 netif(netif.c、ethernetif