我正试图掌握
Java中的访问者方法.
我正在尝试编写一个非常简单的程序来习惯它.基本上它是一个美食菜单.我想阅读用户输入(食物类型(入门,主菜……)和食物名称(意大利面,鱼……)),然后将此项添加到菜单中.
我很确定到目前为止我的代码是正确的,我只是想弄清楚如何传递用户读入的值.
我的一位同时也是程序员的朋友告诉我,你应该在访问者类中拥有所有功能(或者至少尽可能多).
那么我是否将用户输入创建为菜单元素?然后让访问者将元素添加到菜单中? (我也希望能够从菜单中删除项目,但我假设这只是对要添加的方法进行逆向工程)
或者我没有让访问者真正添加元素.例如;我只是创建菜单元素,然后传递,然后在菜单类中添加功能?
对我来说,让访问者实际添加项目是有意义的,因为它是我想要保持特定于添加访问者的功能,但每次我尝试实现时我都会被告知我必须使包含菜单的arraylist元素静态,我不禁想到我做错了.
我不是100%确定访客模式对我想做的事情是否正确?
就个人而言,我相信我要么真的,非常接近……或者说是关闭!!
你们可以提供的任何帮助都会很棒,即使你能指出一个有助于解释如何正确使用这种模式的好教程.
这是我到目前为止:
interface MenuElementVisitor {
void visit(Starter starter);
void visit(MainCourse mainCourse);
void visit(Desert desert);
void visit(Drinks drinks);
void visit(Menu menu);
}
菜单元素类
interface MenuElement {
void accept(MenuElementVisitor visitor); // MenuElements have to provide accept().
}
class Starter implements MenuElement {
private String name;
public Starter(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public void accept(MenuElementVisitor visitor) {
visitor.visit(this);
}
}
class MainCourse implements MenuElement {
private String name;
public MainCourse(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public void accept(MenuElementVisitor visitor) {
visitor.visit(this);
}
}
class Desert implements MenuElement {
private String name;
public Desert(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public void accept(MenuElementVisitor visitor) {
visitor.visit(this);
}
}
class Drinks implements MenuElement {
private String name;
public Drinks(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public void accept(MenuElementVisitor visitor) {
visitor.visit(this);
}
}
菜单类
class Menu implements MenuElement {
MenuElement[] elements;
public MenuElement[] getElements() {
return elements.clone(); // Return a copy of the array of references.
}
public Menu() {
this.elements = new MenuElement[] {
new Starter("Soup"),
new Starter("Pate"),
new MainCourse("Steak"),
new MainCourse("Fish"),
new Desert("Ice Cream"),
new Desert("Apple Tart"),
new Drinks("7up"),
new Drinks("Wine"),
};
}
public void accept(MenuElementVisitor visitor) {
for(MenuElement element : this.getElements()) {
element.accept(visitor);
}
visitor.visit(this);
}
}
访问者将项目添加到菜单
class MenuElementAddVisitor implements MenuElementVisitor {
System.out.println("Press 1 for Starter, 2 for Main Course, 3 for Desert or 4 for Drinks");
int MenuElementType = Console.readInt();
System.out.println("Type the name of the Menu Element you want to add");
String MenuElementName = Console.readString();
访客从菜单中删除项目
class MenuElementRemoveVisitor implements MenuElementVisitor {
}
运行代码演示
public class VisitorDemo {
static public void main(String[] args) {
Menu menu = new Menu();
menu.accept(new MenuElementAddVisitor());
menu.accept(new MenuElementRemoveVisitor());
}
}
最佳答案 我认为您的“添加”访问者不应该知道您使用命令行参数来指示菜单名称的事实.
实际上,这打破了SRP =>单一责任原则因为添加和阅读是两个行为所以两个责任.要理解这一点,想象一下你现在决定从文件中读取菜单名称……你必须打开并重新编码你的“添加”访问者类.
你应该有一个主要的泛型类,它只知道String(用于名称)和专门的类,有人可以创建或最终使用你的类来精确地提供参数.
所以在你的例子中,你应该尝试替换Console.readInt();和带有int方法参数和String方法参数的Console.readString().