面向对象和设计模式(4)-- 设计模式之行为型

策略模式、模板方法模式、观察者模式、迭代模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。


1、策略模式( Strategy )

      定义个策略接口,不同的实现类提供不同的具体策略算法, 同时它们之间可以互相替换。

IStrategy 接口定义了策略方法,Strategy1 和 Strategy2 通过实现 IStrategy 提供不同的策略,而 User 组合了 IStrategy ,可以通过给 User 对象设置不同具体实现类来让其获得不同的策略。

实现示例代码:

/**

 *商人

 */

public class BusinessMan{

  privateTransportationStrategy strategy;

  public BusinessMan(TransportationStrategy strategy) {

    this.strategy =strategy;

  }

  public void changetStrategy(TransportationStrategy strategy) {

    this.strategy =strategy;

  }

  public void transport() {

    this.strategy.go();

  }

}

/**

 *交通方式策略

 */

@FunctionalInterface

public interface TransportationStrategy{

  void  go();

}

/**

 *乘飞机

 */

public class TransportationAirplane implements TransportationStrategy{

  private static final Logger LOGGER = LoggerFactory.getLogger(TransportationAirplane.class);

  @Override

  public void go() {

    LOGGER.info("乘飞机从北京去广州");

  }

}

/**

 *乘火车

 */

public class TransportationTrain implements TransportationStrategy{

  private static final Logger LOGGER = LoggerFactory.getLogger(TransportationTrain.class);

  @Override

  public void go() {

    LOGGER.info("乘高铁从北京去上海");

  }

}

/**

 *驾车

 */

public class TransportationVehicle implements TransportationStrategy{

  private static final Logger LOGGER = LoggerFactory.getLogger(TransportationVehicle.class);

  @Override

  public void go() {

    LOGGER.info("驾车从北京去天津");

  }

}

/**

 * Strategy

 */

public class Application{

  public static void main(String[] args) {

    BusinessMan man= new BusinessMan(newTransportationAirplane());

    man.transport();

    man.changetStrategy(newTransportationTrain());

    man.transport();

    man.changetStrategy(newTransportationVehicle());

    man.transport();

  }

}


2、模板方法模式( Template )

      定义一个操作的算法骨架, 并将一些步骤延迟到子类中。

AbsTemplate 抽象类中定义了一系列的方法,其中外界唯一能调用的 operation() 方法是 final 的(即不可重写),在该方法中分别调用了 first() 、second() 、third() 方法(即搭好算法框架),子类通过继承抽象类重写不同的方法来添加各自的行为。

实现示例代码:

/**

 *学生

 */

public class Student{

  private LearningMethod method;


  public Student(LearningMethod method) {

    this.method =method;

  }


  /**

   *学习

   *

   *@param description 状态

   *@paramadviser    

  请教对象

   */

  public void learn(String description, String adviser) {

    method.learn(description, adviser);

  }


  /**

   *更换学习方法

   *

   *@param method

   */

  public void changeMethod(LearningMethod method) {

    this.method =method;

  }

}

/**

 *学习方法的抽象类

 */

public abstract class LearningMethod{

  private static final Logger LOGGER = LoggerFactory.getLogger(LearningMethod.class);


  /**

   *预习效果

   *

   *@return

   */

  protected abstract String preLearning();


  /**

   *状态

   *

   *@param description 学习状态

   */

  protected abstract void Learning(String description);


  /**

   *请教对象

   *

   *@param adviser 请教对象

   */

  protected abstract void afterLearning(String adviser);


  /**

   *学习过程

   *

   *@param description 听课状态

   *@paramadviser    

  请假对象

   */

  public void learn(String description, String adviser) {

    String preLearningResult=preLearning();

    LOGGER.info("{}",  preLearningResult);

    Learning(description);

    afterLearning(adviser);

  }

}

/**

 *消极的学习方法

 */

public class NegativeLearinngMethod extends LearningMethod{

  private static final Logger LOGGER = LoggerFactory.getLogger(NegativeLearinngMethod.class);


  @Override

  protected String preLearning() {

    return "几乎没有预习,对上课要学的内容一无所知";

  }


  @Override

  protected void Learning(String description) {

    LOGGER.info("学习状态:{}", description);

  }


  @Override

  protected void afterLearning(String adviser) {

    if  (!adviser.equals("")) {

      LOGGER.info("只有很少的知识点没有听懂,于是找{}提问", adviser);

    }

  }

}

/**

 *积极的学习方法

 */

public class PositiveLearningMethod extends LearningMethod{

  private static final Logger LOGGER = LoggerFactory.getLogger(PositiveLearningMethod.class);


