设计模式面试题(六):设计模式之策略模式和观察者模式

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

九、策略模式

1、什么是策略模式

定义了一系列的算法 或 逻辑 或 相同意义的操作并将每一个算法、逻辑、操作封装起来而且使它们还可以相互替换。 (其实策略模式 Java 中用的非常非广)
我觉得主要是为了 简化 if...else 所带来的复杂和难以维护

2、策略模式应用场景

策略模式的用意是针对一组算法或逻辑,将每一个算法或逻辑封装到具有共同接口的独立的类中从而使得它们之间可以相互替换。

  1. 例如: 我要做一个不同会员打折力度不同的三种策略初级会员中级会员高级会员 (三种不同的计算)
  2. 例如: 我要一个支付模块我要有微信支付、支付宝支付、银联支付等

3、策略模式的优点和缺点

优点:

1、算法可以自由切换。

2、避免使用多重条件判断。

3、扩展性非常良好。

缺点:

1、策略类会增多。

2、所有策略类都需要对外暴露。

4、代码演示

模拟支付模块有微信支付、支付宝支付、银联支付

定义抽象的公共方法

package com.lifie;

//策略模式 定义抽象方法 所有支持公共接口
abstract class PayStrategy {

    //支付逻辑方法
    abstract void algorithmInterface();
}

定义实现微信支付

package com.lijie;

class PayStrategyA extends PayStrategy{
    void algorithmInterface(){
        System.out.println("微信支付");
    }
}

1、定义实现支付宝支付

package com.lijie;

class PayStrategyB extends PayStrategy {
    void algorithmInterface(){
        System.out.println("支付宝支付");
    }
}

定义实现银联支付

package com.lijie;

class PayStrategyC extends PayStrategy{
    void algorithmInterface(){
        System.out.println("银联支付");
    }
}

定义下文维护算法策略

package com.lijie;

// 使用上下文维护算法策略
class Context{
    PayStrategy strategy;

    public Context(PayStrategy strategy){
        this.strategy = strategy;
    }

    public void algorithmInterface(){

        strategy.algorithmInterface();
    }
}

运行测试

package com.lijie;

class ClientTestStrategy{
    public static void main(String[] args){
        Context context;    
    //使用支付逻辑A
    context = new Context(new PayStrategyA());
    context.algorithmInterface();
    //使用支付逻辑 B
    context = new Context(new PayStrategyB());
    context.algorithmInterface();
    //使用支付逻辑 C
    context = new Context(new PayStrategyC());
    context.algorithmInterface());
    }
}

十、观察者模式

1、什么是观察者模式

先讲什么是行为性模型行为型模式关注的是系统中对象之间的相互交互解决系统在运行时对象之间的相互通信和协作进一步明确对象的职责。观察者模式是一种行为性模型又叫发布-订阅模式他定义对象之间一种-对多的依赖关系使得当一个对象改变状态则所有依赖于它的对象都会得到通知并自动更新。

2、模式的职责

观察者模式主要用于 1对 N 的通知。当一个对象的状态变化时他需要及时告知一系列对象令他们做出相应。

实现有两种方式:

  1. 推: 每次都会把通知以广播的方式发送给所有观察者所有的观察者只能被动接收。
  2. 拉: 观察者只要知道有情况即可至于什么时候获取内容获取什么内容都可以自主决定。

3、观察者模式应用场景

  1. 关联行为场景需要注意的是关联行为是可拆分的而不是“组合”关系事件多级触发场景。
  2. 跨系统的消息交换场景如消息队列、事件总线的处理机制。

4、代码实现观察者模式

定义抽象观察者每一个实现该接口的实现类都是具体观察者。

package com.lijie;

//观察者的接口用来存放观察者共有方法
public interface Observer{
    // 观察者方法
    void update(int state);
}

定义具体观察者

package com.lijie;

// 具体观察者
public class ObserverImpl implements Observer {
    // 具体观察者的属性
    private int myState;

    public void update(int state){
        myState = state;
        System.out.println("收到消息,myState 值改为:"+ state);
    }

    public int getMyState(){
        return myState;
    }
}

定义主题。主题定义观察者数组并实现增、删及通知操作。

package com.lijie;

import java.util.Vector;

//定义主题以及定义观察者数组并实现增、删及通知操作。
public class Subjecct {
    //观察者的存储集合不推荐 ArrayList线程不安全
    private Vector<Observer> list = new Vector<>();
    
    //注册观察者方法
    public void registerObserver(Observer obs){
        list.add(obs);
    }

    // 删除观察者方法
    public void removeObserver(Observer obs){
        list.remove(obs);
    }

    // 通知所有的观察者更新
    public void notifyAllObserver(int state){
        for (Observer observer : list) {
            observer.update(state);
        }
    }
}

1、 定义具体的他继承继承 Subject 类在这里实现具体业务在具体项目中该类会有很多
 

package com.lijie;

//具体主题
public class RealObserver extends Subjecct{
    //被观察对象的属性
    private int state;
    public int getState(){
        return state;
    }
    public void setState(int state){
        this.state = state;
        //主题对象(目标对象)值发生改变
        this.notifyAllObserver(state);
    }
}

运行测试

package com.lijie;

public class Clien{
    public static void main(String[] args){
        //目标对象
        RealObserver subject = new RealObserver();
        // 创建多个观察者
        ObserverImpl obs1 = new ObserverImpl();
        ObserverImpl obs2 = new ObserverImpl();
        ObserverImpl obs3 = new ObserverImpl();
        // 注册到观察队列中
        subject.registerObserver(obs1);
        subject.registerObserver(obs2);
        subject.registerObserver(obs3);
        // 改变 State 状态
        subject.setState(300);
        System.out.println("obs1 观察者的 MyState 状态值为:"+ obs1.getMyState());
        System.out.println("obs2 观察者的 MyState 状态值为:"+ obs2.getMyState());
        System.out.println("obs3 观察者的 MyState 状态值为:"+ obs3.getMyState());
        // 改变 State 状态
        subject.setState(400);
        System.out.println("obs1 观察者的 MyState 状态值为:"+obs1.getMyState());
        System.out.println("obs2 观察者的 MyState 状态值为:"+obs2.getMyState());
        System.out.println("obs3 观察者的 MyState 状态值为:"+obs3.getMyState());
    }
}

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6