设计模式(一)继承+组合

package com.wfl.designmode;

/**
 * 使用接口设计一个抽象功能方法,让具体类去实现接口中的不同方法;
 *
 */

/*
   需求:模拟鸭子叫、游泳、展示自己的外观、满足鸭子会飞,但是有些鸭子,比如橡胶鸭不能飞,只会咯吱咯吱叫

 * 分析:实现接口的方式是首先想到的,可以让所有不同的鸭子都会叫、游泳、展示自身外观
 *
 * 解决方案1:那么最简单的方式就是在接口中添加flay方法,并且方所有的实现类去实现它,橡胶鸭子要覆盖这个方法设置为不能飞,quack方法设置为咯吱咯吱
 * 缺点:上面好像可以实现,但是不利于扩展,每当要增加其他鸭子,都要被迫检查可能要覆盖fly和quark(),比如诱饵鸭子不会飞、不会叫。。。
 * 总结:单纯使用实现+接口覆盖这种方式实现多种不同类型的实例是不友好的,加大了代码量,不好维护
 */
public class FirstMode {
}

/**
 * 第一步:定义鸭子接口,所有的鸭子实现类实现这个接口
 */
interface duckInterface{
    /**
     * 鸭子叫
     */
    void quack();

    /**
     * 鸭子游泳
     */
    void swim();

    /**
     * 鸭子展示自己的外观
     */
    void display();
}

/**
 * 第二步:实现具体的鸭子类型
 */
class MallardDuck implements duckInterface{

    @Override
    public void quack() {
        System.out.println("MallardDuck quack");
    }

    @Override
    public void swim() {
        System.out.println("MallardDuck swim");
    }

    @Override
    public void display() {
        System.out.println("MallardDuck display");
    }
}

/**
 * 第二步:实现具体的鸭子类型
 * ... 可以创建N多个鸭子类,这些鸭子都会游泳、叫、特技
 */
class RedheadDuck implements duckInterface{

    @Override
    public void quack() {
        System.out.println("RedheadDuck quack");
    }

    @Override
    public void swim() {
        System.out.println("RedheadDuck swim");
    }

    @Override
    public void display() {
        System.out.println("RedheadDuck display");
    }
}



/* 解决方案2:将方法归类,一种是鸭子的公共的特征方法,比如display、swim;另外一种是特殊的方法,比如flay、quack;让鸭子去根据自身的情况去实现这两种接口
* 比如橡胶鸭子就不用实现flay方法所在的接口,
* 缺点:如果需要100个鸭子实体类,所有的鸭子类都去实现公共的接口,但是有许多鸭子实体类还需要稍微修改一下flay方法,代码无法复用。。。
* 总结:继承或实现的方式不能很好地解决问题,应为鸭子的行为在类中千变万化,让所有的鸭子都有这些行为是不恰当的。
*/

/**
 * 公共方法,鸭子都有外部特征display,都会游泳
 */
 class Duck{

     void swim(){
         System.out.println("HolledDuck swim");
    }

     void display(){
         System.out.println("HolledDuck red head");
     }
}

/**
 * 只有部分鸭子会飞、会叫
 */
interface Flayable{
    void flay();
}

interface Quackable{
    void quack();
}

/**
 * 100多种鸭子,都要重写下面的方法
 */
class HolledDuck extends Duck implements Flayable,Quackable{

    /**
     * 需要修改flay方法
     */
    @Override
    public void flay() {
        System.out.println("HolledDuck flay");
    }

    /**
     * 需要修改quack方法
     */
    @Override
    public void quack() {
        System.out.println("HolledDuck quack");
    }
}

/*
* 设计原则1:找出应用中可能需要变化的地方,把它们独立(抽取)出来,不要和那些不需要变化的代码混合在一起。
*
* 使用设计模式的方案:鸭子类不再实现flayable等这些接口,我们设计专门的类来实现flayable接口,这种专门的类称为行为类
*                  以前的鸭子类要实现行为类的功能,这种方式都依赖于子类的实现,被绑的死死地,
*                  鸭子的子类直接使用行为类,组合的方式,
* */


interface FlayBehavior{
    void flay();
}

/**
 * 实现了所有有翅膀的鸭子的飞行
 */
class FlayWithWings implements FlayBehavior{

    @Override
    public void flay() {
        System.out.println("鸭子的飞行");
    }
}

/**
 * 实现所有不会飞的鸭子的动作
 */
class FlayNoWay implements FlayBehavior{

    @Override
    public void flay() {
        System.out.println("什么都不做,不会飞");
    }
}


interface QuackBehavior{
    void quack();
}

/**
 * 实现真正的鸭子呱呱叫
 */
class Quack implements QuackBehavior{

    @Override
    public void quack() {
        System.out.println("鸭子呱呱叫");
    }
}

/**
 * 实现了橡皮鸭子吱吱叫
 */
class Squeak implements QuackBehavior{

    @Override
    public void quack() {
        System.out.println("橡皮鸭子吱吱叫");
    }
}

/**
 * 实现了不吭声的鸭子
 */
class MutaQuack implements QuackBehavior{

    @Override
    public void quack() {
        System.out.println("什么都不做,不会叫");
    }
}

/**
 * 优点:1.让飞行和呱呱叫的动作行为类被其他对象复用,这些行为与鸭子本身类无关
 *      2.当新增一些行为,不会影响到飞行和呱呱叫等,也不会影响到使用飞行类的鸭子类
 *      3。有了继承的复用好处,但是没有继承所带来的报复
 *
 * 具体实现:1.在Duck类中加入两个接口类型的实例变量,每个鸭子都会动态的设置这些变量,在运行时引用正确的行为类型
 */

class DDuck{

    public FlayBehavior flayBehavior;

    public QuackBehavior quackBehavior;

    /**
     * 鸭子对象不亲自处理呱呱叫的行为,而是委托给quackBehavior引用的对象
     * 想要呱呱叫就传Quack子类,想要吱吱叫就传Squeak,
     * 我们不用知道如何实现,只需要知道对象知道要怎样叫就行了
     */
    public void performQuack(){
        quackBehavior.quack();
    }

    public void performFlay(){
        flayBehavior.flay();
    }

    /**
     * !!!在鸭子子类中通过设定方法来设置鸭子的行为,而不是构造器内部实例化
     *
     */
    public void setFlayBehavior(FlayBehavior fb){
        flayBehavior = fb;
    }

    public void setQuackBehavior(QuackBehavior qb){
        quackBehavior = qb;
    }
}

/*
* 如何设置flayBehavior和quackBehavior
* 1.使用构造器
* 2.使用setter方法
* */

class MallardDDuck extends DDuck{
    /**
     * 应为MallardDDuck继承了DDuck,拥有两个实例变量
     * 这里是默认的行为
     */
    public MallardDDuck(){
        flayBehavior = new FlayWithWings();
        quackBehavior = new Quack();
    }

    /**
     * 鸭子的公共方法
     */
    public void display(){
        System.out.println("real Mallard Duck");
    }
}

/**
 测试类
 */

class testDuck{
    public static void main(String[] args) {
        DDuck mallred = new MallardDDuck();
        mallred.setFlayBehavior(new FlayNoWay());
        mallred.setQuackBehavior(new MutaQuack());
        mallred.performFlay();
        mallred.performQuack();
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值