设计模式之行为型模式

本文深入讲解了责任链、迭代器、中介者等十一种经典设计模式的原理与应用实例,帮助读者理解并掌握这些模式在实际开发中的运用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一,责任链模式(chain of responsibility)

定义:将能够处理同一类请求的对象连成一条链,所提交的请求将沿着链传递,链上的对象逐个判断是否有能力处理该请求,如果能则处理,如果不能则传递给链上的下一个对象。


场景:


    -打牌时,轮流出牌


    -接力赛跑


    -大学中,奖学金的审批


    -公司中,公文的审批。
/**
 * 封装请假的基本信息
 * @author Administrator
 *
 */
public class LeaveRequest {
    private String empName;
    private int leaveDays;
    private String reason;  

    public LeaveRequest(String empName, int leaveDays, String reason) {
        super();
        this.empName = empName;
        this.leaveDays = leaveDays;
        this.reason = reason;
    }
    public String getEmpName() {
        return empName;
    }
    public void setEmpName(String empName) {
        this.empName = empName;
    }
    public int getLeaveDays() {
        return leaveDays;
    }
    public void setLeaveDays(int leaveDays) {
        this.leaveDays = leaveDays;
    }
    public String getReason() {
        return reason;
    }
    public void setReason(String reason) {
        this.reason = reason;
    }   
}


/**
 * 抽象类
 * @author Administrator
 *
 */
public abstract class Leader {
    protected String name;
    protected Leader nextLeader; //责任链上的后继对象

    public Leader(String name) {
        super();
        this.name = name;
    }   
    //设定责任链上的后继对象
    public void setNextLeader(Leader nextLeader) {
        this.nextLeader = nextLeader;
    }   
    /**
     * 处理请求的核心的业务方法
     * @param request
     */
    public abstract void handleRequest(LeaveRequest request);   
}


/**
 * 经理
 * @author Administrator
 *
 */
public class Manager extends Leader {

    public Manager(String name) {
        super(name);
    }
    @Override
    public void handleRequest(LeaveRequest request) {
        if(request.getLeaveDays()<10){
            System.out.println("员工:"+request.getEmpName()+"请假,天数:"+request.getLeaveDays()+",理由:"+request.getReason());
            System.out.println("经理:"+this.name+",审批通过!");
        }else{
            if(this.nextLeader!=null){
                this.nextLeader.handleRequest(request);
            }
        }
    }
}


/**
 * 总经理
 * @author Administrator 
 */
public class GeneralManager extends Leader {

    public GeneralManager(String name) {
        super(name);
    }
    @Override
    public void handleRequest(LeaveRequest request) {
        if(request.getLeaveDays()<30){
            System.out.println("员工:"+request.getEmpName()+"请假,天数:"+request.getLeaveDays()+",理由:"+request.getReason());
            System.out.println("总经理:"+this.name+",审批通过!");
        }else{
            System.out.println("莫非"+request.getEmpName()+"想辞职,居然请假"+request.getLeaveDays()+"天!");
        }
    }
}


/**
 * 主任
 * @author Administrator
 *
 */
public class Director extends Leader {

    public Director(String name) {
        super(name);
    }
    @Override
    public void handleRequest(LeaveRequest request) {
        if(request.getLeaveDays()<3){
            System.out.println("员工:"+request.getEmpName()+"请假,天数:"+request.getLeaveDays()+",理由:"+request.getReason());
            System.out.println("主任:"+this.name+",审批通过!");
        }else{
            if(this.nextLeader!=null){
                this.nextLeader.handleRequest(request);
            }
        }
    }
}

/**
 * 副总经理
 * @author Administrator
 *
 */
public class ViceGeneralManager extends Leader {

    public ViceGeneralManager(String name) {
        super(name);
    }
    @Override
    public void handleRequest(LeaveRequest request) {
        if(request.getLeaveDays()<20){
            System.out.println("员工:"+request.getEmpName()+"请假,天数:"+request.getLeaveDays()+",理由:"+request.getReason());
            System.out.println("副总经理:"+this.name+",审批通过!");
        }else{
            if(this.nextLeader!=null){
                this.nextLeader.handleRequest(request);
            }
        }
    }
}


