当一个行为需要经过多道步骤时,可以将步骤串在一起。
该模式常见於两种情境:
以上两个情境转换到现实则是:
实践的作法是:
将相关步骤串在一起的好处是,步骤变更时,只要更换步骤的下一步就好,不用动到太多程序码。
以下范例以需求「权限的验证,必须通过所有验证才算通过」为核心制作。
徽章物件、使用者物件:Badge
、User
public class Badge {
private String name;
public Badge(String name) {
this.name = name;
}
public String show() {
return name;
}
}
public class Player {
private String name;
private HashMap<String, Badge> badgeBox = new HashMap<>();
public Player(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void addNewBadge(Badge badge) {
badgeBox.put(badge.show(), badge);
}
public Badge showBadge(String badgeName) {
return badgeBox.get(badgeName);
}
}
步骤的虚拟层亲代:Doorkeeper
public abstract class Doorkeeper {
protected String name;
protected Doorkeeper nextDoorkeeper;
protected Doorkeeper(String name) {
this.name = name;
}
public void setNextDoorkeeper(Doorkeeper doorkeeper) {
this.nextDoorkeeper = doorkeeper;
}
public abstract boolean check(Player player);
}
步骤子代:BoulderBadgeDoorkeeper
、CascadeBadgeDoorkeeper
、ThunderBadgeDoorkeeper
、RainbowBadgeDoorkeeper
、SoulBadgeDoorkeeper
、MarshBadgeDoorkeeper
、VolcanoBadgeDoorkeeper
、EarthBadgeDoorkeeper
(Chain of Responsibility 物件)
public class BoulderBadgeDoorkeeper extends Doorkeeper {
public BoulderBadgeDoorkeeper() {
super("灰色徽章检查者");
}
@Override
public boolean check(Player player) {
System.out.println("我是 " + name + ",负责检查是否有灰色徽章");
Badge badge = player.showBadge("Boulder");
if (badge == null) {
System.out.println("你未持有灰色徽章,不能通过此门\n");
return false;
}
System.out.println("你持有灰色徽章,请通过此门\n");
return nextDoorkeeper.check(player);
}
}
public class CascadeBadgeDoorkeeper extends Doorkeeper {
public CascadeBadgeDoorkeeper() {
super("蓝色徽章检查者");
}
@Override
public boolean check(Player player) {
System.out.println("我是 " + name + ",负责检查是否有蓝色徽章");
Badge badge = player.showBadge("Cascade");
if (badge == null) {
System.out.println("你未持有蓝色徽章,不能通过此门\n");
return false;
}
System.out.println("你持有蓝色徽章,请通过此门\n");
return nextDoorkeeper.check(player);
}
}
public class ThunderBadgeDoorkeeper extends Doorkeeper {
public ThunderBadgeDoorkeeper() {
super("橙色徽章检查者");
}
@Override
public boolean check(Player player) {
System.out.println("我是 " + name + ",负责检查是否有橙色徽章");
Badge badge = player.showBadge("Thunder");
if (badge == null) {
System.out.println("你未持有橙色徽章,不能通过此门\n");
return false;
}
System.out.println("你持有橙色徽章,请通过此门\n");
return nextDoorkeeper.check(player);
}
}
public class RainbowBadgeDoorkeeper extends Doorkeeper {
public RainbowBadgeDoorkeeper() {
super("彩虹徽章检查者");
}
@Override
public boolean check(Player player) {
System.out.println("我是 " + name + ",负责检查是否有彩虹徽章");
Badge badge = player.showBadge("Rainbow");
if (badge == null) {
System.out.println("你未持有彩虹徽章,不能通过此门\n");
return false;
}
System.out.println("你持有彩虹徽章,请通过此门\n");
return nextDoorkeeper.check(player);
}
}
public class SoulBadgeDoorkeeper extends Doorkeeper {
public SoulBadgeDoorkeeper() {
super("粉红徽章检查者");
}
@Override
public boolean check(Player player) {
System.out.println("我是 " + name + ",负责检查是否有粉红徽章");
Badge badge = player.showBadge("Soul");
if (badge == null) {
System.out.println("你未持有粉红徽章,不能通过此门\n");
return false;
}
System.out.println("你持有粉红徽章,请通过此门\n");
return nextDoorkeeper.check(player);
}
}
public class MarshBadgeDoorkeeper extends Doorkeeper {
public MarshBadgeDoorkeeper() {
super("金色徽章检查者");
}
@Override
public boolean check(Player player) {
System.out.println("我是 " + name + ",负责检查是否有金色徽章");
Badge badge = player.showBadge("Marsh");
if (badge == null) {
System.out.println("你未持有金色徽章,不能通过此门\n");
return false;
}
System.out.println("你持有金色徽章,请通过此门\n");
return nextDoorkeeper.check(player);
}
}
public class VolcanoBadgeDoorkeeper extends Doorkeeper {
public VolcanoBadgeDoorkeeper() {
super("深红徽章检查者");
}
@Override
public boolean check(Player player) {
System.out.println("我是 " + name + ",负责检查是否有深红徽章");
Badge badge = player.showBadge("Volcano");
if (badge == null) {
System.out.println("你未持有深红徽章,不能通过此门\n");
return false;
}
System.out.println("你持有深红徽章,请通过此门\n");
return nextDoorkeeper.check(player);
}
}
public class EarthBadgeDoorkeeper extends Doorkeeper {
public EarthBadgeDoorkeeper() {
super("绿色徽章检查者");
}
@Override
public boolean check(Player player) {
System.out.println("我是 " + name + ",负责检查是否有绿色徽章");
Badge badge = player.showBadge("Earth");
if (badge == null) {
System.out.println("你未持有绿色徽章,不能通过此门");
return false;
}
System.out.println("你持有绿色徽章,请通过此门\n");
return true;
}
}
测试,挑战者小智尝试通过冠军之路的徽章检查:VictoryRoadChainOfResponsibilitySample
public class VictoryRoadChainOfResponsibilitySample {
public static void main(String[] args) {
Player player = new Player("小智");
player.addNewBadge(new Badge("Boulder"));
player.addNewBadge(new Badge("Cascade"));
player.addNewBadge(new Badge("Thunder"));
player.addNewBadge(new Badge("Rainbow"));
player.addNewBadge(new Badge("Soul"));
player.addNewBadge(new Badge("Marsh"));
player.addNewBadge(new Badge("Volcano"));
player.addNewBadge(new Badge("Earth"));
Doorkeeper boulderBadgeDoorkeeper = new BoulderBadgeDoorkeeper();
Doorkeeper cascadeBadgeDoorkeeper = new CascadeBadgeDoorkeeper();
Doorkeeper thunderBadgeDoorkeeper = new ThunderBadgeDoorkeeper();
Doorkeeper rainbowBadgeDoorkeeper = new RainbowBadgeDoorkeeper();
Doorkeeper soulBadgeDoorkeeper = new SoulBadgeDoorkeeper();
Doorkeeper marshBadgeDoorkeeper = new MarshBadgeDoorkeeper();
Doorkeeper volcanoBadgeDoorkeeper = new VolcanoBadgeDoorkeeper();
Doorkeeper earthBadgeDoorkeeper = new EarthBadgeDoorkeeper();
boulderBadgeDoorkeeper.setNextDoorkeeper(cascadeBadgeDoorkeeper);
cascadeBadgeDoorkeeper.setNextDoorkeeper(thunderBadgeDoorkeeper);
thunderBadgeDoorkeeper.setNextDoorkeeper(rainbowBadgeDoorkeeper);
rainbowBadgeDoorkeeper.setNextDoorkeeper(soulBadgeDoorkeeper);
soulBadgeDoorkeeper.setNextDoorkeeper(marshBadgeDoorkeeper);
marshBadgeDoorkeeper.setNextDoorkeeper(volcanoBadgeDoorkeeper);
volcanoBadgeDoorkeeper.setNextDoorkeeper(earthBadgeDoorkeeper);
boolean check = boulderBadgeDoorkeeper.check(player);
if (check) {
System.out.println("挑战者 " + player.getName() + " 通过冠军之路");
} else {
System.out.println("请继续挑战各地的道馆,直到获得八个徽章吧");
}
}
}
徽章物件、使用者物件:Badge
、User
class Badge {
/** @param {string} name */
constructor(name) {
this.name = name;
}
show() {
return this.name;
}
}
class Player {
/** @param {string} name */
constructor(name) {
this.name = name;
/** @type {Map<string, Badge>} */
this.badgeBox = new Map();
}
getName() {
return this.name;
}
/** @param {Badge} badge */
addNewBadge(badge) {
this.badgeBox.set(badge.show(), badge);
}
/** @param {string} badgeName */
showBadge(badgeName) {
if (this.badgeBox.has(badgeName)) {
return this.badgeBox.get(badgeName);
} else {
return null;
}
}
}
步骤的虚拟层亲代:Doorkeeper
/** @abstract */
class Doorkeeper {
/** @param {string} name */
constructor(name) {
this.name = name;
/** @type {Doorkeeper} */
this.nextDoorkeeper = null;
}
/** @param {Doorkeeper} doorkeeper */
setNextDoorkeeper(doorkeeper) {
this.nextDoorkeeper = doorkeeper;
}
/**
* @abstract
* @param {Player} player
* @returns {boolean}
*/
check(player) { return; }
}
步骤子代:BoulderBadgeDoorkeeper
、CascadeBadgeDoorkeeper
、ThunderBadgeDoorkeeper
、RainbowBadgeDoorkeeper
、SoulBadgeDoorkeeper
、MarshBadgeDoorkeeper
、VolcanoBadgeDoorkeeper
、EarthBadgeDoorkeeper
(Chain of Responsibility 物件)
class BoulderBadgeDoorkeeper extends Doorkeeper {
constructor() {
super("灰色徽章检查者");
}
/**
* @override
* @param {Player} player
* @returns {boolean}
*/
check(player) {
console.log("我是 " + this.name + ",负责检查是否有灰色徽章");
const badge = player.showBadge("Boulder");
if (badge == null) {
console.log("你未持有灰色徽章,不能通过此门\n");
return false;
}
console.log("你持有灰色徽章,请通过此门\n");
return this.nextDoorkeeper.check(player);
}
}
class CascadeBadgeDoorkeeper extends Doorkeeper {
constructor() {
super("蓝色徽章检查者");
}
/**
* @override
* @param {Player} player
* @returns {boolean}
*/
check(player) {
console.log("我是 " + this.name + ",负责检查是否有蓝色徽章");
const badge = player.showBadge("Cascade");
if (badge == null) {
console.log("你未持有蓝色徽章,不能通过此门\n");
return false;
}
console.log("你持有蓝色徽章,请通过此门\n");
return this.nextDoorkeeper.check(player);
}
}
class ThunderBadgeDoorkeeper extends Doorkeeper {
constructor() {
super("橙色徽章检查者");
}
/**
* @override
* @param {Player} player
* @returns {boolean}
*/
check(player) {
console.log("我是 " + this.name + ",负责检查是否有橙色徽章");
const badge = player.showBadge("Thunder");
if (badge == null) {
console.log("你未持有橙色徽章,不能通过此门\n");
return false;
}
console.log("你持有橙色徽章,请通过此门\n");
return this.nextDoorkeeper.check(player);
}
}
class RainbowBadgeDoorkeeper extends Doorkeeper {
constructor() {
super("彩虹徽章检查者");
}
/**
* @override
* @param {Player} player
* @returns {boolean}
*/
check(player) {
console.log("我是 " + this.name + ",负责检查是否有彩虹徽章");
const badge = player.showBadge("Rainbow");
if (badge == null) {
console.log("你未持有彩虹徽章,不能通过此门\n");
return false;
}
console.log("你持有彩虹徽章,请通过此门\n");
return this.nextDoorkeeper.check(player);
}
}
class SoulBadgeDoorkeeper extends Doorkeeper {
constructor() {
super("粉红徽章检查者");
}
/**
* @override
* @param {Player} player
* @returns {boolean}
*/
check(player) {
console.log("我是 " + this.name + ",负责检查是否有粉红徽章");
const badge = player.showBadge("Soul");
if (badge == null) {
console.log("你未持有粉红徽章,不能通过此门\n");
return false;
}
console.log("你持有粉红徽章,请通过此门\n");
return this.nextDoorkeeper.check(player);
}
}
class MarshBadgeDoorkeeper extends Doorkeeper {
constructor() {
super("金色徽章检查者");
}
/**
* @override
* @param {Player} player
* @returns {boolean}
*/
check(player) {
console.log("我是 " + this.name + ",负责检查是否有金色徽章");
const badge = player.showBadge("Marsh");
if (badge == null) {
console.log("你未持有金色徽章,不能通过此门\n");
return false;
}
console.log("你持有金色徽章,请通过此门\n");
return this.nextDoorkeeper.check(player);
}
}
class VolcanoBadgeDoorkeeper extends Doorkeeper {
constructor() {
super("深红徽章检查者");
}
/**
* @override
* @param {Player} player
* @returns {boolean}
*/
check(player) {
console.log("我是 " + this.name + ",负责检查是否有深红徽章");
const badge = player.showBadge("Volcano");
if (badge == null) {
console.log("你未持有深红徽章,不能通过此门\n");
return false;
}
console.log("你持有深红徽章,请通过此门\n");
return this.nextDoorkeeper.check(player);
}
}
class EarthBadgeDoorkeeper extends Doorkeeper {
constructor() {
super("绿色徽章检查者");
}
/**
* @override
* @param {Player} player
* @returns {boolean}
*/
check(player) {
console.log("我是 " + this.name + ",负责检查是否有绿色徽章");
const badge = player.showBadge("Earth");
if (badge == null) {
console.log("你未持有绿色徽章,不能通过此门\n");
return false;
}
console.log("你持有绿色徽章,请通过此门\n");
return true;
}
}
测试,挑战者小智尝试通过冠军之路的徽章检查:victoryRoadChainOfResponsibilitySample
const victoryRoadChainOfResponsibilitySample = () => {
const player = new Player("小智");
player.addNewBadge(new Badge("Boulder"));
player.addNewBadge(new Badge("Cascade"));
player.addNewBadge(new Badge("Thunder"));
player.addNewBadge(new Badge("Rainbow"));
player.addNewBadge(new Badge("Soul"));
player.addNewBadge(new Badge("Marsh"));
player.addNewBadge(new Badge("Volcano"));
player.addNewBadge(new Badge("Earth"));
const boulderBadgeDoorkeeper = new BoulderBadgeDoorkeeper();
const cascadeBadgeDoorkeeper = new CascadeBadgeDoorkeeper();
const thunderBadgeDoorkeeper = new ThunderBadgeDoorkeeper();
const rainbowBadgeDoorkeeper = new RainbowBadgeDoorkeeper();
const soulBadgeDoorkeeper = new SoulBadgeDoorkeeper();
const marshBadgeDoorkeeper = new MarshBadgeDoorkeeper();
const volcanoBadgeDoorkeeper = new VolcanoBadgeDoorkeeper();
const earthBadgeDoorkeeper = new EarthBadgeDoorkeeper();
boulderBadgeDoorkeeper.setNextDoorkeeper(cascadeBadgeDoorkeeper);
cascadeBadgeDoorkeeper.setNextDoorkeeper(thunderBadgeDoorkeeper);
thunderBadgeDoorkeeper.setNextDoorkeeper(rainbowBadgeDoorkeeper);
rainbowBadgeDoorkeeper.setNextDoorkeeper(soulBadgeDoorkeeper);
soulBadgeDoorkeeper.setNextDoorkeeper(marshBadgeDoorkeeper);
marshBadgeDoorkeeper.setNextDoorkeeper(volcanoBadgeDoorkeeper);
volcanoBadgeDoorkeeper.setNextDoorkeeper(earthBadgeDoorkeeper);
const check = boulderBadgeDoorkeeper.check(player);
if (check) {
console.log("挑战者 " + player.getName() + " 通过冠军之路");
} else {
console.log("请继续挑战各地的道馆,直到获得八个徽章吧");
}
}
victoryRoadChainOfResponsibilitySample();
光看名称,很难想像 Chain of Responsibility 模式的功用,当理解需求是转换需要多步骤的行为时,顿时豁然开朗。同时,理解该模式是针对特殊情况下的解,难以用於其他情境下。
明天将介绍 Behavioural patterns 的第二个模式:Command 模式。
<<: Docker:KVM管理介面(virt-manager)
基於现在kubernetes的建置实在太过容易,有kind、k3d、minikube、microk8...
在这篇文章中,我们要来认识一个函式库: Redux Toolkit。 Redux Toolkit 官...
状况描述: esxi server 7.0.0 上面运行 vSphere Client 7.0.0 ...
接下来要说的是「单选方格」 单选方格的呈现方式是 有一个问题描述 接下来左边是n 个小题,右边是m ...
k8s只是一个平台,要发挥他的价值就要让适合的服务运行在上面,所以从今天开始就会介绍一些有趣的服务(...