[英]Visitor Design Pattern, How to deal with If-else statement
Problem statement: 问题陈述:
There are three types of Machines, Machine1 Machine2 and Machine3. 机器共有三种类型,即Machine1 Machine2和Machine3。 There are three types of validators, ValidatorX , ValidatorY , ValidatorZ. 验证器有以下三种类型:ValidatorX,ValidatorY和ValidatorZ。
Each Validator validates each machine differently. 每个验证器以不同的方式验证每台计算机。
Write Java classes to design the above problem. 编写Java类来设计上述问题。
The program runs from a main function , which already has the list of validators and machines. 该程序从主要功能运行,该功能已经具有验证器和机器的列表。 Each Validator should print a message during validation 每个验证器应在验证期间打印一条消息
"Validator X validating Machine Y"; “验证者X验证机Y”;
To design this, First of all I have created one Machine class and 3 different Validator classes. 为此,我首先创建了一个Machine类和3个不同的Validator类。
Machine.java 机器.java
/**
* Machine
*
* @author sunny
*
*/
public class Machine {
private final String name;
public Machine(final String name) {
this.name = name;
}
public boolean validate(final Validator validator) {
return validator.validate(this);
}
public String getName() {
return name;
}
}
Validator.java 验证程序
/**
* This is an abstract class for a Validator
*
* @author sunny
*
*/
public abstract class Validator {
private String name;
public Validator(final String name) {
this.name = name;
}
public boolean validate(final Machine machine) {
System.out.println("Validator " + getName() + " validating "
+ machine.getName());
// Here I need to write login corresponding to the machine name
// I need to write if machine Name is X then do this
// if machine name is Y then do this.
// I need to avoid this if else or switch case
// Is there any other better way to achieve this.
return true;
}
public String getName() {
return name;
}
}
ValidatorX.java ValidatorX.java
/**
* This is one ValidatorX class that I have created
*
* Similarly I have written ValidatorY and ValidatorZ classes
*
* @author sunny
*
*/
public class ValidatorX extends Validator {
public ValidatorX() {
super("X");
}
@Override
public boolean validate(Machine machine) {
super.validate(machine);
return true;
}
}
TestMain.java TestMain.java
import java.util.ArrayList;
import java.util.List;
/**
* Test class I have written to test this.
*
* @author sunny
*
*/
public class TestMain {
public static void main(String[] args) {
Validator[] validators = { new ValidatorX(), new ValidatorY(),
new ValidatorZ() };
List<Machine> machines = new ArrayList<Machine>();
machines.add(new Machine("Machine1"));
machines.add(new Machine("Machine2"));
machines.add(new Machine("Machine3"));
for (int i = 0; i < validators.length; i++) {
for (Machine machine : machines) {
validators[i].validate(machine);
}
}
}
}
In Validator.java (as you can see in the comments) I need to write login corresponding to the machine name, I need to write if machine Name is Machine1 then do this if machine name is Machine2 then do this. 在Validator.java中(您可以在注释中看到),我需要编写与计算机名称相对应的登录名,如果计算机名称是Machine1,则需要编写登录名,然后如果计算机名称是Machine2,则需要编写登录名。 I need to avoid this if else or switch case. 我需要避免这种情况,否则请切换大小写。 Is there any other better way to achieve this. 还有其他更好的方法来实现这一目标。
You might use an action map. 您可以使用动作图。
Map<String, Action> actionMap = new HashMap<>();
actionMap.put("Machine1", new SomeActionOne());
actionMap.put("Machine2", new SomeActionTwo());
actionMap.put("Machine3", new SomeActionThree());
for (int i = 0; i < validators.length; i++) {
for (Machine machine : machines) {
validators[i].validate(machine);
Action action = actionMap.get(machine.getName());
assert action != null;
action.doSomething();
}
}
Your use of the visitor pattern is fine, problem is the Machine Class. 您对访问者模式的使用很好,问题出在机器类上。
From what I see, your machine class represent "depending" on name, different version/type of machine. 据我所知,您的机器类代表“取决于”名称,机器的不同版本/类型。 Therefore you need the if/else to identify the machine and act accordingly. 因此,您需要if / else来识别机器并采取相应的措施。
Your problem coudl be fixe by Abstraction 您的问题可以通过抽象来解决
AbstractMachine - would be the class that represent the shared functions to each of your machine type/categories> AbstractMachine-将是代表每种机器类型/类别的共享功能的类>
So in it you would have at the very least the following functions : 因此,它至少具有以下功能:
public boolean Validate (...)
public string GetName()
abstract public void MachineAction(...) = 0;
Therefore you would have to write up the class Machine1, Machine2, Machine3 and you would be obligated to "overload" MachineAction for each child class. 因此,您将不得不编写Machine1,Machine2,Machine3类,并且必须为每个子类“重载” MachineAction。
Your validator's validate function would then look like this : 验证器的validate函数将如下所示:
public boolean validate(final Machine machine)
{
System.out.println("Validator " + getName() + " validating "
+ machine.getName());
machine.MachineAction(...);
return true;
}
By design, it is better than having a Dictionnary(Map) of functions and you are sure to always call the right one. 通过设计,它比具有Dictionnary(Map)函数要好,并且您可以确保始终调用正确的函数。
++ I would really give better name than Machine1, Machine2, Machine3 - there is something bigger than a "name" difference here ++我真的会给比Machine1,Machine2,Machine3更好的名称-这里有些东西比“名称”大
EDIT:: 编辑::
MachineA : Child Class (inherits from) Machine
//Since it inherits from Machine no need to reimplement
//Validate/GetName, but we need and it's obligated to
//reimplement MachineAction for this subclass.
override public void MachineAction(...)
{
DoThisMachineA();
}
private void DoThisMachineA(){...}
while MachineB would look like this : 而MachineB看起来像这样:
MachineB : Child Class (inherits from) Machine
//Since it inherits from Machine no need to reimplement
//Validate/GetName, but we need and it's obligated to
//reimplement MachineAction for this subclass.
override public void MachineAction(...)
{
DoThisMachineB();
}
private void DoThisMachineB(){...}
** Note that DoThisMachineB() does not exist in the MachineA class, and would not be presented by the intellisense, and would not compile at all, and vice versa. **请注意,DoThisMachineB()在MachineA类中不存在,并且不会由智能感知提供,也不会编译,反之亦然。
Yet in the visitor, all you would have to do is Call MachineAction(...) has the visitor knows it's a Machine but not which child-type of machine and that what-ever type of machine you are, you will act properly on a MachineAction(..) call. 但是,在访客中,您所要做的就是致电MachineAction(...),让访客知道这是一台机器,但不是哪种子类型的机器以及无论哪种类型的机器,您都可以正常操作MachineAction(..)调用。 You can read on this, we call it polymorphism. 您可以阅读此书,我们称之为多态性。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.