设计模式——行为型

一、 模板方法模式

定义算法骨架,允许子类为一个或多个步骤提供实现

适用:

  • 一次性实现一个算法的不变部分,将可变行为留给子类
  • 各个子类中公共的行为被提取出来集中到公共父类中,避免代码重复

优点:

  • 提高复用性
  • 提高扩展性
  • 符合开闭原则

缺点:

  • 类数目增加
  • 增加系统实现的复杂度
  • 父类添加新抽象方法,子类也要实现
public abstract class ACourse {

	protected final void makeCourse() {
		this.makePPT();
		this.makeVideo();
		if (needWriteArticle()) {
			this.writeArticle();
		}
		this.packageCourse();
	}

	final void makePPT() {
		System.out.println("制作PPT");
	}

	final void makeVideo() {
		System.out.println("制作视频");
	}

	final void writeArticle() {
		System.out.println("编写手记");
	}

	// 钩子方法
	protected boolean needWriteArticle() {
		return false;
	}

	abstract void packageCourse();
}

public class FECourse extends ACourse {
	private boolean needWriteArticleFlag = false;

	@Override
	void packageCourse() {
		System.out.println("提供课程的前端代码");
		System.out.println("提供课程的图片等多媒体素材");
	}

	public FECourse(boolean needWriteArticleFlag) {
		this.needWriteArticleFlag = needWriteArticleFlag;
	}

	@Override
	protected boolean needWriteArticle() {
		return this.needWriteArticleFlag;
	}
}

二、 迭代器模式

提供一种方法,顺序访问一个集合对象中的各个元素,而不暴露对象的内部表示

适用:

  • 访问集合对象内容
  • 为遍历不同的集合结构提供统一接口

优点:

  • 分离了集合对象的遍历行为

缺点:

  • 类的个数成对增加
// 集合类
public interface CourseAggregate {

	void addCourse(Course course);

	void removeCourse(Course course);

	CourseIterator getCourseIterator();
}

public class CourseAggregateImpl implements CourseAggregate {

    private List courseList;

    public CourseAggregateImpl() {
        this.courseList = new ArrayList();
    }

    // remove add

    @Override
    public CourseIterator getCourseIterator() {
        return new CourseIteratorImpl(courseList);
    }
}

// 迭代器
public interface CourseIterator {
	Course nextCourse();

	boolean isLastCourse();
}

public class CourseIteratorImpl implements CourseIterator {

	private List courseList;
	private int position;
	private Course course;

	public CourseIteratorImpl(List courseList) {
		this.courseList = courseList;
	}

	@Override
	public Course nextCourse() {
		System.out.println("返回课程,位置是: " + position);
		course = (Course) courseList.get(position);
		position++;
		return course;
	}

	@Override
	public boolean isLastCourse() {
		if (position < courseList.size()) {
			return false;
		}
		return true;
	}
}

三、 策略模式

定义算法家族,分别封装,可以互相替换,算法的变化不影响用户

适用:

  • 有很多类,区别仅在于行为不同
  • 系统需要动态在几种算法中选择一种

优点:

扫描二维码关注公众号,回复: 10644349 查看本文章
  • 符合开闭原则
  • 避免使用多重条件转移
  • 提高算法的保密性和安全性

缺点:

  • 客户端需要知道所有策略类,并自行选择
  • 产生很多策略类
public class PromotionActivity {
	private PromotionStrategy promotionStrategy;

	public PromotionActivity(PromotionStrategy promotionStrategy) {
		this.promotionStrategy = promotionStrategy;
	}

	public void executePromotionStrategy() {
		promotionStrategy.doPromotion();
	}
}

// 策略
public interface PromotionStrategy {
    void doPromotion();
}

public class ManJianPromotionStrategy implements PromotionStrategy{
    @Override
    public void doPromotion() {
        System.out.println("满减促销,满200-20元");
    }
}

public class FanXianPromotionStrategy implements PromotionStrategy{
    @Override
    public void doPromotion() {
        System.out.println("返现促销,返回的金额存放到账户余额中");
    }
}

四、 解释器模式

给定一个语言,定义文法的一种表示,并定义一个解释器,解释该语言

适用:

  • 某个特定类型问题发生频率足够高

