设计模式总结

常见设计模式

1、单例模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class Singleton {

private static Singleton instance;

private Singleton() {
}

public static Singleton getInstance() {
if (null != instance) {
return instance;
}
synchronized (Singleton.class) {
if (null == instance) {
instance = new Singleton();
}
}
return instance;
}
}

2、策略模式

常用写法
1
2
3
4
5
6
7
8
9
public interface ICouponDiscount<T> {
/**
* 优惠券⾦额计算
* @param couponInfo 券折扣信息;直减、满减、折扣、N元购
* @param skuPrice sku⾦额
* @return 优惠后⾦额
*/
BigDecimal discountAmount(T couponInfo, BigDecimal skuPrice);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class MJCouponDiscount implements
ICouponDiscount<Map<String, String>> {

/**
* 满减计算
* 1. 判断满⾜x元后-n元,否则不减
* 2. 最低⽀付⾦额1元
*/
public BigDecimal discountAmount(Map<String, String> couponInfo,
BigDecimal skuPrice) {
String x = couponInfo.get("x");
String o = couponInfo.get("n");
// ⼩于商品⾦额条件的,直接返回商品原价
if (skuPrice.compareTo(new BigDecimal(x)) < 0) {
return skuPrice;
}
// 减去优惠⾦额判断
BigDecimal discountAmount = skuPrice.subtract(new BigDecimal(o));
if (discountAmount.compareTo(BigDecimal.ZERO) < 1) {
return
BigDecimal.ONE;
}
return discountAmount;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class ZJCouponDiscount implements ICouponDiscount<Double> {

/**
* 直减计算
* 1. 使⽤商品价格减去优惠价格
* 2. 最低⽀付⾦额1元
*/
public BigDecimal discountAmount(Double couponInfo, BigDecimal
skuPrice) {
BigDecimal discountAmount = skuPrice.subtract(new
BigDecimal(couponInfo));
if (discountAmount.compareTo(BigDecimal.ZERO) < 1) {
return
BigDecimal.ONE;
}
return discountAmount;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class ZKCouponDiscount implements ICouponDiscount<Double> {

/**
* 折扣计算
* 1. 使⽤商品价格乘以折扣⽐例,为最后⽀付⾦额
* 2. 保留两位⼩数
* 3. 最低⽀付⾦额1元
*/
public BigDecimal discountAmount(Double couponInfo, BigDecimal
skuPrice) {
BigDecimal discountAmount = skuPrice.multiply(new
BigDecimal(couponInfo)).setScale(2, BigDecimal.ROUND_HALF_UP);
if (discountAmount.compareTo(BigDecimal.ZERO) < 1) {
return
BigDecimal.ONE;
}
return discountAmount;
}
}
1
2
3
4
5
6
7
8
9
10
11
public class NYGCouponDiscount implements ICouponDiscount<Double> {

/**
* n元购购买
* 1. ⽆论原价多少钱都固定⾦额购买
*/
public BigDecimal discountAmount(Double couponInfo, BigDecimal
skuPrice) {
return new BigDecimal(couponInfo);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
public class StrategyFactory<T> {

private ICouponDiscount<T> couponDiscount;

public StrategyFactory(ICouponDiscount<T> couponDiscount) {
this.couponDiscount = couponDiscount;
}

public BigDecimal discountAmount(T couponInfo, BigDecimal skuPrice) {
return couponDiscount.discountAmount(couponInfo, skuPrice);
}
}
1
2
3
4
5
6
7
8
9
@Test
public void test_zj(){
// 直减;100-10,商品100元
StrategyFactory<Double> context=new StrategyFactory<Double>(new ZJCouponDiscount());
BigDecimal discountAmount=context.discountAmount(10D,new
BigDecimal(100));
logger.info("测试结果:直减优惠后⾦额 {}",discountAmount);
}


一套策略框架

image-20220828233200118

管理各种策略的注册
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public interface FactoryStrategy<E, S> extends InitializingBean {

/**
* 保存策略映射的map
*
* @return
*/
Optional<Map<E, S>> cacheMap();

/**
* 获取对应的策略
*
* @param e
* @return
*/
S getStrategy(E e);

/**
* 获取当前注册的所有策略
*
* @return
*/
Collection<S> getAllStrategy();
}
策略工厂顶级抽象类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
@Slf4j
public abstract class AbstractFactoryStrategy<E, S> implements FactoryStrategy<E, S> {

/**
* 只是用来加载后转换为strategyCacheMap
* beanName -> bean
*/
@Autowired(required = false)
private Map<String, S> strategyBeans;
/**
* supportEnum -> strategy bean
*/
private Map<E, S> strategyCacheMap;

@Override
public Optional<Map<E, S>> cacheMap() {
return Optional.ofNullable(strategyCacheMap);
}

/**
* 由具体的实现来添加内容(如枚举策略、predicate策略)
*
* @param strategyMap
* @return
*/
protected abstract Map<E, S> initCacheMap(Map<String, S> strategyMap);

@Override
public synchronized void afterPropertiesSet() {
log.info("{}策略开始注册", this.getClass().getName());
if (strategyBeans == null) {
log.info("未找到策略实现");
}

// validateStrategy(localCacheMap);
this.strategyCacheMap = initCacheMap(strategyBeans);
validateStrategy(this.strategyCacheMap);
log.info("策略注册结束, localCacheMap = {}", cacheMap());
}

/**
* 策略注册结束后校验一下
*
* @param localCacheMap
*/
public abstract void validateStrategy(Map<E, S> localCacheMap);

@Override
public S getStrategy(E e) {
if (e == null) {
throw new IllegalArgumentException("不允许通过【空的支持类型】获取对应的策略");
}
return cacheMap().map(esMap -> esMap.get(e))
.orElseThrow((Supplier<IllegalArgumentException>) () -> {
log.error("未找到合适的策略, e = {}, map = {}", e, cacheMap());
throw new IllegalArgumentException("未找到合适的策略");
});
}

@Override
public Collection<S> getAllStrategy() {
return cacheMap().map(Map::values).orElseThrow(() -> new IllegalArgumentException("策略未注册"));
}

}
1、predicate型策略选择
1
2
3
4
5
6
7
8
9
10
11
12
public interface PredicateSupport<T> {


/**
* 支持的实现
*
* @param t determine to support t or not
* @return true 支持,false 不支持
*/
Boolean support(T t);

}

predicate型single策略模式工厂

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
@Slf4j
public abstract class AbstractFactoryPredicateSingleStrategy<P, S extends PredicateSupport<P>> extends AbstractFactoryStrategy<String, S> implements PredicateSupport<P> {

@Override
public Boolean support(P p) {
// default return false in (non-factory strategy must rewrite this method)
return false;
}

@Override
protected Map<String, S> initCacheMap(Map<String, S> strategyMap) {
return strategyMap;
}

@Override
public void validateStrategy(Map<String, S> localCacheMap) {
// predicate 策略工厂默认不校验
}

public S selectStrategy(P p) {
if (p == null) {
throw new IllegalArgumentException("不允许通过【空的支持类型】获取对应的策略");
}

return cacheMap().flatMap(beanName -> beanName.values().stream().filter(s -> s.support(p)).findFirst())
.orElseThrow((Supplier<IllegalArgumentException>) () -> {
log.error("未找到合适的策略, p = {}, map = {}", p, cacheMap());
throw new IllegalArgumentException("未找到合适的策略");
});
}

/**
* 通过策略执行内容
*
* @param p
* @param <R>
* @return
*/
public <R> R selectStrategyAndDo(P p, Function<S, R> function) {
return function.apply(selectStrategy(p));
}

}

predicate型multi策略模式工厂

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
@Slf4j
public abstract class AbstractFactoryPredicateMultiStrategy<P, S extends PredicateSupport<P>> extends AbstractFactoryStrategy<String, S> implements PredicateSupport<P> {


@Override
public Boolean support(P p) {
// default return false in factory
return false;
}

@Override
protected Map<String, S> initCacheMap(Map<String, S> strategyMap) {
return strategyMap;
}

@Override
public void validateStrategy(Map<String, S> localCacheMap) {
// predicate 策略工厂默认不校验
}

/**
* 获取多strategy(无法保证顺序)
*
* @param p
* @return
*/
public List<S> selectStrategy(P p) {
if (p == null) {
throw new IllegalArgumentException("不允许通过【空的支持类型】获取对应的策略");
}

List<S> list = getAllStrategy().stream()
.filter(s -> s.support(p))
.collect(Collectors.toList());

if (CollectionUtils.isEmpty(list)) {
log.error("未找到合适的策略, p = {}, map = {}", JacksonUtil.toJson(p), cacheMap());
throw new IllegalArgumentException("未找到合适的策略");
}

return list;
}

/**
* 通过策略执行内容
*
* @param p
* @param <R> result
* @return
*/
public <R> List<R> selectStrategyAndDo(P p, Function<S, R> function) {
return selectStrategy(p).stream().map(function).collect(Collectors.toList());
}
2、固定型策略选择
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public interface SupportType<T> extends Ordered {

/**
* 支持的类型
*
* @return
*/
default T supportType() {
return null;
}

/**
* 多支持
*
* @return
*/
default Set<T> multiSupportType() {
return Collections.emptySet();
}

@Override
default int getOrder() {
return Ordered.LOWEST_PRECEDENCE;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
@Slf4j
public abstract class AbstractFactoryEnumStrategy<E extends NamedEnumEntity, S extends SupportType<E>> extends AbstractFactoryStrategy<E, S> {

/**
* 校验策略(主要是查看所有enum,观察是否有缺失)
*
* @param localCacheMap localCacheMap
*/
@Override
public abstract void validateStrategy(Map<E, S> localCacheMap);

@Override
protected Map<E, S> initCacheMap(Map<String, S> strategyMap) {
Map<E, S> localCacheMap = new LinkedHashMap<>();
for (S strategy : strategyMap.values()) {
if (strategy.supportType() != null) {
register(localCacheMap, strategy, strategy.supportType());
}

for (E supportTypeEnum : strategy.multiSupportType()) {
register(localCacheMap, strategy, supportTypeEnum);
}
}
return localCacheMap;
}

/**
* 不允许在initCacheMap外再手动注册
*
* @param localCacheMap
* @param strategy
* @param supportType
*/
private void register(Map<E, S> localCacheMap, S strategy, E supportType) {
log.info("策略注册中, enum = {}, bean = {}", supportType, strategy);
S oldStrategy = localCacheMap.put(supportType, strategy);
if (oldStrategy != null) {
log.warn("注册重复的策略, enum = {}, old = {}, new = {}", supportType, oldStrategy, strategy);
log.error("!!!", new IllegalArgumentException("策略重复,请注意"));
}
}

public S selectStrategy(E e) {
if (e == null) {
throw new IllegalArgumentException("不允许通过【空的支持类型】获取对应的策略");
}

return cacheMap().map(esMap -> esMap.get(e))
.orElseThrow((Supplier<IllegalArgumentException>) () -> {
log.error("项目正在启动中, e = {}, map = {}", e, cacheMap());
throw new IllegalArgumentException("未找到合适的策略");
});

}

/**
* 通过策略执行内容
*
* @param e enum
* @param <R> result
* @return 执行结果
*/
public <R> R selectStrategyAndDo(E e, Function<S, R> function) {
return function.apply(selectStrategy(e));
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
@Slf4j
public abstract class AbstractFactoryStringStrategy<S extends SupportType<String>> extends AbstractFactoryStrategy<String, S> {

@Override
protected Map<String, S> initCacheMap(Map<String, S> strategyMap) {
Map<String, S> localCacheMap = new LinkedHashMap<>();
for (S strategy : strategyMap.values()) {
if (strategy.supportType() != null) {
register(localCacheMap, strategy, strategy.supportType());
}

for (String supportTypeEnum : strategy.multiSupportType()) {
register(localCacheMap, strategy, supportTypeEnum);
}
}
return localCacheMap;
}

@Override
public void validateStrategy(Map<String, S> localCacheMap) {
// DO NOTHING
}

/**
* 不允许在initCacheMap外再手动注册
*
* @param localCacheMap
* @param strategy
* @param supportType
*/
private void register(Map<String, S> localCacheMap, S strategy, String supportType) {
log.info("策略注册中, enum = {}, bean = {}", supportType, strategy);
S oldStrategy = localCacheMap.put(supportType, strategy);
if (oldStrategy != null) {
log.warn("注册重复的策略, enum = {}, old = {}, new = {}", supportType, oldStrategy, strategy);
log.error("!!!", new IllegalArgumentException("策略重复,请注意"));
}
}

public S selectStrategy(String identify) {
if (identify == null) {
throw new IllegalArgumentException("不允许通过【空的支持类型】获取对应的策略");
}

return cacheMap().map(esMap -> esMap.get(identify))
.orElseThrow((Supplier<IllegalArgumentException>) () -> {
log.error("项目正在启动中, identify = {}, map = {}", identify, cacheMap());
throw new IllegalArgumentException("未找到合适的策略");
});

}

/**
* 通过策略执行内容
*
* @param identify enum
* @param <R> result
* @return 执行结果
*/
public <R> R selectStrategyAndDo(String identify, Function<S, R> function) {
return function.apply(selectStrategy(identify));
}

}
TEST
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class AbstractFactoryEnumStrategyTest {

@Test
public void enumStrategyTest() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(TestNumberStrategyConfiguration.class, OneEnumStrategy.class);
IEnumStrategy strategy = context.getBean(IEnumStrategy.class);
assertEquals("oneEnumStrategy", strategy.apply(TestNumberEnum.ONE));
assertEquals("defaultStrategy", strategy.apply(TestNumberEnum.TWO));
assertEquals("defaultStrategy", strategy.apply(TestNumberEnum.THREE));
assertEquals("defaultStrategy", strategy.apply(TestNumberEnum.OTHER));
}

@Test
public void enumStrategyMissingTest() {
// BeanCreationException actually
assertThrows(RuntimeException.class, () -> {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(TestNumberStrategyConfiguration.class);
}, "必须抛出异常,因为OneEnumStrategy未注册");
}
}
1
2
3
4
5
public interface IEnumStrategy extends Function<TestNumberEnum, String>, SupportType<TestNumberEnum> {

@Override
String apply(TestNumberEnum testNumberEnum);
}
1
2
3
4
5
6
7
8
9
10
11
12
@Service
public class OneEnumStrategy extends AbstractEnumStrategy {
@Override
public TestNumberEnum supportType() {
return TestNumberEnum.ONE;
}

@Override
public String apply(TestNumberEnum testNumberEnum) {
return "oneEnumStrategy";
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
public enum TestNumberEnum implements NamedEnumEntity {
ONE, TWO, THREE, OTHER;

@Override
public int getValue() {
return 0;
}

@Override
public String getName() {
return name();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
@Configuration
public class TestNumberStrategyConfiguration {

public static class TestNumberFactoryEnumStrategy extends AbstractFactoryEnumStrategy<TestNumberEnum, IEnumStrategy> implements IEnumStrategy {

@Override
public int getOrder() {
return 0;
}

@Override
public void validateStrategy(Map<TestNumberEnum, IEnumStrategy> localCacheMap) {
Set<TestNumberEnum> enums = new HashSet<>(Arrays.asList(TestNumberEnum.values()));
enums.removeAll(localCacheMap.keySet());
Assert.isTrue(enums.isEmpty(), "策略缺失, enums = " + enums);
}

@Override
public String apply(TestNumberEnum testNumberEnum) {
return selectStrategyAndDo(testNumberEnum, s -> s.apply(testNumberEnum));
}
}

public abstract static class AbstractEnumStrategy implements IEnumStrategy {

@Override
public int getOrder() {
return 0;
}
}

@Primary
@Bean
public IEnumStrategy factoryStrategy() {
return new TestNumberFactoryEnumStrategy();
}

@Bean
public IEnumStrategy defaultStrategy() {
return new AbstractEnumStrategy() {
@Override
public Set<TestNumberEnum> multiSupportType() {
return Sets.newHashSet(TestNumberEnum.TWO, TestNumberEnum.THREE, TestNumberEnum.OTHER);
}

@Override
public String apply(TestNumberEnum testNumberEnum) {
return "defaultStrategy";
}
};
}
}

3、模板方法模式

在抽象类中定义逻辑⾏为的执⾏顺序,控制整套逻辑的执⾏顺序和统 ⼀的输⼊、输出,⽽对于实现⽅只需要关⼼好⾃⼰的业务逻辑即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
/**
* 基础电商推⼴服务
* 1. ⽣成最优价商品海报
* 2. 海报含带推⼴邀请码
*/
public abstract class NetMall {

protected Logger logger = LoggerFactory.getLogger(NetMall.class);
String uId; // ⽤户ID
String uPwd; // ⽤户密码

public NetMall(String uId, String uPwd) {
this.uId = uId;
this.uPwd = uPwd;
}

/**
* ⽣成商品推⼴海报
*
* @param skuUrl 商品地址(京东、淘宝、当当)
* @return 海报图⽚base64位信息
*/
public String generateGoodsPoster(String skuUrl) {
if (!login(uId, uPwd)) {
return null; // 1. 验证登录
}
Map<String, String> reptile = reptile(skuUrl); // 2. 爬⾍商品
return createBase64(reptile); // 3. 组装海报
}

// 模拟登录
protected abstract Boolean login(String uId, String uPwd);

// 爬⾍提取商品信息(登录后的优惠价格)
protected abstract Map<String, String> reptile(String skuUrl);

// ⽣成商品海报信息
protected abstract String createBase64(Map<String, String> goodsInfo);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public class JDNetMall extends NetMall {

public JDNetMall(String uId, String uPwd) {
super(uId, uPwd);
}

public Boolean login(String uId, String uPwd) {
logger.info("模拟京东⽤户登录 uId:{} uPwd:{}", uId, uPwd);
return true;
}

public Map<String, String> reptile(String skuUrl) {
String str = HttpClient.doGet(skuUrl);
Pattern p9 = Pattern.compile("(?<=title\\>).*(?=</title)");
Matcher m9 = p9.matcher(str);
Map<String, String> map = new ConcurrentHashMap<String, String>();
if (m9.find()) {
map.put("name", m9.group());
}
map.put("price", "5999.00");
logger.info("模拟京东商品爬⾍解析:{} | {} 元 {}", map.get("name"),
map.get("price"), skuUrl);
return map;
}

public String createBase64(Map<String, String> goodsInfo) {
BASE64Encoder encoder = new BASE64Encoder();
logger.info("模拟⽣成京东商品base64海报");
return encoder.encode(JSON.toJSONString(goodsInfo).getBytes());
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public class TaoBaoNetMall extends NetMall {

public TaoBaoNetMall(String uId, String uPwd) {
super(uId, uPwd);
}

@Override
public Boolean login(String uId, String uPwd) {
logger.info("模拟淘宝⽤户登录 uId:{} uPwd:{}", uId, uPwd);
return true;
}

@Override
public Map<String, String> reptile(String skuUrl) {
String str = HttpClient.doGet(skuUrl);
Pattern p9 = Pattern.compile("(?<=title\\>).*(?=</title)");
Matcher m9 = p9.matcher(str);
Map<String, String> map = new ConcurrentHashMap<String, String>();
if (m9.find()) {
map.put("name", m9.group());
}
map.put("price", "4799.00");
logger.info("模拟淘宝商品爬⾍解析:{} | {} 元 {}", map.get("name"),
map.get("price"), skuUrl);
return map;
}

@Override
public String createBase64(Map<String, String> goodsInfo) {
BASE64Encoder encoder = new BASE64Encoder();
logger.info("模拟⽣成淘宝商品base64海报");
return encoder.encode(JSON.toJSONString(goodsInfo).getBytes());
}
}
1
2
3
4
5
6
7
@Test
public void test_NetMall() {
NetMall netMall = new JDNetMall("1000001","*******");
String base64 =
netMall.generateGoodsPoster("https://item.jd.com/100008348542.html");
logger.info("测试结果:{}", base64);
}
策略模式+模板模式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
@Slf4j
public abstract class AbstractOrderTransfer extends DefaultTransferSupport implements IOrderTransfer, SupportType<TransferType> {

/**
* @param orderTransferContext 选单转换上下文
* @return 返回转换后的数据
*/
@Override
public Map<Long, List<ObjectValueVO>> transfer(OrderTransferContext orderTransferContext) {

// 执行转换
Map<Long, List<ObjectValueVO>> result = doTransfer(orderTransferContext);

// 封装反写路径
calculateTransferInfo(orderTransferContext, result);

// 返回数据
return result;

}

/**
* 执行字段转换
* @param context 上下文
* @return 返回值
*/
protected abstract Map<Long, List<ObjectValueVO>> doTransfer(OrderTransferContext context);

/**
* 计算反写路径
* @param context 上下文
* @param resultData 返回数据
*/
protected abstract void calculateTransferInfo(OrderTransferContext context, Map<Long, List<ObjectValueVO>> resultData);

/**
* 是否支持多选、全选
* @return -
*/
protected abstract boolean supportMultiTransfer();


}

image-20220828235056616

image-20220828235132329

image-20220828235147506

image-20220828235206812

image-20220828235220317

image-20220828235239692

4、状态模式

使用状态模式,在对应字段状态类中判断是否可以转换成目标状态

匹配到每一种字段可转换的类型并执行转换

image.png

image-20220828235537838

image-20220828235821563

image-20220828235853582

image-20220828235912450

image-20220828235941227

image-20220829000004249

image-20220829000026189

image-20220829000040952

1
2
3
4
5
// 例如  现在需要文本转数字:
// 当前状态:currentState: 文本
// 转换流程:文本-》数字
Object result = fieldStateComponent.getStateFlowMap().get(DataType.NUM)
.apply(new FieldTransferContextBO());

或者直接把stateGroup.get(currentStatus)写在Component里面,编写每一个执行方法

1
2
3
4
5
6
7
8
//当前字段类型转成文本字段类型
Object result = fieldStateComponent.textState(bo,currentState);

//当前字段类型转成boolean字段类型
Object result = fieldStateComponent.boolState(bo,currentState);

//当前字段类型转成date字段类型
Object result = fieldStateComponent.dateState(bo,currentState);

5、抽象工厂模式

工厂方法

定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使一个类的实例化延迟到其子类。

1
2
3
4
5
public class NumberFactoryImpl implements NumberFactory {
public Number parse(String s) {
return new BigDecimal(s);
}
}
1
2
3
4
5
6
7
8
9
10
11
public interface NumberFactory {
// 创建方法:
Number parse(String s);

// 获取工厂实例:
static NumberFactory getFactory() {
return impl;
}

static NumberFactory impl = new NumberFactoryImpl();
}
1
2
NumberFactory factory = NumberFactory.getFactory();
Number result = factory.parse("123.456");

抽象工厂

提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

工厂是抽象的,产品是抽象的,而且有多个产品需要创建,因此,这个抽象工厂会对应到多个实际工厂,每个实际工厂负责创建多个实际产品:

image-20220829001410474

1
2
3
4
5
6
public interface AbstractFactory {
// 创建Html文档:
HtmlDocument createHtml(String md);
// 创建Word文档:
WordDocument createWord(String md);
}
1
2
3
4
5
6
7
8
9
10
// Html文档接口:
public interface HtmlDocument {
String toHtml();
void save(Path path) throws IOException;
}

// Word文档接口:
public interface WordDocument {
void save(Path path) throws IOException;
}

这样,我们就定义好了抽象工厂(AbstractFactory)以及两个抽象产品(HtmlDocumentWordDocument)。因为实现它们比较困难,我们决定让供应商来完成。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class FastHtmlDocument implements HtmlDocument {
public String toHtml() {
...
}
public void save(Path path) throws IOException {
...
}
}

public class FastWordDocument implements WordDocument {
public void save(Path path) throws IOException {
...
}
}
1
2
3
4
5
6
7
8
public class FastFactory implements AbstractFactory {
public HtmlDocument createHtml(String md) {
return new FastHtmlDocument(md);
}
public WordDocument createWord(String md) {
return new FastWordDocument(md);
}
}
1
2
3
4
5
6
7
8
// 创建AbstractFactory,实际类型是FastFactory:
AbstractFactory factory = new FastFactory();
// 生成Html文档:
HtmlDocument html = factory.createHtml("#Hello\nHello, world!");
html.save(Paths.get(".", "fast.html"));
// 生成Word文档:
WordDocument word = factory.createWord("#Hello\nHello, world!");
word.save(Paths.get(".", "fast.doc"));

第二个厂家

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 实际工厂:
public class GoodFactory implements AbstractFactory {
public HtmlDocument createHtml(String md) {
return new GoodHtmlDocument(md);
}
public WordDocument createWord(String md) {
return new GoodWordDocument(md);
}
}

// 实际产品:
public class GoodHtmlDocument implements HtmlDocument {
...
}

public class GoodWordDocument implements HtmlDocument {
...
}

把创建工厂的代码放到AbstractFactory中,就可以连实际工厂也屏蔽了:

1
2
3
4
5
6
7
8
9
10
11
public interface AbstractFactory {
public static AbstractFactory createFactory(String name) {
if (name.equalsIgnoreCase("fast")) {
return new FastFactory();
} else if (name.equalsIgnoreCase("good")) {
return new GoodFactory();
} else {
throw new IllegalArgumentException("Invalid factory name");
}
}
}
变种使用实例

image-20220829002543850

定义顶层接口,声明复制方法

image-20220829002650548

管理factory的注册,与方法执行编排

image-20220829002959295

抽象方法的默认实现

image-20220829003054099

具体工厂的实现

image-20220829003144589

image-20220829003155173

image-20220829003222921

赋予业务类复制功能

image-20220829003258746

6、发布订阅

7、代理模式

8、责任链模式

适配器、装饰器、建造者模式等