设计模式(三)

观察者模式:发布者持有订阅者列表,当发布者变化时通知观察者列表。
模板模式:抽象父类规范主方法,调用内部的抽象方法由具体子类重写实现。
命令模式:命令者下发命令到一个系统接收命令类,由这个类去找合适的执行者,比如一个智能遥控器包括电脑、门、灯的开关功能,我们只需使用遥控去下发这个命令。
状态模式:
责任链模式:先判断自己能否处理,如果不能就交给下一个链处理。

1、观察者模式

一个被观察的类在状态发生变化时,需要主动发出消息来通知订阅它的观察者类。
定义观察者

public interface Observer {
    void update(Observable o);    
}
public class ConcreteObserver1 implements Observer{
    public void update(Observable o) {
        System.out.println("观察者1观察到" + o.getClass().getSimpleName() + "发生变化");
        System.out.println("update");
    }
}
public class ConcreteObserver2 implements Observer{
    public void update(Observable o) {
        System.out.println("观察者2观察到" + o.getClass().getSimpleName() + "发生变化");
        System.out.println("update");
    }
}

//被观察者

public class Observable {
    List<Observer> observers = new ArrayList<Observer>();
    public void addObserver(Observer o){
        observers.add(o);
    } 
    public void changed(){
        //通知观察自己的所有观察者
        notifyObservers();
    }
    public void notifyObservers(){
        for (Observer observer : observers) {
            observer.update(this);
        }
    }
}

实际应用,比如我们订阅新闻时,当有更新时,订阅者会收到更新通知。
1、tomcat中的Listener,当加载spring配置文件时,tomcat启动那么 spring的IOC容器就会跟着启动。
2、spring中的ServletContextListener会监听 ServletContext的启动和销毁。

2、模板模式

为了统一子类的算法实现步骤,所使用的一种手段或者说是方式。它在父类中定义一系列算法的步骤,而将具体的实现都推迟到子类。
通常定义一个功能接口,再定一个抽象类实现这个接口,抽象类会再定义一些抽象方法并实现这个接口方法,接口方法里面会调用定义的抽象方法。这样不同子类重写抽象方法增加一定的灵活性,并且父类也规范了实现步骤。

优点
1、封装不变部分,扩展可变部分。 2、提取公共代码,便于维护。 3、行为由父类控制,子类实现。

public interface JobTask {
    Result execute();
}
public abstract class defaultJob{
    @Override
    public Result execute() {
        try {
            checkParameter();
            //调用抽象方法,子类会重写抽方法
            return process();

        } catch (Exception ex) {
        }
        return null;
    }
    protected abstract Result process();
}
//子类job
public class ModelJob extends defaultJob{
    @Override
    public Result process() {
       //do some thing...
       return Result;
    }
}

比如类加载器就用的模板方法

public abstract class ClassLoader {
    //这是一个重载方法
    public Class<?> loadClass(String name) throws ClassNotFoundException {
    return loadClass(name, false);
    }
    //这里就是父类算法的定义
    protected synchronized Class<?> loadClass(String name, boolean resolve)
    throws ClassNotFoundException
    {
    Class c = findLoadedClass(name);
    if (c == null) {
        try {
        if (parent != null) {
            c = parent.loadClass(name, false);
        } else {
            c = findBootstrapClass0(name);
        }
        } catch (ClassNotFoundException e) {
            c = findClass(name);
        }
    }
    if (resolve) {
        resolveClass(c);
    }
    return c;
    }
    //这里留了一个方法给子类选择性覆盖
    protected Class<?> findClass(String name) throws ClassNotFoundException {
    throw new ClassNotFoundException(name);
    }
}

从代码上我们可以看出,在ClassLoader中定义的算法顺序是。
* 1,首先看是否有已经加载好的类。
* 2,如果父类加载器不为空,则首先从父类类加载器加载。
* 3,如果父类加载器为空,则尝试从启动加载器加载。
* 4,如果两者都失败,才尝试从findClass方法加载。
这是JDK类加载器的双亲委派模型,即先从父类加载器加载,直到继承体系的顶层,否则才会采用当前的类加载器加载。这样做的目的是为了JVM中类的一致性。

3、命令模式

请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。
比如你提交开灯、关灯、开门、关灯等多个命令给智能遥控,由智能遥控分配任务给执行者去执行相应任务,而不需你自己单个去发送命令。

//具体命令执行者
public class Light{  
    public void on(){  
        System.out.println("打开电灯");  
    }    
    public void off(){  
        System.out.println("关闭电灯");  
    }  
} 
//定义命令
public interface Command{  
    public void execute();  
}
public class LightOffCommond implements Command{  
    private Light light ;        
    public LightOffCommond(Light light){  
        this.light = light;  
    }   
    @Override  
    public void execute(){  
        light.off();  
    }    
}
public class LightOnCommond implements Command{  
    private Light light ;      
    public LightOnCommond(Light light){  
        this.light = light;  
    }  
    @Override  
    public void execute(){  
        light.on();  
    } 
} 

//接收命令类,再找到合适的执行者执行任务