优点:

  • 语法由很多类表示,易于扩展

缺点:

  • 语法规则数目太多时,增加复杂度

五、 观察者模式

定义对象间一对多的依赖,多个观察者同时监听某一个主题对象,当主题变化时,所有观察者收到通知

适用:

  • 关联行为场景,建立触发机制

优点:

  • 观察者和被观察者之间建立抽象耦合
  • 广播通信

缺点:

  • 观察者间有过多的细节依赖,提高时间消耗及程序复杂度
  • 避免循环调用
// 主题
public class Subject {

	// 观察者数组
	private Vector<Observer> oVector = new Vector<>();

	public void addObserver(Observer observer) {
		this.oVector.add(observer);
	}

	public void deleteObserver(Observer observer) {
		this.oVector.remove(observer);
	}

	public void notifyObserver() {
		for (Observer observer : this.oVector) {
			observer.update();
		}
	}
}

public class ConcreteSubject extends Subject {

	// 具体业务
	public void doSomething() {
		// ...
		super.notifyObserver();
	}

}

// 观察者
public interface Observer {
	public void update();
}

public class ConcreteObserver implements Observer {

	@Override
	public void update() {
		System.out.println("收到消息,进行处理");
	}
}

六、 备忘录模式

保存对象状态,以便在适当时候恢复

适用:

  • 保存及恢复数据
  • 想要恢复到之前状态

优点:

  • 提供可恢复机制
  • 存档信息封装

缺点:

  • 资源占用
// 可以创建备忘录和恢复的普通对象
public class Originator {

	private String state;

	public Memento createMemento() {
		return new Memento(state);
	}

	public void restore(Memento memento) {
		this.state = memento.getState();
	}
}

// 备忘录
public class Memento {
	private String state;

	public Memento(String state) {
		this.state = state;
	}

	public String getState() {
		return state;
	}

	public void setState(String state) {
		this.state = state;
	}
}

// 备忘录管理者
public class Caretaker {
	private Memento memento;

	public Memento restoreMemento() {
		return memento;
	}

	public void storeMemengto(Memento memento) {
		this.memento = memento;
	}
}

七、 命令模式

将请求封装成对象,以便使用不同的请求

解决应用程序中对象的职责及通信方式

适用:

  • 请求调用者和请求接受者解耦
  • 需要抽象出等待执行的行为

优点:

  • 降低耦合
  • 容易扩展新命令或一组命令

缺点:

  • 增加类的数量,提高系统实现复杂度
// 命令
interface Command {
	void execute();
}

class LightOnCommand implements Command {
	Light light;

	public LightOnCommand(Light light) {
		this.light = light;
	}

	@Override
	public void execute() {
		light.on();
	}
}

class LightOffCommand implements Command {
	Light light;

	public LightOffCommand(Light light) {
		this.light = light;
	}

	@Override
	public void execute() {
		light.off();
	}
}

// 命令接受者
class Light {
	public void on() {
		System.out.println("打开电灯。。。");
	}

	public void off() {
		System.out.println("关闭电灯。。。");
	}
}

八、 中介者模式

定义一个对象,封装一组对象如何交互

适用:

  • 系统中对象之间存在复杂的引用关系,产生的相互依赖关系结构混乱
  • 交互的公共行为,如果需要改变行为,可以增加新的中介者类

优点:

  • 将一对多转化成一对一
  • 类之间解耦

缺点:

  • 中介者过多,导致系统复杂
abstract class Colleague {
	public abstract void onEvent(Mediator mediator);
}

class Alarm extends Colleague {
	@Override
	public void onEvent(Mediator mediator) {
		mediator.doEvent("alarm");
	}

	public void doAlarm() {
		System.out.println("doAlarm()");
	}
}

// 中介者
abstract class Mediator {
	public abstract void doEvent(String eventType);
}

class ConcreteMediator extends Mediator {
	private Alarm alarm;

	public ConcreteMediator(Alarm alarm) {
		this.alarm = alarm;
	}

	@Override
	public void doEvent(String eventType) {
		switch (eventType) {
		case "alarm":
			break;
		}
	}
}

九、 责任链模式

为请求创建一个接受次请求对象的链

适用:

  • 一个请求的处理需要多个对象中的一个或几个协作

