设计模式总结
常见设计模式
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> {
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>> {
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> {
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> {
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> {
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(){ StrategyFactory<Double> context=new StrategyFactory<Double>(new ZJCouponDiscount()); BigDecimal discountAmount=context.discountAmount(10D,new BigDecimal(100)); logger.info("测试结果:直减优惠后⾦额 {}",discountAmount); }
|
一套策略框架
![image-20220828233200118](https://bolg2022.oss-cn-hangzhou.aliyuncs.com/202208282332032.png)
管理各种策略的注册
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 {
Optional<Map<E, S>> cacheMap();
S getStrategy(E e);
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> {
@Autowired(required = false) private Map<String, S> strategyBeans;
private Map<E, S> strategyCacheMap;
@Override public Optional<Map<E, S>> cacheMap() { return Optional.ofNullable(strategyCacheMap); }
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("未找到策略实现"); }
this.strategyCacheMap = initCacheMap(strategyBeans); validateStrategy(this.strategyCacheMap); log.info("策略注册结束, localCacheMap = {}", cacheMap()); }
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> {
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) { return false; }
@Override protected Map<String, S> initCacheMap(Map<String, S> strategyMap) { return strategyMap; }
@Override public void validateStrategy(Map<String, S> localCacheMap) { }
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("未找到合适的策略"); }); }
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) { return false; }
@Override protected Map<String, S> initCacheMap(Map<String, S> strategyMap) { return strategyMap; }
@Override public void validateStrategy(Map<String, S> localCacheMap) { }
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; }
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 {
default T supportType() { return null; }
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> {
@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; }
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("未找到合适的策略"); });
}
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) { }
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("未找到合适的策略"); });
}
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() { 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
|
public abstract class NetMall {
protected Logger logger = LoggerFactory.getLogger(NetMall.class); String uId; String uPwd;
public NetMall(String uId, String uPwd) { this.uId = uId; this.uPwd = uPwd; }
public String generateGoodsPoster(String skuUrl) { if (!login(uId, uPwd)) { return null; } Map<String, String> reptile = reptile(skuUrl); return createBase64(reptile); }
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> {
@Override public Map<Long, List<ObjectValueVO>> transfer(OrderTransferContext orderTransferContext) {
Map<Long, List<ObjectValueVO>> result = doTransfer(orderTransferContext);
calculateTransferInfo(orderTransferContext, result);
return result;
}
protected abstract Map<Long, List<ObjectValueVO>> doTransfer(OrderTransferContext context);
protected abstract void calculateTransferInfo(OrderTransferContext context, Map<Long, List<ObjectValueVO>> resultData);
protected abstract boolean supportMultiTransfer();
}
|
![image-20220828235056616](https://bolg2022.oss-cn-hangzhou.aliyuncs.com/202208282350542.png)
![image-20220828235132329](https://bolg2022.oss-cn-hangzhou.aliyuncs.com/202208282351238.png)
![image-20220828235147506](C:\Users\zzc\AppData\Roaming\Typora\typora-user-images\image-20220828235147506.png)
![image-20220828235206812](https://bolg2022.oss-cn-hangzhou.aliyuncs.com/202208282352860.png)
![image-20220828235220317](https://bolg2022.oss-cn-hangzhou.aliyuncs.com/202208282352298.png)
![image-20220828235239692](https://bolg2022.oss-cn-hangzhou.aliyuncs.com/202208282352471.png)
4、状态模式
使用状态模式,在对应字段状态类中判断是否可以转换成目标状态
匹配到每一种字段可转换的类型并执行转换
![image.png](https://bolg2022.oss-cn-hangzhou.aliyuncs.com/202208282357202.png)
![image-20220828235537838](https://bolg2022.oss-cn-hangzhou.aliyuncs.com/202208282355665.png)
![image-20220828235821563](https://bolg2022.oss-cn-hangzhou.aliyuncs.com/202208282358383.png)
![image-20220828235853582](https://bolg2022.oss-cn-hangzhou.aliyuncs.com/202208282358450.png)
![image-20220828235912450](https://bolg2022.oss-cn-hangzhou.aliyuncs.com/202208282359161.png)
![image-20220828235941227](https://bolg2022.oss-cn-hangzhou.aliyuncs.com/202208282359931.png)
![image-20220829000004249](https://bolg2022.oss-cn-hangzhou.aliyuncs.com/202208290000152.png)
![image-20220829000026189](https://bolg2022.oss-cn-hangzhou.aliyuncs.com/202208290000081.png)
![image-20220829000040952](https://bolg2022.oss-cn-hangzhou.aliyuncs.com/202208290000001.png)
1 2 3 4 5
|
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);
Object result = fieldStateComponent.boolState(bo,currentState);
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](https://bolg2022.oss-cn-hangzhou.aliyuncs.com/202208290014396.png)
1 2 3 4 5 6
| public interface AbstractFactory { HtmlDocument createHtml(String md); WordDocument createWord(String md); }
|
1 2 3 4 5 6 7 8 9 10
| public interface HtmlDocument { String toHtml(); void save(Path path) throws IOException; }
public interface WordDocument { void save(Path path) throws IOException; }
|
这样,我们就定义好了抽象工厂(AbstractFactory
)以及两个抽象产品(HtmlDocument
和WordDocument
)。因为实现它们比较困难,我们决定让供应商来完成。
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 factory = new FastFactory();
HtmlDocument html = factory.createHtml("#Hello\nHello, world!"); html.save(Paths.get(".", "fast.html"));
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](https://bolg2022.oss-cn-hangzhou.aliyuncs.com/202208290025682.png)
定义顶层接口,声明复制方法
![image-20220829002650548](https://bolg2022.oss-cn-hangzhou.aliyuncs.com/202208290026584.png)
管理factory的注册,与方法执行编排
![image-20220829002959295](https://bolg2022.oss-cn-hangzhou.aliyuncs.com/202208290030228.png)
抽象方法的默认实现
![image-20220829003054099](https://bolg2022.oss-cn-hangzhou.aliyuncs.com/202208290030491.png)
具体工厂的实现
![image-20220829003144589](https://bolg2022.oss-cn-hangzhou.aliyuncs.com/202208290031104.png)
![image-20220829003155173](https://bolg2022.oss-cn-hangzhou.aliyuncs.com/202208290031078.png)
![image-20220829003222921](https://bolg2022.oss-cn-hangzhou.aliyuncs.com/202208290032850.png)
…
赋予业务类复制功能
![image-20220829003258746](https://bolg2022.oss-cn-hangzhou.aliyuncs.com/202208290032717.png)
6、发布订阅
…
7、代理模式
…
8、责任链模式
…
适配器、装饰器、建造者模式等