//测试代码如下:


public class Client {
    public static void main(String[] args) {
        Leader a = new Director("张三");
        Leader b = new Manager("李四");
        Leader b2 = new ViceGeneralManager("李小四");
        Leader c = new GeneralManager("王五");
        //组织责任链对象的关系
        a.setNextLeader(b);
        b.setNextLeader(b2);
        b2.setNextLeader(c);        
        //开始请假操作
        LeaveRequest req1 = new LeaveRequest("TOM", 15, "回英国老家探亲!");
        a.handleRequest(req1);      
    }
}

二,迭代器模式(Iterator)

迭代器模式我们不陌生,我们jdk提供的也有这样啊案例,如下是我们自定义的迭代器模式的代码如下:
import java.util.ArrayList;
import java.util.List;

/**
 * 自定义的聚合类
 * @author Administrator
 *
 */
public class ConcreteMyAggregate {
    private List<Object> list = new ArrayList<Object>();

    public void addObject(Object obj){
        this.list.add(obj);
    }
    public void removeObject(Object obj){
        this.list.remove(obj);
    }

    public List<Object> getList() {
        return list;
    }

    public void setList(List<Object> list) {
        this.list = list;
    }   
    //获得迭代器
    public MyIterator  createIterator(){
        return new ConcreteIterator();
    }   
    //使用内部类定义迭代器,可以直接使用外部类的属性
    private class ConcreteIterator implements MyIterator {
        private int cursor;  //定义游标用于记录遍历时的位置

        @Override
        public void first() {
            cursor = 0;
        }

        @Override
        public Object getCurrentObj() {
            return list.get(cursor);
        }

        @Override
        public boolean hasNext() {
            if(cursor<list.size()){
                return true;
            }
            return false;
        }

        @Override
        public boolean isFirst() {
            return cursor==0?true:false;
        }

        @Override
        public boolean isLast() {
            return cursor==(list.size()-1)?true:false;
        }

        @Override
        public void next() {
            if(cursor<list.size()){
                cursor++;
            }
        }       
    }
}


//迭代器接口:

/**
 *  自定义的迭代器接口
 * @author Administrator
 *
 */
public interface MyIterator {
    void first();   //将游标指向第一个元素
    void next();    //将游标指向下一个元素
    boolean hasNext();//判断是否存在下一个元素

    boolean isFirst();
    boolean isLast();

    Object getCurrentObj();  //获取当前游标指向的对象
}


//测试代码:

public class Client {

    public static void main(String[] args) {
        ConcreteMyAggregate cma = new ConcreteMyAggregate();
        cma.addObject("aa");
        cma.addObject("bb");
        cma.addObject("cc");

        MyIterator iter = cma.createIterator();
        while(iter.hasNext()){
            System.out.println(iter.getCurrentObj());
            iter.next();
        }       
    }
}

三,中介者模式(Mediator)

举例:各个部门之间打交道都是通过经理来做的,如果是直接打交道会显得很混乱,所以经理就是中介者


public interface Mediator {

    void register(String dname,Department d);

    void command(String dname); 
}


//市场部
public class Market implements Department {

    private Mediator m;  //持有中介者(总经理)的引用

    public Market(Mediator m) {
        super();
        this.m = m;
        m.register("market", this);
    }
    @Override
    public void outAction() {
        System.out.println("汇报工作!项目承接的进度,需要资金支持!");

        m.command("finacial");      
    }
    @Override
    public void selfAction() {
        System.out.println("跑去接项目!");
    }
}

//财务部

public class Finacial implements Department {

    private Mediator m;  //持有中介者(总经理)的引用

    public Finacial(Mediator m) {
        super();
        this.m = m;
        m.register("finacial", this);
    }
    @Override
    public void outAction() {
        System.out.println("汇报工作!没钱了,钱太多了!怎么花?");
    }
    @Override
    public void selfAction() {
        System.out.println("数钱!");
    }
}


