JYM 设计模式系列- 责任链模式,装饰模式,让你的代码更优雅!

JYM 设计模式系列- 责任链模式,装饰模式,让你的代码更优雅!

首页角色扮演代号放置RPG更新时间:2024-05-28
概述设计模式分类

总体来说设计模式分为三大类:

一:责任链模式1.1 名词解释:

责任链模式是一种行为设计模式,允许你将请求沿着处理者链进行发送。收到请求后,每个处理者均可对请求进行处理,或将其传递给链上的下个处理者。责任链模式的核心是解决一组服务中的先后执行处理关系。

责任链模式可以让各个服务模块更加清晰,而每一个模块可以通过next的方式进行获取。而每一个next是由继承的统一抽象类实现的,最终所有类的职责可以动态的进行编排使用,编排的过程可以做成可配置化。

在使用责任链时,如果场景比较固定,可写死到代码中进行初始化。但如果业务场景经常变化可以做成xml配置的方式进行处理,也可以保存到数据库中进行初始化操作。

实际的业务中在使用责任链时会进行一系列的包装,通过把不同的责任节点进行组装,构成一条完整业务的责任链。

1.2 优点:

责任链模式很好的处理单一职责和开闭原则,简单耦合也使对象关系更加清晰,而且外部的调用方并不需要关系责任链是如何处理的。

1.3责任链模式结构1.4 适用场景1.5 实现方式1.6 上demo

requestHandler :请求处理器

csharp复制代码public interface RequestHandler { boolean canHandleRequest(Request req); int getPriority(); void handle(Request req); String name(); }

Request:

arduino复制代码public class Request { /** * 此请求的类型,由链中的每个项目使用以查看它们是否应该或可以处理 * 这个特殊要求 */ private final RequestType requestType; /** * 请求的描述 */ private final String requestDescription; /** * 指示请求是否已处理。请求只能将状态从未处理切换到 * 已处理,无法“取消处理”请求 */ private boolean handled; /** * 创建给定类型和随附描述的新请求。 * * @param requestType The type of request * @param requestDescription The description of the request */ public Request(final RequestType requestType, final String requestDescription) { this.requestType = Objects.requireNonNull(requestType); this.requestDescription = Objects.requireNonNull(requestDescription); } /** * 获取请求的描述。 * * @返回请求的人可读描述 */ public String getRequestDescription() { return requestDescription; } /** * G获取此请求的类型,由命令链中的每个人使用以查看他们是否应该 * 或者可以处理这个特定的请求 * * @return The request type */ public RequestType getRequestType() { return requestType; } /** * 将请求标记为已处理 */ public void markHandled() { this.handled = true; } /** * 指示是否处理此请求 * * @return <tt>true</tt> when the request is handled, <tt>false</tt> if not */ public boolean isHandled() { return this.handled; } @Override public String toString() { return getRequestDescription(); } }

RequestType:请求枚举类