优点:

  • 请求的发送者和接收者解耦
  • 责任链可以动态组合

缺点:

  • 责任链太长影响性能
  • 责任链可能过多
interface ILeave {
	String getName();

	int getNum();

	String getContent();
}

abstract class Handler {
	protected Handler successor;

	public Handler(Handler successor) {
		this.successor = successor;
	}

	abstract void handleLeave(ILeave leave);
}

class GroupLeader extends Handler {
	public GroupLeader(Handler successor) {
		super(successor);
	}

	@Override
	public void handleLeave(ILeave leave) {
		System.out.println(leave.getName() + "请假" + leave.getNum() + "天," + leave.getContent() + "。");
		System.out.println("小组长审批:同意。");
		if (successor != null) {
			successor.handleLeave(leave);
		}
	}
}

class Manager extends Handler {
	public Manager(Handler successor) {
		super(successor);
	}

	@Override
	public void handleLeave(ILeave leave) {
		System.out.println(leave.getName() + "请假" + leave.getNum() + "天," + leave.getContent() + "。");
		System.out.println("部门经理审批:同意。");
	}
}

十、 访问者模式

封装作用于某数据结构中各元素的操作

可以在不改变各元素的类的前提下,定义作用于这些元素的操作

适用:

  • 一个数据结构包含很多类型对象
  • 数据结构于数据操作分离

优点:

  • 增加新操作很容易

缺点:

  • 增加新数据结构困难
  • 具体元素变更比较麻烦
public interface ComputerPart {
	public void accept(ComputerPartVisitor computerPartVisitor);
}

public class Computer implements ComputerPart {

	ComputerPart[] parts;

	public Computer() {
		parts = new ComputerPart[] { new Mouse(), new Keyboard() };
	}

	@Override
	public void accept(ComputerPartVisitor computerPartVisitor) {
		for (int i = 0; i < parts.length; i++) {
			parts[i].accept(computerPartVisitor);
		}
		computerPartVisitor.visit(this);
	}
}

public class Keyboard implements ComputerPart {

	@Override
	public void accept(ComputerPartVisitor computerPartVisitor) {
		computerPartVisitor.visit(this);
	}
}

public class Mouse implements ComputerPart {

	// accept
}

public interface ComputerPartVisitor {

	public void visit(Mouse mouse);

	public void visit(Keyboard keyboard);

	public void visit(Computer computer);
}

public class ComputerPartDisplayVisitor implements ComputerPartVisitor {

	// ...
}

public class Test {
	public static void main(String[] args) {
		ComputerPart computer = new Computer();
		computer.accept(new ComputerPartDisplayVisitor());
	}
}

十一、 状态模式

允许一个对象在其内部状态改变时,改变它的行为

状态转换图

适用:

  • 一个对象存在多个状态,且可相互转换

优点:

  • 将不同状态隔离
  • 把状态转换逻辑,分布到State子类中,减少相互间依赖
  • 增加新状态简单

缺点:

  • 状态多的业务场景导致类数目增加,系统变得复杂
interface State {
	void insertQuarter();

	void ejectQuarter();

	void turnCrank();

	void dispense();
}

class HasQuarterState implements State {
	private GumballMachine gumballMachine;

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

	@Override
	public void insertQuarter() {
		System.out.println("You can't insert another quarter");
	}

	@Override
	public void ejectQuarter() {
		System.out.println("Quarter returned");
		gumballMachine.setState(gumballMachine.getNoQuarterState());
	}

	@Override
	public void turnCrank() {
		System.out.println("You turned...");
		gumballMachine.setState(gumballMachine.getSoldState());
	}

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

class NoQuarterState implements State {
	// ...
}

class SoldOutState implements State {
	// ...
}

class SoldState implements State {
	// ...
}

class GumballMachine {
	private State soldOutState;
	private State noQuarterState;
	private State hasQuarterState;
	private State soldState;
	private State state;
	private int count = 0;

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

	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;
	}

	public void releaseBall() {
		System.out.println("A gumball comes rolling out the slot...");
		if (count != 0) {
			count -= 1;
		}
	}

	// getter ...
}

猜你喜欢

转载自www.cnblogs.com/JL916/p/12643024.html