public class ControlPanel{  
    private static final int CONTROL_SIZE = 9;
    private Command[] commands;
    public ControlPanel() {
        commands = new Command[CONTROL_SIZE];
        /**
         * 初始化所有按钮指向空对象
         */
        for (int i = 0; i < CONTROL_SIZE; i++)
        {
            commands[i] = new NoCommand();
        }
    }
    /**
     * 设置每个按钮对应的命令
     * @param index
     * @param command
     */
    public void setCommand(int index, Command command){
        commands[index] = command;
    }
    /**
     * 模拟点击按钮
     * @param index
     */
    public void keyPressed(int index){
        commands[index].execute();
    } 
} 

//命令人

public static void main(String[] args) {
    Light light = new Light();
    ControlPanel controlPanel = new ControlPanel();
    // 为每个按钮设置功能  
    controlPanel.setCommand(0, new LightOnCommond(light));
    controlPanel.setCommand(1, new LightOffCommond(light));

    // 模拟点击  
    controlPanel.keyPressed(0);
    controlPanel.keyPressed(2);
    controlPanel.keyPressed(3);
    controlPanel.keyPressed(4);
    controlPanel.keyPressed(5);
    controlPanel.keyPressed(8);// 这个没有指定,但是不会出任何问题,我们的NoCommand的功劳  
}

4、状态模式

当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。

5、责任链模式

责任链模式就是将能够处理同一类请求的对象连成一条链,所提交的请求沿着链传递,链上的对象逐个判断是否有能力处理该请求,如果能则处理,如果不能则传递给链上的下一个对象进行处理,以此类推。
比如审批财物报销,如果小于500则由主管批,500-1000由经理批,1000-2000由部经理批,大于2000不予报销等。
//请求对象

public class Request {
    private String name;
    private int money;
    public LeaveRequest(String name, int money) {
        super();
        this.name = name;
        this.money = money;
    }
    //省略get和set方法
}  

//责任链

public abstract class Leader {
    protected String name;
    //责任链上的后继对象,即这个对象无法处理,就转移给下一个Leader
    protected Leader nextLeader; 
    public Leader(String name) {
        super();
        this.name = name;
    }
    // 设定责任链上的后继对象
    public void setNextLeader(Leader nextLeader) {
        this.nextLeader = nextLeader;
    }
    /**
     * 处理请求的核心的业务方法
     * 需要不同继承该类的领导自己实现
     */
    public abstract void handleRequest(LeaveRequest request);
}
//主任
public class Director extends Leader {
    public Director(String name) {
        super(name);
    }
    @Override
    public void handleRequest(Request request) {
        //获取请假天数
        int money = request.getMoney(); 
        String name = request.getName(); //获取请假人姓名
        //如果小于500元,主任直接审批
        if(days <= 500) { 
            System.out.println("员工" + name + "报销" + money + "元" );
            System.out.println("主任" + this.name + "审批通过");
        } else {
            System.out.println("审批金额过多,主任" + this.name + "没法处理");
             //否则,如果链上存在下一个Leader,就让他处理
            if(this.nextLeader != null) {
                this.nextLeader.handleRequest(request);
            } 
        }
    }
}

/**
 * @Description 经理
 */
public class Manager extends Leader {

    public Manager(String name) {
        super(name);
    }
    @Override
    public void handleRequest(Request request) {
        int money = request.getMoney(); 
        String name = request.getName(); //获取请假人姓名
        //如果小于1000的要求,经理直接审批
        if(days <= 1000) { 
            System.out.println("员工" + name + "报销" + money + "元" );
            System.out.println("经理" + this.name + "审批通过");
        } else {
            System.out.println("报销过多,经理" + this.name + "没法处理");
            //否则,如果链上存在下一个Leader,就让他处理
            if(this.nextLeader != null) { 
                this.nextLeader.handleRequest(request);
            } 
        }
    }
}
/**
 * @Description 总经理
 */
public class GeneralManager extends Leader {
    public GeneralManager(String name) {
        super(name);
    }
    @Override
    public void handleRequest(Request request) {
        int money = request.getMoney(); 
        String name = request.getName(); //获取请假人姓名
        if(money <= 2000) { 
            System.out.println("员工" + name + "报销" + money + "天,理由:" + reason);
            System.out.println("总经理" + this.name + "审批通过");
        } else {
            System.out.println("报销过多,总经理" + this.name + "没法处理");
            if(this.nextLeader != null) { //否则,如果链上存在下一个Leader,就让他处理
                this.nextLeader.handleRequest(request);
            } else {
                System.out.println("报销不成功");
            }
        }
    }
}

//调用

public class Client {
    public static void main(String[] args) {
        Leader director = new Director("张三");
        Leader manager = new Manager("李四");
        Leader gManager = new GeneralManager("王五");
        // 组织好责任链对象的关系
        director.setNextLeader(manager);
        manager.setNextLeader(gManager);
        // 开始请假操作
        LeaveRequest request = new Request("倪升武", 1000);
        director.handleRequest(request);
    }
}

6、解释器模式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值