行为型设计模式

  • 行为型设计模式主要处理类或对象如何交互及如何分配职责。
    在这里插入图片描述

6.5.1 策略模式

  • 当我们写代码的时候如果出现很多选择,就会使用if…else这种语句。
  • 如果这些语句中还包含多个条件语句,那么代码就会变得很臃肿。
  • 定义:定义一系列的算法,把每一个算法封装起来,并且使他们可以相互替换。策略模式使算法可独立于使用它的客户而独立变化。
    在这里插入图片描述

1. 策略模式的简单实现

在这里插入图片描述

  1. 定义策略接口
package com.example.mode2;

public interface FightingStrategy {
    public void fighting();
}
  1. 具体策略实现
package com.example.mode2;

public class WeakRivalStrategy implements FightingStrategy{
    @Override
    public void fighting() {
        System.out.println("遇到了较弱的对手,张无忌使用了太极剑");
    }
}


package com.example.mode2;

public class CommonRivalStrategy implements FightingStrategy{
    @Override
    public void fighting() {
        System.out.println("遇到了普通的对手,张无忌使用了圣火令神功");
    }
}

package com.example.mode2;

public class StrongRivalStrategy implements FightingStrategy{
    @Override
    public void fighting() {
        System.out.println("遇到了强大的对手,张无忌使用乾坤大挪移");
    }
}
  1. 上下文角色
  • 屏蔽高层模块对我们具体实现的算法的直接调用
package com.example.mode2;

public class Context {
    private FightingStrategy fightingStrategy;
    
    public Context(FightingStrategy fightingStrategy){
        this.fightingStrategy = fightingStrategy;
    }
    
    public void fighting(){
        fightingStrategy.fighting();
    }
}
  1. 客户端调用
  • 张无忌对不同实力层次的对手,采用了不同的策略来迎战
package com.example.mode2;

public class Client3 {
    public static void main(String[] args) {
        Context context;
        context = new Context(new WeakRivalStrategy());
        context.fighting();
        
        context = new Context(new CommonRivalStrategy());
        context.fighting();
        
        context = new Context(new StrongRivalStrategy());
        context.fighting();
    }
}
  • 通过策略类来封装条件语句,使代码不会变得过于臃肿。

2. 策略模式的使用场景和缺点

  • 使用场景
    • 对客户隐藏策略算法的实现
    • 针对同一类型问题的多种处理方式,仅仅是具体行为有差别。
    • 在一个类中定义了很多行为,而且这些行为在这个类里的操作以多个条件语句的形式出现。策略模式将相关的条件分支移入到他们各自的Strategy类中,代替这些条件语句。
  • 优点
    • 避免多重条件语句,多重条件语句不易维护
    • 易于拓展,添加策略只需要实现接口即可。
  • 缺点
    • 每一个策略都是一个类,复用性小。
    • 上层模块必须知道有哪些策略,才可以使用这些策略,和迪米特原则违背。

6.5.2 模块方法模式

在这里插入图片描述

  • 定义:定义一个操作中的算法框架,而将一些步骤延迟到子类中,使得子类不改变一个算法的结构即可重定义算法的某些特定步骤。
    在这里插入图片描述

1. 模块方法的简单实现

  • 模版方法就是封装固定的流程,像模版一样,第一步做什么,第二步做什么。
  1. 创建抽象类,定义算法框架
  • 接着举武侠的例子,一个武侠要战斗的时候,有一套固定的流程。就是运行内功、开启经脉、准备武器和使用招式。
    在这里插入图片描述
package com.example.mode2;

public abstract class AbstractSwordsman {
    //该方法为final,防止算法框架被覆写
    public final void fighting(){
        //运行内功,抽象方法
        neigong();
        //调整经脉,具体方法
        meridian();
        
        if(hasWeapons()){
            weapons();
        }//2
        
        //使用招式
        movers();
        //钩子方法
        hook(); //1
    }
    
    //空实现方法
    protected void hook(){}
    protected abstract void neigong();
    protected abstract void weapons();
    protected abstract void movers();
    protected void meridian(){
        System.out.println("开启正经与奇功");
    }
    protected boolean hasWeapons(){
        //是否有武器,默认有
        return true;
    }
}
  1. 具体实现类
  • 张无忌没有武器,覆盖了判断是否有武器的钩子方法
