【设计模式-4.1】行为型——策略模式

说明:本文介绍设计模式中的行为型设计模式中的,策略模式;

计算器

策略模式属于行为型设计模式,关注对象的行为。例如,目前有一个计算器类,可对两个数进行加减计算,如下:

(Calculator,计算器类)

/**
 * 计算器
 */
public class Calculator {
    
    
    /**
     * 加法
     */
    public static int add(int a, int b) {
    
    
        return a + b;
    }

    /**
     * 减法
     */
    public static int subtract(int a, int b) {
    
    
        return a - b;
    }
}

(Client,客户端,使用计算器的加法、减法)

/**
 * 客户端
 */
public class Client {
    
    
    public static void main(String[] args) {
    
    
        // 1. 加法
        System.out.println(Calculator.add(1, 2));

        // 2. 减法
        System.out.println(Calculator.subtract(1, 2));
    }
}

执行结果;

在这里插入图片描述

从这个简单的例子中就可以看出问题,扩展性差,如果需要增加乘法、减法或其他种种两个数运算的方法,都需要去修改计算器类。

我们可以考虑将计算器类中的计算方法抽出来称为一个抽象方法,让所有计算方法类都去实现这个接口,然后在计算器类中注入一个计算方法。如下:

(Computation,计算接口)

/**
 * 计算接口
 */
public interface Computation {
    
    

    /**
     * 计算方法
     */
    int compute(int num1, int num2);
}

(AddCompute,加法实现)

/**
 * 加法计算
 */
public class AddCompute implements Computation{
    
    

    @Override
    public int compute(int num1, int num2) {
    
    
        return num1 + num2;
    }
}

(SubCompute,减法实现)

/**
 * 减法计算
 */
public class SubCompute implements Computation{
    
    

    @Override
    public int compute(int num1, int num2) {
    
    
        return num1 - num2;
    }
}

(Calculator,计算器类,注入一个计算对象)

/**
 * 计算器
 */
public class Calculator {
    
    

    private Computation computation;

    public void setComputation(Computation computation) {
    
    
        this.computation = computation;
    }

    /**
     * 计算方法
     */
    public int compute(int num1, int num2) {
    
    
        return this.computation.compute(num1, num2);
    }
}

(Client,客户端,使用什么计算,就new什么计算方式)

/**
 * 客户端
 */
public class Client {
    
    
    public static void main(String[] args) {
    
    
        Calculator calculator = new Calculator();
        calculator.setComputation(new AddCompute());

        // 1. 加法
        System.out.println(calculator.compute(1, 2));

        // 2. 减法
        calculator.setComputation(new SubCompute());
        System.out.println(calculator.compute(1, 2));
    }
}

运行结果;

在这里插入图片描述

通过策略模式,将多种计算方法,从类中抽出来成一个个具体实现类,再创建一个统一的接口,使其实现该接口。这样,不论以后有多少计算方式,都可以创建具体实现类,实现其接口来添加,而不需要对现有的系统做改动。提高了扩展性。

登录方式

策略模式在项目开发中的一个应用是,对多种登录方式的整合。如下:

(LoginMethod,登录方式接口)

/**
 * 登录方式
 */
public interface LoginMethod {
    
    

    /**
     * 登录
     * @return
     */
    String login();
}

(PhoneServiceImpl,具体实现类,手机号登录,Bean名称:phone)

import org.springframework.stereotype.Service;

@Service("phone")
public class PhoneServiceImpl implements LoginMethod {
    
    
    @Override
    public String login() {
    
    
        return "手机号登录";
    }
}

(PasswordServiceImpl,具体实现类,账号密码登录,Bean名称:password)

import org.springframework.stereotype.Service;

@Service("password")
public class PasswordServiceImpl implements LoginMethod {
    
    
    @Override
    public String login() {
    
    
        return "账号密码登录";
    }
}

(WXLoginServiceImpl,具体实现类,微信登录,Bean名称:wx)

import org.springframework.stereotype.Service;

@Service("wx")
public class WXLoginServiceImpl implements LoginMethod {
    
    
    @Override
    public String login() {
    
    
        return "微信登录";
    }
}

(LoginController,登录Controller,传递登录类型)

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping
public class LoginController {
    
    

    @Autowired
    private LoginService loginService;

    @PostMapping("/login")
    public String login(String loginType) {
    
    
        return loginService.executeLogin(loginType);
    }
}

(LoginService,登录接口)

public interface LoginService {
    
    

    /**
     * 根据登录方式执行登录
     *
     * @param loginType
     * @return
     */
    String executeLogin(String loginType);
}

(LoginServiceImpl,登录实现类,使用applicationContext.getBean方法获取对应的登录具体实现类,执行其方法,执行对应的登录方式

import com.hezy.service.LoginMethod;
import com.hezy.service.LoginService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;

/**
 * 登录服务实现类
 */
@Service
public class LoginServiceImpl implements LoginService {
    
    

    @Autowired
    private ApplicationContext applicationContext;

    @Override
    public String executeLogin(String loginType) {
    
    
        LoginMethod loginMethod = (LoginMethod) applicationContext.getBean(loginType);
        return loginMethod.login();
    }
}

启动项目,使用apifox查看执行效果;

在这里插入图片描述


在这里插入图片描述


在这里插入图片描述

当然,这只是一个框架。实际开发,登录需要的信息很多。登录方式肯定是作为一个字段值传入的,如DTO中的一个属性值,具体的登录实现也是需要编写大量代码的,账号密码登录的是去查数据库,手机号登录的是去实现第三方SDK,微信登录的是实现微信登录的SDK。

以上就是策略模式的实现,通过两个例子可以看出,策略模式是对多种解决方案的封装,通过将解决方案设计成接口>具体实现类组合的方式,提高了系统的扩展性,非常实用。

总结

本文参考《设计模式的艺术》、《秒懂设计模式》两书

猜你喜欢

转载自blog.csdn.net/qq_42108331/article/details/134757299