  @Override

  protected String preLearning() {

    return "预习到位,为听课打下很好的基础";

  }


  @Override

  protected void Learning(String description) {

    LOGGER.info("学习状态:{}", description);

  }


  @Override

  protected void afterLearning(String adviser) {

    if  (!adviser.equals("")) {

      LOGGER.info("只有很少的知识点没有听懂,于是找{}提问", adviser);

    }

  }

}

/**

 * Template method

 */

public class Application{

  private static final Logger LOGGER = LoggerFactory.getLogger(Application.class);


  public static void main(String[] args) {

    Student student= new Student(newPositiveLearningMethod());

    student.learn("上课走神", "同学");

    LOGGER.info("更换学习方法");

    student.changeMethod(newNegativeLearinngMethod());

    student.learn("认证听讲", "老师");

  }

}


3、观察者模式( Observer )

        定义了一种一对多的依赖关系,让多个观察者对象同时监听某一主题对象,在它的状态发生变化时,会通知所有的观察者。

先将 Observer 注册到 Observable ,那么当 Observable 状态改变时会通知它持有的所有 Observer ,对了,最好 Observable 中的 mList 的泛型是 WeakReference ,防止内存泄漏。

实现示例代码:

/**

 *一天中的几个时间点

 */

public enum TimePoint{

  MORNING("早晨"), NOON("中午"), AFTERNOON("下午"), EVENING("晚上");

  privateString name;


  TimePoint(String name)  {

    this.name =name;

  }


  @Override

  public String toString() {

    returnname;

  }

}

/**

 *时间观察者接口

 */

public interface TimeObserver{

  void  update(TimePoint time);

}

/**

 *时间

 */

public class Time{

  private static final Logger LOGGER = LoggerFactory.getLogger(Time.class);


  privateTimePoint point;

  private Listobservers;


  public Time() {

    this.point = TimePoint.MORNING;

    observers= new ArrayList<>();

  }


  public void addObserver(TimeObserver observer) {

    observers.add(observer);

  }


  public void removeObserver(TimeObserver observer) {

    observers.remove(observer);

  }


  public void passing() {

    TimePoint[] points =  TimePoint.values();

    point= points[(point.ordinal()

  + 1) % points.length];

    LOGGER.info("时间来到了{}", point);

    notifyObservers();

  }


  public void notifyObservers() {

    for  (TimeObserver observer :observers) {

      observer.update(point);

    }

  }

}

/**

 *北方人

 */

public class Northern implements TimeObserver{

  private static final Logger LOGGER = LoggerFactory.getLogger(Northern.class);


  @Override

  public void update(TimePoint time) {

    LOGGER.info("北方人吃饭了");

    switch(time) {

      case MORNING:

        LOGGER.info("煎饼果子");

        break;

      case NOON:

        LOGGER.info("炸酱面");

        break;

      case AFTERNOON:

        LOGGER.info("牛奶");

        break;

      case EVENING:

        LOGGER.info("包子");

        break;

      default:

        break;

    }

  }

}

/**

 *南方人

 */

public class Southern implements TimeObserver{

  private static final Logger LOGGER = LoggerFactory.getLogger(Southern.class);


  @Override

  public void update(TimePoint time) {

    LOGGER.info("南方人吃饭了");

    switch(time) {

      case MORNING:

        LOGGER.info("热干面");

        break;

      case NOON:

        LOGGER.info("米饭");

        break;

      case AFTERNOON:

        LOGGER.info("茶");

        break;

      case EVENING:

        LOGGER.info("鱼");

        break;

      default:

        break;

    }

  }

}

/**

 * Observer

 */

public class Application{

  public static void main(String[] args) {

    Time time= newTime();

    time.addObserver(newNorthern());

    time.addObserver(newSouthern());


    time.passing();

    time.passing();

    time.passing();

    time.passing();

    time.passing();

    time.passing();

    time.passing();

    time.passing();

    time.passing();

  }

}


4、命令模式( Command )

        将一个请求封装成为一个对象, 使可以用不同的请求对客户进行参数化。

Action 封装了具体行为,Command 封装了 Action 并提供空方法 execute() ,它的子类通过重写该方法可在方法里调用 mAction 不同行为达到封装命令的目的,最后 Client 封装了一系列的 Command 对象,并可以通过 notify() 方法一个接着一个调用所持有 Command 对象们的 execute() 方法达到给 Action 传达命令的目的。

实现示例代码:

/**

 *字体颜色

 */

public enum Color{

  RED("红"), BLACK("黑");

  private String name;


  Color(String name)  {

    this.name =name;

  }


  @Override

  public String toString() {

    returnname;

  }

}