//科研部

public class Development implements Department {

    private Mediator m;  //持有中介者(总经理)的引用

    public Development(Mediator m) {
        super();
        this.m = m;
        m.register("development", this);
    }

    @Override
    public void outAction() {
        System.out.println("汇报工作!没钱了,需要资金支持!");
    }

    @Override
    public void selfAction() {
        System.out.println("专心科研,开发项目!");
    }
}


//部门类的接口
public interface Department {
    void selfAction(); //做本部门的事情
    void outAction();  //向总经理发出申请
}


//中介者实现类
import java.util.HashMap;
import java.util.Map;

public class President implements Mediator {

    private Map<String,Department> map = new HashMap<String , Department>();

    @Override
    public void command(String dname) {
        map.get(dname).selfAction();
    }
    @Override
    public void register(String dname, Department d) {
        map.put(dname, d);//加入到中介者可以控制的范围里
    }
}

public class Client {
    public static void main(String[] args) {
        Mediator m = new President();

        Market   market = new Market(m);
        Development devp = new Development(m);
        Finacial f = new Finacial(m);

        market.selfAction();
        market.outAction();     
    }
}

四,命令模式(command)

定义:将一个请求封装为一个对象,从而使我们可用不同的请求对客户进行参数化;对请求排队或者记录请求日志,以及支持可以撤销的操作,也称之为:动作Action模式,事务transaction模式。

结构:

  • Command抽象命令类

    -ConcreterCommand具体命令类

    -Invoker调用者/请求者

    -Receiver接收者

    -Client客户类


public interface Command {
    /**
     * 这个方法是一个返回结果为空的方法。
     * 实际项目中,可以根据需求设计多个不同的方法
     */
    void execute();
}
//命令类的实现类 持有接收者的引用
class ConcreteCommand implements Command {  
    private Receiver receiver;  //命令的真正的执行者 
    public ConcreteCommand(Receiver receiver) {
        super();
        this.receiver = receiver;
    }
    @Override
    public void execute() {
        //命令真正执行前或后,执行相关的处理!
        receiver.action();
    }   
}


//调用者/发起者 持有命令的引用
public class Invoke {

    private Command command;   //也可以通过容器List<Command>容纳很多命令对象,进行批处理。数据库底层的事务管理就是类似的结构!

    public Invoke(Command command) {
        super();
        this.command = command;
    }   
    //业务方法 ,用于调用命令类的方法
    public void call(){
        command.execute();
    }   
}


/**
 * 真正的命令的执行者
 * @author Administrator
 *
 */
public class Receiver {
    public void action(){
        System.out.println("Receiver.action()");
    }
}

//测试类
public class Client {
    public static void main(String[] args) {
        Command c = new ConcreteCommand(new Receiver());
        Invoke i = new Invoke(c);
        i.call();   

//      new Receiver().action();

    }
}

五,解释器模式(Interpreter)

1.简单了解一下即可!

-是一种不常用的设计模式


-用于描述如何构成一个简单的语言解释器,主要用于使用面向对象语言开发的编译器和解释器设计。


-当我们需要开发一种新的语言时,可以考虑使用解释器模式。

2.开发中常见的场景:

-EL表达式式的处理


-正则表达式解释器。


-SQL语法的计数器。


-数学表达式解析器。如现成的工具包:Math Expression String Parser ,Expression4J等。

六,访问者模式(Visitor)

1.一般了解
2.模式动机:

        对于存储在一个集合中的对象,他们可能具有不同的类型(即使有一个公共的接口),对于该集合中的,可以接受一类成为访问者的对象来访问,不同的访问者其访问方式也有所不同。

3.定义:

        表示一个作用于某对象结构中的各元素的操作,它使我们可以在不改变各的类的前提下定义作用于这些元素的新操作。

4.开发中的场景:

            XML文档解析器设计
            编译器设计
            复杂集合对象的处理

七,策略模式


