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

九、策略模式

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

出世&入世

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值