arduino复制代码public enum RequestType { defend_CASTLE, //防御城堡 TORTURE_PRISONER,//酷刑囚犯 COLLECT_TAX //收税 }

OrcCommander:兽人指挥官

typescript复制代码@Slf4j public class OrcCommander implements RequestHandler { @Override public boolean canHandleRequest(Request req) { return req.getRequestType() == RequestType.DEFEND_CASTLE; } @Override public int getPriority() { return 2; } @Override public void handle(Request req) { req.markHandled(); LOGGER.info("{} handling request "{}"", name(), req); } @Override public String name() { return "Orc commander"; } }

OrcKing: 发出由链处理的请求

scss复制代码public class OrcKing { private List<RequestHandler> handlers; public OrcKing() { buildChain(); } private void buildChain() { handlers = Arrays.asList(new OrcCommander(), new OrcOfficer(), new OrcSoldier()); } /** * Handle request by the chain. */ public void makeRequest(Request req) { handlers .stream() .sorted(Comparator.comparing(RequestHandler::getPriority)) .filter(handler -> handler.canHandleRequest(req)) .findFirst() .ifPresent(handler -> handler.handle(req)); } }

OrcOfficer:兽人军官

typescript复制代码@Slf4j public class OrcOfficer implements RequestHandler { @Override public boolean canHandleRequest(Request req) { return req.getRequestType() == RequestType.TORTURE_PRISONER; } @Override public int getPriority() { return 3; } @Override public void handle(Request req) { req.markHandled(); LOGGER.info("{} handling request "{}"", name(), req); } @Override public String name() { return "Orc officer"; } }

OrcSoldier:兽人士兵

typescript复制代码@Slf4j public class OrcSoldier implements RequestHandler { @Override public boolean canHandleRequest(Request req) { return req.getRequestType() == RequestType.COLLECT_TAX; } @Override public int getPriority() { return 1; } @Override public void handle(Request req) { req.markHandled(); LOGGER.info("{} handling request "{}"", name(), req); } @Override public String name() { return "Orc soldier"; } }

程序入口:

typescript复制代码public class App { /** * Program entry point. * * @param args command line args */ public static void main(String[] args) { var king = new OrcKing(); king.makeRequest(new Request(RequestType.DEFEND_CASTLE, "defend castle 保卫城堡")); king.makeRequest(new Request(RequestType.TORTURE_PRISONER, "torture prisoner 酷刑囚犯")); king.makeRequest(new Request(RequestType.COLLECT_TAX, "collect tax 征税")); } }

在这个例子中,我们将请求处理程序 RequestHandler组织成一个链,其中 每个处理程序都有机会轮流处理请求。这里国王 OrcKing发出请求,军事兽人 OrcCommander, OrcOfficer, OrcSoldier 形成处理程序链。

二:装饰模式2.1 什么是装饰模式解释:

装饰模式又名包装模式(Wrapper)。装饰模式是以对客户端透明的方式扩展对象的功能,是继承关系的一种替代方案。

2.2 装饰模式的组成2.3 装饰模式的优点

装饰模式的优点:

装饰模式的缺点:

2.4装饰模式的适用环境

在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。 需要动态地给一个对象增加功能,这些功能也可以动态地被撤销。 当不能采用继承的方式对系统进行扩充或者采用继承不利于系统扩展和维护时。不能采用继承的情况主要有两类:第一类是系统中存在大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长;第二类是因为类定义不能继承(如final类).

2.5 上demo

Troll:巨魔接口

csharp复制代码public interface Troll { void attack(); //攻击 int getAttackPower(); // 获取攻击力 void fleeBattle(); //逃离战斗 }

棒子巨魔实现巨魔接口:

typescript复制代码@Slf4j @RequiredArgsConstructor public class ClubbedTroll implements Troll { private final Troll decorated; @Override public void attack() { decorated.attack(); LOGGER.info("The troll swings at you with a club!"); } @Override public int getAttackPower() { return decorated.getAttackPower() 10; } @Override public void fleeBattle() { decorated.fleeBattle(); } }

一般的巨魔:

typescript复制代码@Slf4j public class SimpleTroll implements Troll { @Override public void attack() { LOGGER.info("The troll tries to grab you!"); } @Override public int getAttackPower() { return 10; } @Override public void fleeBattle() { LOGGER.info("The troll shrieks in horror and runs away!"); } }

程序入口:

scss复制代码@Slf4j public class App { /** * Program entry point. * * @param args command line args */ public static void main(String[] args) { // simple troll LOGGER.info("A simple looking troll approaches."); var troll = new SimpleTroll(); troll.attack(); troll.fleeBattle(); LOGGER.info("Simple troll power: {}.\n", troll.getAttackPower()); // 通过添加装饰器改变简单巨魔的行为 LOGGER.info("A troll with huge club surprises you."); var clubbedTroll = new ClubbedTroll(troll); clubbedTroll.attack(); clubbedTroll.fleeBattle(); LOGGER.info("Clubbed troll power: {}.\n", clubbedTroll.getAttackPower()); } }

在这个例子中,我们展示了简单的 SimpleTroll 如何首先攻击然后逃离 战斗。然后我们用 ClubbedTroll装饰 SimpleTroll 并再次执行攻击。可以看到装饰后行为发生了怎样的变化。

装饰器模式是子类化的更灵活的替代方案。 Decorator 类实现与目标相同的接口,并使用组合来“装饰”对目标的调用。使用装饰器模式可以在运行时改变类的行为。


作者:小蚂蚁技术
链接:https://juejin.cn/post/7237540467427590199

查看全文
大家还看了
也许喜欢
更多游戏

Copyright © 2024 妖气游戏网 www.17u1u.com All Rights Reserved