/**
 * 实现起来比较容易,符合一般开发人员的思路
 * 假如,类型特别多,算法比较复杂时,整个条件语句的代码就变得很长,难于维护。
 * 如果有新增类型,就需要频繁的修改此处的代码!
 * 不符合开闭原则!
 *(无使用策略模式)
 *
 */
public class TestStrategy {
    public double getPrice(String type, double price) {
        if (type.equals("普通客户小批量")) {
            System.out.println("不打折,原价");
            return price;
        } else if (type.equals("普通客户大批量")) {
            System.out.println("打九折");
            return price * 0.9;
        } else if (type.equals("老客户小批量")) {
            System.out.println("打八五折");
            return price * 0.85;
        } else if (type.equals("老客户大批量")) {
            System.out.println("打八折");
            return price * 0.8;
        }
        return price;
    }
}

public interface Strategy {
    public double getPrice(double  standardPrice);
}

//接口的实现类如下:

public class NewCustomerFewStrategy implements Strategy {
    @Override
    public double getPrice(double standardPrice) {
        System.out.println("不打折,原价");
        return standardPrice;
    }
}

public class NewCustomerManyStrategy implements Strategy {
    @Override
    public double getPrice(double standardPrice) {
        System.out.println("打九折");
        return standardPrice*0.9;
    }
}



public class OldCustomerFewStrategy implements Strategy {
    @Override
    public double getPrice(double standardPrice) {
        System.out.println("打八五折");
        return standardPrice*0.85;
    }
}


public class OldCustomerManyStrategy implements Strategy {
    @Override
    public double getPrice(double standardPrice) {
        System.out.println("打八折");
        return standardPrice*0.8;
    }
}

/**
 * 负责和具体的策略类交互
 * 这样的话,具体的算法和直接的客户端调用分离了,使得算法可以独立于客户端独立的变化。
 * 如果使用spring的依赖注入功能,还可以通过配置文件,动态的注入不同策略对象,动态的切换不同的算法.
 *
 */
public class Context {
    private Strategy strategy;  //当前采用的算法对象

    //可以通过构造器来注入
    public Context(Strategy strategy) {
        super();
        this.strategy = strategy;
    }
    //可以通过set方法来注入
    public void setStrategy(Strategy strategy) {
        this.strategy = strategy;
    }   
    public void pringPrice(double s){
        System.out.println("您该报价:"+strategy.getPrice(s));
    }   
}


package com.bjsxt.strategy;

public class Client {
    public static void main(String[] args) {

        Strategy s1 = new OldCustomerManyStrategy();
        Context ctx = new Context(s1);

        ctx.pringPrice(998);        
    }
}

八,模板方法模式(template method)


public abstract class BankTemplateMethod {
    //具体方法
    public void takeNumber(){
        System.out.println("取号排队");
    }   
    public abstract void transact(); //办理具体的业务  //钩子方法  
    public void evaluate(){
        System.out.println("反馈评分");
    }
    public final void process(){    //模板方法!!!
        this.takeNumber();

        this.transact();

        this.evaluate();
    }   
}




public class Client {
    public static void main(String[] args) {
        BankTemplateMethod btm = new DrawMoney();
        btm.process();      
        //采用匿名内部类
        BankTemplateMethod btm2 = new BankTemplateMethod() {

            @Override
            public void transact() {
                System.out.println("我要存钱!");
            }
        };
        btm2.process();

        BankTemplateMethod btm3 = new BankTemplateMethod() {
            @Override
            public void transact() {
                System.out.println("我要理财!我这里有2000万韩币");
            }
        };      
        btm3.process();     
    }
}
//采用类
class DrawMoney extends BankTemplateMethod {
    @Override
    public void transact() {
        System.out.println("我要取款!!!");
    }

}

九,状态模式(State)

核心:用于解决系统中复杂对象状态转换以及不同状态下行为的封装问题。


结构:


-Context环境类


     .环境类中维护一个State对象,他是定义来了当前的状态。


-State抽象状态类


-ConcreteState具体状态类


    .每一个类封装了一个状态对应的行为。
//接口
public interface State {
    void handle();
}


