hf-ch7-10 外观,模板,迭代器,状态模式

ch7 外观模式

0. 序
  1. 外观与适配器是不同的模式

  2. 装饰者模式?适配器模式?

    装饰着模式是把对象包装起来,赋予新的职责。

    适配器模式是对现有对象进行包装,让它的接口看起来像是别的东西。这可以把类的接口转换成想要的接口。

  3. 适配器模式 --适配器 应用

在这里插入图片描述

这样只需要去添加适配器的代码了。不需要改变原有的代码(设计原则)

现实中的例子:插头与转换头。

适配器定义:将一个类的接口转换成客户期望的另一个接口,适配器让原本接口不兼容的类可以合作无间。

这一部分的内容比较容易理解,以下仅附上练习代码。

1. 适配器Exercise Code
/**
 * 鸭子接口
 * @author chain
 */
public interface Duck {
    /**
     * 叫
     */
     void  quack();

    /**
     * 飞行方法
     */
    void fly();
}
/**
 * @author chain
 * @date 2020/4/9
 * @description 火鸡的基类
 */
public interface Turkey {

    /**
     * 火鸡的咕咕叫方法
     * @author chain
     * @date 2020/4/9
     * @description
     */
    void gobble();

    /**
     * 火鸡的飞行方法
     * @author chain
     * @date 2020/4/9
     *
     */
    void  fly();
}
/**
 * @author chain
 * @description 火鸡实现类
 * @date 2020/4/9
 */
public class WildTurkey implements Turkey {
    @Override
    public void gobble() {
        System.out.println("火鸡 叫 gobble");
    }

    @Override
    public void fly() {
        System.out.println("火鸡 飞");
    }
}

我需要做的: 把一只火鸡 包装成一只鸭子 。 很显然,火鸡与鸭子接口不同,不能直接拿来用,那么就增加一个适配器,该适配器接受火鸡,输出鸭子!

/**
 * @author chain
 * @description 适配器类 Turkey --> Duck
 * @date 2020/4/9
 */
public class TurkeyAdapter implements Duck {
    /**
     * 接受的火鸡 需要转换的接口
     */
    Turkey turkey;

    public TurkeyAdapter(Turkey turkey) {
        this.turkey = turkey;
    }

    @Override
    public void quack() {
        //把火鸡的叫方法伪装成鸭子叫方法
        turkey.gobble();
    }

    @Override
    public void fly() {
        turkey.fly();
    }

    public static void main(String[] args) {
        //测试代码
        Turkey wildTurkey=new WildTurkey();
        //这里已经把一只火鸡伪装成鸭子
        Duck turkeyAdatpter = new TurkeyAdapter(wildTurkey);
        turkeyAdatpter.fly();
    }
}

很显然,适配器模式就是在外面套了一层接口,里面对应的方法的实现仍然是被包装的对象的方法

2. 外观模式

装饰者模式:不改变接口,但假如责任

适配器模式:将一个接口转换成另一个接口

外观模式:让接口更简单

外观模式更像是把许多复杂的接口经过包装,变成一个简单的接口。p262实例:在看电影前,要打开电视,设置dvd, 设置灯光等一系列操作,这些都是子系统的功能;采用外观模式,将上述子系统功能封装成一个新的接口,那么直接一键就可以调用上述子系统(组合的方式)功能。

**外观模式:**提供了一个统一的接口,用来访问子系统中的一群接口。外观定义了一个高层接口,让子系统更容易使用。
在这里插入图片描述
**新的OO原则:**最少知识原则:减少对象之间的交互,只留下几个"密友"---->不要让太多类耦合

ch8 模板方法模式–封装算法

0. 序

这个模式有点类似于 把变化的代码抽离封装,但是 这个模式是给变化的方法定义了一个骨架,并且将该骨架的实现延迟到子类中。这个模式就是来创建一个算法的模板,其中任何步骤都可以是抽象的,抽象部分将由子类实现,可以确保算法的数据结构保持不变。

在这里插入图片描述

package 模块封装模式;

/**
 * @author chain
 * @description
 * @date 2020/4/11
 */
public abstract class AbstarctClass1 {
    /**
     * 封装代码模板 且为final 防止子类修改这个算法模板
     * @author chain
     * @date 2020/4/11
     */
    final void templateMethod(){
        primitiveOperation1();
        primitiveOperation2();
        concreteOperation();
        hook();
    }
    /**
     * 操作1 由子类实现
     * @author chain
     * @date 2020/4/11
     */
    abstract void primitiveOperation1();

    /**
     * 操作2 由子类实现
     * @author chain
     * @date 2020/4/11
     */
    abstract void  primitiveOperation2();

    /**
     * 子类的共同的代码
     * @author chain
     * @date 2020/4/11
     */
    void concreteOperation(){
        //省略实现代码
    }
     void hook(){
        //什么都不做 由子类去覆盖
         //这个好处可以让子类去向模板方法添加新的方法
    }
}

策略模式和模板模式都封装算法,策略使用组合,模板使用继承,工厂方法是模板方法的一种特殊版本。

