Java设计模式--策略模式,枚举+⼯⼚⽅法实现如果项⽬中的⼀个页⾯跳转功能存在10个以上的if else判断,想要做⼀下整改
⼀、什么是策略模式
策略模式是对算法的包装,是把使⽤算法的责任和算法本⾝分割开来,委派给不同的对象管理,最终可以实现解决多重If判断问题。
1.环境(Context)⾓⾊:持有⼀个Strategy的引⽤。
2.抽象策略(Strategy)⾓⾊:这是⼀个抽象⾓⾊,通常由⼀个接⼝或抽象类实现。此⾓⾊给出所有的具体策略类所需的接⼝。
3.具体策略(ConcreteStrategy)⾓⾊:包装了相关的算法或⾏为。
(定义策略接⼝→实现不同的策略类→利⽤多态或其他⽅式调⽤策略。)
⼆、策略模式优缺点
优点:
算法可以⾃由切换(⾼层屏蔽算法,⾓⾊⾃由切换)
避免使⽤多重条件判断(如果算法过多就会出现很多相同的判断,很难维护)
扩展性好(可⾃由添加取消算法,⽽不影响整个功能)
缺点:
策略数量增多(每⼀个策略类复⽤性⼩,如果需要增加算法,就只能新增类)
所有的策略类都需要对外暴露(使⽤的⼈必须了解使⽤策略,这个就需要其他模式来补充,⽐如⼯⼚模式、代理模式)
三、代码⽰例
1.定义共同的⽅法和⾏为
package com.ultiwill.strategy;
public interface PayStrategy {
/**
* 共同的⾏为⽅法
* @return
*/
String toPayHtml();
}
2. 三种具体策略的实现 (阿⾥⽀付, ⽀付, ⼩⽶⽀付)
package com.ultiwill.strategy.impl;
import com.ultiwill.strategy.PayStrategy;
/**
* @author chong.zuo
* @date 2020/9/24 15:21
*/
public class AliPayStrategy implements PayStrategy {
@Override
public String toPayHtml() {
return "调⽤阿⾥⽀付...AliPayStrategy";
}
package com.ultiwill.strategy.impl;
import com.ultiwill.strategy.PayStrategy;
/**
* @author chong.zuo
* @date 2020/9/24 15:29
*/
public class WeChatPayStrategy implements PayStrategy {
@Override
public String toPayHtml() {
return "调⽤⽀付...WeChatPayStrategy";
}
}
package com.ultiwill.strategy.impl;
import com.ultiwill.strategy.PayStrategy;
/**
* @author chong.zuo
* @date 2020/9/24 15:34
*/
public class XiaomiPayStrategy implements PayStrategy {
@Override
public String toPayHtml() {
return "调⽤⼩⽶⽀付...XiaomiPayStrategy";
}
}
3. 枚举类定义映射地址
package com.ums;
import org.apachemons.lang.StringUtils;
/**
* 枚举
* @author chong.zuo
* @date 2020/9/24 15:45
*/
public enum PayEnumStrategy {
/**
* 阿⾥⽀付
*/
ALI_PAY("1","com.ultiwill.strategy.impl.AliPayStrategy"),
/**
* ⽀付
*/
WECHAT_PAY("2","com.ultiwill.strategy.impl.WeChatPayStrategy"), /**
* ⼩⽶⽀付
*/
XIAOMI_PAY("3","com.ultiwill.strategy.impl.XiaomiPayStrategy");
private String code;
private String className;
PayEnumStrategy() {
}
PayEnumStrategy(String code, String className) {
this.className = className;
}
public static String getClassNameByCode(String code) {
String className = "";
if (StringUtils.isEmpty(code)) {
return className;
}
for (PayEnumStrategy e : PayEnumStrategy.values()) {
if (e.code.equalsIgnoreCase(code)) {
className = e.className;
break;
}
}
return className;
}
public String getCode() {
return code;
}
public String getClassName() {
return className;
}
4.⼯⼚类反射执⾏
package com.ultiwill.strategy.factory;
import com.ultiwill.strategy.PayStrategy;
import com.ums.PayEnumStrategy;
/**
* @author chong.zuo
* @date 2020/9/24 16:10
*/
public class StrategyFactory {
/**
* 使⽤策略⼯⼚获取具体策略实现
* @param code
* @return
*/
public static PayStrategy getPayStrategy(String code) {
try {
return (PayStrategy) Class.ClassNameByCode(code)).newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
}
5.上下⽂获取具体策略
package com.t;
import com.ultiwill.strategy.PayStrategy;
import com.ums.PayEnumStrategy;
import com.ultiwill.strategy.factory.StrategyFactory;
import org.apachemons.lang.StringUtils;
/**
* 上下⽂
*
* @author chong.zuo
* @date 2020/9/24 15:41
*/
public class PayContextStrategy {
/
**
* 获取具体的策略实现
*
* @param code
* @return
*/
public static String toPayHtml(String code) {
if (StringUtils.isBlank(code)) {
return "code不能为空...";
}
PayStrategy payStrategy = PayStrategy(code);
if (payStrategy == null) {
return "没有到具体的策略...";
}
PayHtml();
}
}
四、测试
controller:
package ller;
import com.t.PayContextStrategy;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author c
* @date 2020/5/14 9:59
*/
@RestController
public class TestController {
@RequestMapping("/helloworld")
public String hello(String code) {
PayHtml(code);
/*if ("0".equals(code)) {
return "调⽤阿⾥⽀付...AliPayStrategy";
} else if ("1".equals(code)) {
return "调⽤⽀付...AliPayStrategy";
} else if ("2".equals(code)) {
return "调⽤⼩⽶⽀付...AliPayStrategy";
}
return "调⽤接⼝不存在";
*/
}
}
spring boot原理和设计模式pom:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="/POM/4.0.0"
xmlns:xsi="/2001/XMLSchema-instance"
xsi:schemaLocation="/POM/4.0.0 /xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion>
<groupId>com.ultiwill</groupId>
<artifactId>springboot-jar</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<version>2.1.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<version>2.1.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.1.8.RELEASE</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.1.8.RELEASE</version>
<configuration>
<includeSystemScope>true</includeSystemScope>
<mainClass>com.ultiwill.Application</mainClass>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
五、结果
六、在spring中通过Autowired注解实现策略模式
使⽤AutowireCapableBeanFactory⼿动注⼊
使⽤.newInstance();创建对象的话,如果其他对象都使⽤Spring Autowired,还需要⼿动创建所有依赖的Bean: private @Autowired AutowireCapableBeanFactory beanFactory;
public void process() {
MyBean obj = new MyBean();
beanFactory.autowireBean(obj);
// obj will now have its dependencies autowired.
}
本例中可以使⽤
private @Autowired AutowireCapableBeanFactory beanFactory;
/**
* 使⽤策略⼯⼚获取具体策略实现
* @param code
* @return
*/
public PayStrategy getPayStrategy(String code) {
String className = ClassNameByCode(code);
try {
PayStrategy str = (PayStrategy) Class.forName(className).getDeclaredConstructor().newInstance();
beanFactory.autowireBean(str);
return str;
} catch (InstantiationException |
NoSuchMethodException |
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论