/**

 *字体大小

 */

public enum Size{

  LARGE("大"), SMALL("小");

  private String name;


  Size(String

  name) {

    this.name =name;

  }


  @Override

  public String toString() {

    returnname;

  }

}

/**

 *字体抽象类

 */

public abstract class AbstractFont{

  private static final Logger LOGGER = LoggerFactory.getLogger(AbstractFont.class);

  privateSize size;

  privateColor color;


  public Size getSize() {

    returnsize;

  }


  public void setSize(Size size) {

    this.size =size;

  }


  public Color getColor() {

    returncolor;

  }


  public void setColor(Color color) {

    this.color =color;

  }


  @Override

  public abstract String toString();


  /**

   *打印当前状态

   */

  public void printStatus() {

    LOGGER.info("字体当前状态为:\t字体大小:{}\t颜色:{}", getSize(),  getColor());

  }

}

/**

 *字体

 */

public class RegularScript extends AbstractFont{

  public RegularScript() {

    setColor(Color.BLACK);

    setSize(Size.SMALL);

  }


  @Override

  public String toString() {

    return "楷体";

  }

}

/**

 *命令抽象类

 */

public abstract class Command{

  public abstract void execute();

  public abstract void undo();

  public abstract void redo();


  @Override

  public abstract String toString();

}

/**

 *设置字体为大号

 */

public class Enlarge extends Command{

  private finalAbstractFont font;

  private finalSize oriSize;


  public Enlarge(AbstractFont font) {

    this.font =font;

    oriSize= font.getSize();

  }


  @Override

  public void execute() {

    font.setSize(Size.LARGE);

  }


  @Override

  public void undo() {

    font.setSize(oriSize);

  }


  @Override

  public void redo() {

    execute();

  }


  @Override

  public String toString() {

    return "设置字体为大号";

  }

}

/**

 *设置字体颜色为红色的命令

 */

public class Rubify extends Command{

  private finalAbstractFont font;

  private finalColor oriColor;


  public Rubify(AbstractFont font) {

    this.font =font;

    oriColor= font.getColor();

  }


  @Override

  public void execute() {

    font.setColor(Color.RED);

  }


  @Override

  public void undo() {

    font.setColor(oriColor);

  }


  @Override

  public void redo() {

    execute();

  }


  @Override

  public String toString() {

    return "设置字体为红色";

  }

}

/**

 *打字员

 */

public final class Typist{

  private static final Logger LOGGER = LoggerFactory.getLogger(Typist.class);

  private Deque redoStack = new LinkedList<>();

  private Deque undoStack = new LinkedList<>();


  public void cast(Command command, AbstractFont font) {

    LOGGER.info("{}正在处理字体,命令为:{},处理的字体为:{}", this, command, font);

    command.execute();

    undoStack.offerLast(command);

  }


  public void undo() {

    if  (!undoStack.isEmpty()) {

      Command previousCommand= undoStack.pollLast();

      redoStack.offerLast(previousCommand);

      LOGGER.info("{}正在进行撤销操作,命令为:{}", this, previousCommand);

      previousCommand.undo();

    }else{

      LOGGER.info("没有可以撤销的操作了");

    }

  }


  public void redo() {

    if  (!redoStack.isEmpty()) {

      Command previousCommand= redoStack.pollLast();

      undoStack.offerLast(previousCommand);

      LOGGER.info("{}正在进行重做操作,命令为:{}", this, previousCommand);

      previousCommand.redo();

    }else{

      LOGGER.info("没有可以重做的操作了");

    }

  }


  @Override

  public String toString() {

    return "打字员";

  }

}

/**

 * Command

 */

public class Application{

  public static void main(String[] args) {

    Typist sizeTypist= newTypist();

    Typist colorTypist= newTypist();

    RegularScript font= newRegularScript();


    Command rubify= newRubify(font);

    Command enlarge= newEnlarge(font);


    font.printStatus();


    // 设置字体颜色

    colorTypist.cast(rubify, font);

    font.printStatus();


    // 设置字体大小

    sizeTypist.cast(enlarge, font);

    font.printStatus();


    // 撤销颜色更改

    colorTypist.undo();

    font.printStatus();

    colorTypist.undo();


    // 撤销大小更改

    sizeTypist.undo();

    font.printStatus();

    sizeTypist.undo();


    // 字体颜色重做

    colorTypist.redo();

    font.printStatus();

    colorTypist.redo();


    // 大小重做

    sizeTypist.redo();

    font.printStatus();

    sizeTypist.redo();

  }

}

你可能感兴趣的:(面向对象和设计模式(4)-- 设计模式之行为型)