//接口的实现类如下:

/**
 * 空闲状态
 */
public class FreeState implements State {

    @Override
    public void handle() {
        System.out.println("房间空闲!!!没人住!");
    }
}

/**
 * 已入住状态
 * @author Administrator
 *
 */
public class CheckedInState implements State {

    @Override
    public void handle() {
        System.out.println("房间已入住!请勿打扰!");
    }
}

/**
 * 已预订状态

 */
public class BookedState implements State {

    @Override
    public void handle() {
        System.out.println("房间已预订!别人不能定!");
    }
}

/**
 * 已预订状态
 */
public class BookedState implements State {
    @Override
    public void handle() {
        System.out.println("房间已预订!别人不能定!");
    }
}

/**
 * 房间对象
 * @author Administrator
 *
 */
public class HomeContext {
    //如果是银行系统,这个Context类就是账号。根据金额不同,切换不同的状态!    
    private State state;        
    public void setState(State s){
        System.out.println("修改状态!");
        state = s;
        state.handle();
    }   
}


//测试类:

public class Client {
    public static void main(String[] args) {
        HomeContext ctx = new HomeContext();

        ctx.setState(new FreeState());
        ctx.setState(new BookedState());        
    }
}

十,观察者模式(Observer)

//观察者接口
public interface Observer {
    void  update(Subject subject);
}

import java.util.ArrayList;
import java.util.List;

public class Subject {

    protected List<Observer> list = new ArrayList<Observer>();

    public void registerObserver(Observer obs){
        list.add(obs);
    }
    public void removeObserver(Observer obs){
        list.add(obs);
    }
    //通知所有的观察者更新状态
    public void notifyAllObservers(){
        for (Observer obs : list) {
            obs.update(this);
        }
    }   
}

public class ConcreteSubject extends Subject {

    private int state;

    public int getState() {
        return state;
    }
    public void setState(int state) {
        this.state = state;
        //主题对象(目标对象)值发生了变化,请通知所有的观察者
        this.notifyAllObservers();
    }   
}
 //observer实现类
 public class ObserverA implements Observer {

    private int myState;    

    @Override
    public void update(ConcreteSubject subject) {
        myState = subject.getState();
    }
    public int getMyState() {
        return myState;
    }
    public void setMyState(int myState) {
        this.myState = myState;
    }   
}

//测试类代码如下:

public class Client {
    public static void main(String[] args) {
        //目标对象
        ConcreteSubject subject = new ConcreteSubject();

        //创建多个观察者
        ObserverA  obs1 = new ObserverA();
        ObserverA  obs2 = new ObserverA();
        ObserverA  obs3 = new ObserverA();

        //将这三个观察者添加到subject对象的观察者队伍中
        subject.registerObserver(obs1);
        subject.registerObserver(obs2);
        subject.registerObserver(obs3);     

        //改变subject的状态
        subject.setState(3000);
        System.out.println("########################");
        //我们看看,观察者的状态是不是也发生了变化
        System.out.println(obs1.getMyState());
        System.out.println(obs2.getMyState());
        System.out.println(obs3.getMyState());

        //改变subject的状态
        subject.setState(30);
        System.out.println("########################");
        //我们看看,观察者的状态是不是也发生了变化
        System.out.println(obs1.getMyState());
        System.out.println(obs2.getMyState());
        System.out.println(obs3.getMyState());      
    }
}

观察者模式进阶(jdk)

import java.util.Observable;

//目标对象
public class ConcreteSubject extends Observable {//继承jdk中的Observable类

    private int state; 

    public void set(int s){
        state = s;  //目标对象的状态发生了改变

        setChanged();  //表示目标对象已经做了更改
        notifyObservers(state);  //通知所有的观察者

    }

    public int getState() {
        return state;
    }

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


import java.util.Observable;
import java.util.Observer;

public class ObserverA implements Observer {//jdk中的Observer接口

    private int myState;    

