• 设计模式——行为型


    一、 模板方法模式

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

    适用:

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

    优点:

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

    缺点:

    • 类数目增加
    • 增加系统实现的复杂度
    • 父类添加新抽象方法,子类也要实现
    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;
    	}
    }
    

    三、 策略模式

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

    适用:

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

    优点:

    • 符合开闭原则
    • 避免使用多重条件转移
    • 提高算法的保密性和安全性

    缺点:

    • 客户端需要知道所有策略类,并自行选择
    • 产生很多策略类
    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 ...
    }
    
  • 相关阅读:
    板子们~缓慢更新
    Hello World!
    [SHOI2008]堵塞的交通traffic
    [JSOI2008]最大数
    [SCOI2005]扫雷
    [HAOI2007]上升序列
    [HAOI2007]理想的正方形
    [SCOI2003]字符串折叠
    [HAOI2008]移动玩具
    [BJOI2006]狼抓兔子
  • 原文地址:https://www.cnblogs.com/JL916/p/12643024.html
Copyright © 2020-2023  润新知