说明:本文介绍设计模式中的行为型设计模式中的,策略模式;
计算器
策略模式属于行为型设计模式,关注对象的行为。例如,目前有一个计算器类,可对两个数进行加减计算,如下:
(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。
以上就是策略模式的实现,通过两个例子可以看出,策略模式是对多种解决方案的封装,通过将解决方案设计成接口>具体实现类组合的方式,提高了系统的扩展性,非常实用。
总结
本文参考《设计模式的艺术》、《秒懂设计模式》两书