    @Override
    public void update(Observable o, Object arg) {
        myState = ((ConcreteSubject)o).getState();
    }
    public int getMyState() {
        return myState;
    }
    public void setMyState(int myState) {
        this.myState = myState;
    }   
}


//测试类

public class Client {
    public static void main(String[] args) {
        //创建目标对象Obserable
        ConcreteSubject subject = new ConcreteSubject();

        //创建观察者
        ObserverA obs1 = new ObserverA();
        ObserverA obs2 = new ObserverA();
        ObserverA obs3 = new ObserverA();

        //将上面三个观察者对象添加到目标对象subject的观察者容器中
        subject.addObserver(obs1);
        subject.addObserver(obs2);
        subject.addObserver(obs3);

        //改变subject对象的状态
        subject.set(3000);
        System.out.println("===============状态修改了!");
        //观察者的状态发生了变化
        System.out.println(obs1.getMyState());
        System.out.println(obs2.getMyState());
        System.out.println(obs3.getMyState());

        subject.set(600);
        System.out.println("===============状态修改了!");
        //观察者的状态发生了变化
        System.out.println(obs1.getMyState());
        System.out.println(obs2.getMyState());
        System.out.println(obs3.getMyState());          
    }
}

十一,备忘录模式(memento)

核心:

    -就是保存某个对象内部状态的拷贝,这样以后就可以将该对象恢复到原先的状态。

结构:

   -源发器类Originator

   -备忘录类Memento

   -负责人类CareTake

备忘点较多时:

    -将备忘录压栈

    -将多个备忘录对象,序列化和持久化。
/**
 * 备忘录类
 * @author Administrator
 *
 */
public class EmpMemento {
    private String ename;
    private int age;
    private double salary;  

    public EmpMemento(Emp e) {
        this.ename = e.getEname();
        this.age = e.getAge();
        this.salary = e.getSalary();
    }   
    public String getEname() {
        return ename;
    }
    public void setEname(String ename) {
        this.ename = ename;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public double getSalary() {
        return salary;
    }
    public void setSalary(double salary) {
        this.salary = salary;
    }   
}

/**
 * 源发器类
 * @author Administrator
 *
 */
public class Emp {
    private String ename;
    private int age;
    private double salary;  
    //进行备忘操作,并返回备忘录对象
    public EmpMemento  memento(){
        return new EmpMemento(this);
    }   
    //进行数据恢复,恢复成制定备忘录对象的值
    public void recovery(EmpMemento mmt){
        this.ename = mmt.getEname();
        this.age = mmt.getAge();
        this.salary = mmt.getSalary();
    }   
    public Emp(String ename, int age, double salary) {
        super();
        this.ename = ename;
        this.age = age;
        this.salary = salary;
    }
    public String getEname() {
        return ename;
    }
    public void setEname(String ename) {
        this.ename = ename;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public double getSalary() {
        return salary;
    }
    public void setSalary(double salary) {
        this.salary = salary;
    }
}

/**
 * 负责人类
 * 负责管理备忘录对象
 * @author Administrator
 *
 */
public class CareTaker {    
    private EmpMemento memento;

//  private List<EmpMemento> list = new ArrayList<EmpMemento>();    //也可用堆栈

    public EmpMemento getMemento() {
        return memento;
    }
    public void setMemento(EmpMemento memento) {
        this.memento = memento;
    }
}


测试类:

public class Client {
    public static void main(String[] args) {
        CareTaker taker = new CareTaker();

        Emp emp = new Emp("高淇", 18, 900);
        System.out.println("第一次打印对象:"+emp.getEname()+"---"+emp.getAge()+"---"+emp.getSalary());

        taker.setMemento(emp.memento());   //备忘一次

        emp.setAge(38);
        emp.setEname("搞起");
        emp.setSalary(9000);
        System.out.println("第二次打印对象:"+emp.getEname()+"---"+emp.getAge()+"---"+emp.getSalary());

        emp.recovery(taker.getMemento()); //恢复到备忘录对象保存的状态

        System.out.println("第三次打印对象:"+emp.getEname()+"---"+emp.getAge()+"---"+emp.getSalary());     
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值