ch9 迭代器与组合

0. 序

迭代器 --Java中的Iterator 可以在不用了解集合内部实现的情况下,遍历集合

其他:略

ch10 状态模式

0. 序

策略模式围绕可以互换的算法来创建成功业务。状态模式通过改变对象内部的状态来帮助对象控制自己的行为。

对于书上的糖果机的例子,在不加入“赢家模式”的时候代码是很简单易懂的,就是对于糖果机的几种状态,每次操作都去根据当前的状态做if-else操作即可。加入“赢家模式”后,显然如果要对之前的代码进行维护,修改的成本是很大的。因此,摆脱旧的条件代码,将动作委托到状态类上(封装变化),让状态来实现自己的行为。

对于状态抽象出一个接口State, 实现有SoldState, SoldOutState, NoQuarterState, HasQuarterState, WinnerState ,实现的子类各自去实现自己在状态下的操作方法即可。

实际上,我们对状态进行改变的话,糖果机的行为会因为状态的改变而改变。每一个状态又是独立的,方便维护与扩展

2. Code

状态模式的一些代码

状态基类

package 状态模式;

/**
 * 状态接口
 *
 * @author chain
 * @date 2020/4/12
 */
public interface State {
    /**
     * 插入
     *
     * @author chain
     * @date 2020/4/12
     */
    void insertQuarter();

    /**
     * 退钱
     *
     * @author chain
     * @date 2020/4/12
     */
    void ejectQuarter();
    /**
     * 转动把手
     * @author chain
     * @date 2020/4/12
     */
    void  turnCrank();

    /**
     * 售完
     * @author chain
     * @date 2020/4/12
     */
    void dispense();
}

状态实现类(只列出一种)

package 状态模式;

import java.util.Random;

/**
 * @author chain
 * @description 未投钱状态
 * @date 2020/4/12
 */
public class HasQuarterState implements State {
    Random randomWinner=new Random(System.currentTimeMillis());
    GumballMachine gumballMachine;

    public HasQuarterState(GumballMachine gumballMachine) {
        this.gumballMachine = gumballMachine;
    }

    @Override
    public void insertQuarter() {
        System.out.println("you has inserted a quarter");

    }

    @Override
    public void ejectQuarter()
    {
        gumballMachine.setState(gumballMachine.getNoQuarterState());
        System.out.println("you haven't inserted a quarter ");
    }

    @Override
    public void turnCrank() {

        System.out.println("you turned...");
        int winner=randomWinner.nextInt(10);
        if (winner==0&&gumballMachine.getCount()>1){
            gumballMachine.setState(gumballMachine.getWinnerState());
        }else {
            gumballMachine.setState(gumballMachine.getSoldState());
        }

    }

    @Override
    public void dispense() {
        System.out.println("no gumball dispensed");
    }
}

机器类,状态组合

package 状态模式;

/**
 * @author chain
 * @description
 * @date 2020/4/12
 */
public class GumballMachine {

    private State soldOutState;
    private State noQuarterState;
    private State hasQuarterState;
    private State soldState;

    public State getWinnerState() {
        return winnerState;
    }

    /**
     * 十次抽中一次的赢家状态
     */
    private State winnerState;

    /**
     * 初始状态 为soldOutState
     * state为糖果机的状态
     */
    private State state=soldOutState;
    int count=0;

  public GumballMachine(int numberGumballs){
      soldOutState=new SoldOutState(this);
      noQuarterState=new NoQuarterState(this);
      hasQuarterState=new HasQuarterState(this);
      soldState=new SoldState(this);
      winnerState=new WinnerState(this);
      this.count=numberGumballs;
      if (numberGumballs>0){
          state=noQuarterState;
      }
  }

    public void insertQuarter(){
      state.insertQuarter();
    }
    public void  ejectQuarter(){
      state.ejectQuarter();
    }
    public void turnCrank(){
      state.turnCrank();
      state.dispense();
    }

    public void setState(State state) {
        this.state = state;
    }
    void releaseBall(){
      System.out.println("a gumball comes rolling out the slot...");
      if (count!=0){
          count--;
      }
    }
    //其他方法
	//	getter setter toString


    public static void main(String[] args) {
        GumballMachine gumballMachine=new GumballMachine(5);
        System.out.println("糖果机构造完成: "+ gumballMachine);
        gumballMachine.insertQuarter();
        gumballMachine.turnCrank();

        System.out.println("当前糖果机:"+gumballMachine);

        gumballMachine.insertQuarter();
        gumballMachine.turnCrank();

        System.out.println("当前糖果机:"+gumballMachine);

        gumballMachine.insertQuarter();
        gumballMachine.turnCrank();

        System.out.print(gumballMachine);

    }
}

通过这些代码,很容易观察出 不使用状态模式的缺点,在大量的if - else 情况下修改很大,没有弹性。使用状态模式,将每一个状态的动作交给该状态去完成,修改只关心状态本身的功能的实现,而机器Machine只是组合一下状态并根据状态的转换来实现动作变化。
在这里插入图片描述

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值