package com.example.mode2;

public class ZhangWuJi extends AbstractSwordsman{
    //他没有武器,所以返回false
    @Override
    protected void neigong() {
        System.out.println("运行九阳神功");
    }

    @Override
    protected void weapons() {
        
    }

    @Override
    protected void movers() {
        System.out.println("使用招式乾坤大挪移");
    }

    @Override
    protected boolean hasWeapons() {
        return false;
    }
}
  • 来看用武器的张三丰
package com.example.mode2;

public class ZhangSanFeng extends AbstractSwordsman{
    @Override
    protected void neigong() {
        System.out.println("运行纯阳无极神功");
    }

    @Override
    protected void weapons() {
        System.out.println("使用真武剑");
    }

    @Override
    protected void movers() {
        System.out.println("使用招式神门十三剑");
    }

    @Override
    protected void hook() {
        System.out.println("突然肚子不舒服,老夫先去趟厕所");
    }
}
  1. 客户端调用
package com.example.mode2;

public class Client4 {
    public static void main(String[] args) {
        ZhangWuJi zhangWuJi = new ZhangWuJi();
        zhangWuJi.fighting();
        
        ZhangSanFeng zhangSanFeng = new ZhangSanFeng();
        zhangSanFeng.fighting();
    }
}

2. 使用场景和优缺点

在这里插入图片描述

6.5.3 观察者模式

  • 观察者模式又叫做发布-订阅模式,属于行为设计模式的一种,是在项目中经常使用的模式。
  • 定义:定义对象间一种一对多的依赖关系,每当一个对象状态改变时,所有依赖于它的对象都会得到通知并被自动更新。
    在这里插入图片描述

1. 观察者模式的简单实现

  • 拿微信公众号来举例。如果微信用户是观察者,微信公众号就是被观察者。有多个微信用户关注了一个公众号,当公众号更新的时候,就会通知这些订阅的微信用户。
  1. 抽象观察者
  • 定义了一个更新的方法
package com.example.mode2;

public interface Observer {
    public void update(String message);
}
  1. 具体观察者
  • 微信用户是具体观察者,里面实现了更新方法
package com.example.mode2;

public class WeixinUser implements Observer{
    //微信用户名
    private String name;
    public WeixinUser(String name){
        this.name = name;
    }

    @Override
    public void update(String message) {
        System.out.println(name + "-" + message);
    }
}
  1. 抽象被观察者
  • 抽象被观察者,提供了attach、detach、notify方法
package com.example.mode2;

public interface Subject {
    //增加订阅者
    public void attach(Observer observer);

    //删除订阅者
    public void detach(Observer observer);

    //通知订阅者更新消息
    public void notify(Observer message);
}
  1. 具体被观察者
  • 微信公众号是具体主题(具体被观察者),里面存储了订阅该公众号的微信用户,并实现了抽象主题中的方法
package com.example.mode2;

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

public class SubscriptionSubject implements Subject{
    //存储订阅公众号的微信用户
    private List<Observer> weixinUserList = new ArrayList<Observer>(); 
    
    @Override
    public void attach(Observer observer) {
        weixinUserList.add(observer);
    }

    @Override
    public void detach(Observer observer) {
        weixinUserList.remove(observer);
    }

    @Override
    public void notify(String message) {
        for(Observer observer : weixinUserList){
            observer.update(message);
        }
    }


}
  1. 客户端调用
package com.example.mode2;

public class Client5 {
    public static void main(String[] args) {
        SubscriptionSubject mSubscriptionSubject = new SubscriptionSubject();
        //创建微信用户
        WeixinUser user1 = new WeixinUser("1111");
        WeixinUser user2 = new WeixinUser("2222");
        WeixinUser user3 = new WeixinUser("3333");
        //订阅公众号(订阅)
        mSubscriptionSubject.attach(user1);
        mSubscriptionSubject.attach(user2);
        mSubscriptionSubject.attach(user3);
        //公众号更新消息发送给微信用户(改变)
        mSubscriptionSubject.notify("小宁的博客更新了!");
    }
}

2. 观察者模式的使用场景和优缺点

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值