访问者模式为两个参数 [英] Visitor Pattern for two arguments
问题描述
这是一个问题陈述:
我们有接口/超级类学生和教师
学生有两个实现/子类,ScienceStudent和PhysicalEducationStudent
教师有ScienceTeacher和PhysicalEducationTeacher。
我们要实现getMeetingPoint(Student s,Teacher t)他们根据学生和老师的类型见面的地方。
例如,
如果它的 ScienceStudent 和 ScienceTeacher 他们在 / strong>
如果 PEStudent 和 PETeacher ,他们会在地面和
(如果其 ScienceStudent 和 PETeacher ,反之亦然,他们在自助餐厅
我们可以写一个天真的方法,使用 instanceof
进行检查。但问题是,当老师或学生延长,难以维护时,这变得复杂。
这样的东西:
public class MeetingPointDecider {
getMeetingPoint(学生,老师t){
if(s instanceof ScienceStudent&
} else if(s instanceof PhysicalEducationStudent& and instance of PhysicalEducationTeacher){
returnGRound;
}
。
。
。
}
}
另一个选择是写一个工厂,它接受一个学生和教师并返回类似MeetingPointDecision [Ground或Lab],但问题仍然存在。
有没有什么好的模式,我们可以使用,我们不必修改现有的类(或最小的修改),当添加一个新的类时,说 instanceof
ScienceStudent我们有化学学士,物理学和化学实验室,PhysicsLab。
还有机会添加更多的操作,这些操作在实现中基于
学生和教师类型(Where Visitor是一个选项,但不确定如何使用两个决定类实现)实现不同。
有人可以建议一个很好的方法来实现吗?
谢谢!
我将使用地图解决这个问题。关键在于确定老师+学生组合,价值将是会议点。对于关键,我将组合类名。这是解决方案:
public class MeetingPointDecider
{
public enum MeetingPoint {Ground,Lab,Cafeteria }
private static MeetingPoint defaultmp = MeetingPoint.Cafeteria;
private static Map< String,MeetingPoint> studentTeacherCombinations = new HashMap<>();
static {
studentTeacherCombinations.put(getMapKey(ScienceTeacher.class,ScienceStudent.class),MeetingPoint.Lab);
studentTeacherCombinations.put(getMapKey(PETeacher.class,PEStudent.class),MeetingPoint.Ground);
}
public static MeetingPoint getMeetingPoint(Student s,Teacher t)
{
String mapKey = getMapKey(t.getClass(),s.getClass()) ;
返回studentTeacherCombinations.containsKey(mapKey)?
studentTeacherCombinations.get(mapKey):defaultmp;
private static String getMapKey(Class<?extends Teacher> tCls,Class<?extends Student> sCls)
{
return tCls.getName() _+ sCls.getName();
}
}
逻辑部分在静态ctor中,地图人口稠密很容易支持未来的课程。
Here is a problem statement: We have interfaces/super classes Student and Teacher
Student has two implementations/sub clasees, ScienceStudent and PhysicalEducationStudent
Teacher has ScienceTeacher and PhysicalEducationTeacher.
We want to implement a method getMeetingPoint(Student s, Teacher t) which returns a place where they meet based on the type of Student and Teacher.
For example, if its a ScienceStudent and ScienceTeacher they meet at Lab if PEStudent and PETeacher they meet on the Ground and if its a ScienceStudent and PETeacher or vice versa, they meet at cafeteria
We can write a naive method, which checks using instanceof
. But the problem is, this becomes complex when Teacher or Student gets extended, and tough to maintain.
something like this:
public class MeetingPointDecider {
getMeetingPoint(Student s,Teacher t) {
if(s instanceof ScienceStudent && t instanceof ScienceTeacher) {
return "Lab";
} else if (s instanceof PhysicalEducationStudent && t instanceof PhysicalEducationTeacher) {
return "GRound";
}
.
.
.
}
}
Another option is writing a factory, which accepts a Student and a Teacher and returns something like MeetingPointDecision [Ground or Lab], but the problem persists.
Is there any good pattern we can use, where we do not have to modify existing classes (or minimal modification) when a new class is added, Say instanceof
ScienceStudent we have ChemistryStudent, PhysicsStudent and ChemistryLab, PhysicsLab.
There is also a chance of adding more actions, which differs in implementation based on the
Student and Teacher type ( Where Visitor is an option, but not sure how to implement with two deciding classes)
Can someone please suggest a good way to implement this?
Thanks!
I would solve this using a map. The key should identify the teacher + student combination and the value would be the meeting point. for the key I would combine the class names. Here is the solution:
public class MeetingPointDecider
{
public enum MeetingPoint { Ground, Lab, Cafeteria }
private static MeetingPoint defaultmp = MeetingPoint.Cafeteria;
private static Map<String, MeetingPoint> studentTeacherCombinations = new HashMap<>();
static {
studentTeacherCombinations.put(getMapKey(ScienceTeacher.class, ScienceStudent.class), MeetingPoint.Lab);
studentTeacherCombinations.put(getMapKey(PETeacher.class , PEStudent.class) , MeetingPoint.Ground);
}
public static MeetingPoint getMeetingPoint(Student s,Teacher t)
{
String mapKey = getMapKey(t.getClass(), s.getClass());
return studentTeacherCombinations.containsKey(mapKey) ?
studentTeacherCombinations.get(mapKey) : defaultmp;
}
private static String getMapKey (Class<? extends Teacher> tCls, Class<? extends Student> sCls)
{
return tCls.getName() + "_" + sCls.getName();
}
}
The logic part is in the static ctor where the map gets populated. It is easy to support future classes.
这篇关于访问者模式为两个参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!