我有一个类的层次结构:Employee - > (经理,服务员,库克)。 我正在尝试使用Spring MVC控制器构建一个Web表单,以便能够在DB中创建并保存所有继承Employee的类型。 因此,在推送表单时,我必须将一些Model绑定到View(JSP - 页面)。问题是我的用户将使用{Waiter,Cook,Manager}的下拉列表决定要创建的类型。基于此信息,我想创建实例并将其保存在DB中。 我怎么做? 标准方法意味着我绑定一个这样的表单:
@RequestMapping("/new_employee")
public ModelAndView showEmployeeForm(){
return new ModelAndView("new_employee","employee",new Employee());
}
但是在处理表单的处理方法中,我将被迫创建给定类型的另一个实例。水木清华。像这样:
String pos = webRequest.getParameter("position");
Employee employee;
switch (pos) {
case "1":
employee = new Manager();
break;
case "2":
employee = new Chef();
break;
case "3":
employee = new Waiter();
break;
default:
throw new RuntimeException();
}
是否有更可爱和可接受的做法?
答案 0 :(得分:3)
问题是我的用户将决定使用哪个类型创建 {Waiter,Cook,Manager}的下拉列表。根据这些信息我 想要创建实例并将其保存在DB中。
我认为你的目标是松散地将设计结合起来,以增加新的员工类型。创造与在不修改现有类的情况下保存逻辑,您需要按照以下步骤操作:
(1)创建员工界面或抽象类类型
(2)创建经理,服务员,厨师类型(所有实现/扩展员工类型)
(3)创建EmployeeService
接口类型并实施ManagerService
,WaiterService
等。通过编写create
所涉及的特定逻辑(如下所述,这是添加的如果您为每种类型都有复杂的创建逻辑,则可以获得更大的灵活性)
(4)添加showEmployeeForm()
& createEmployee()
Controller
EmployeeService
使用ApplicationContext
动态获取相应的ApplicationContext
对象(根据用户选择的输入检索对象)。请注意,我们有单独的服务类(bean),我们使用create()
来获取正确的bean(Waiter服务,Manager服务,Chef服务)来调用相应的@Component
public class Manager implements Employee {
//define props
}
。
代码如下:
(1)创建员工界面或抽象类类型
(2)创建经理,服务员,厨师类(所有实施/扩展员工类型)
public interface EmployeeService {
public void create();
}
(2)EmployeeService接口:
@Service("ManagerService")
public class ManagerService extends EmployeeService {
public void create(Manager manager) {
//add Manager save logic
}
}
** ManagerService类:**
@Service("WaiterService")
public class WaiterService extends EmployeeService {
public void create(Waiter waiter) {
//add Waiter save logic
}
}
WaiterService类:
@Service("ChefService")
public void create(Chef chef) {
//add Chef save logic
}
}
ChefService类:
@Controller
public class EmployeeController {
@Autowired
private ApplicationContext appContext;
@RequestMapping("/new_employee", method=RequestMethod.GET)
public ModelAndView showEmployeeForm(){
String position = webRequest.getParameter("position");
Employee employee = (EmployeeService)appContext.getBean(position);
//Put position to session
session.setAttribute("position", position);
return new ModelAndView("new_employee","employee", employee);
}
@RequestMapping("/create", method=RequestMethod.POST)
public ModelAndView createEmployee() {
//Get position from session and then getBean
String position = session.getAttribute("position");
EmployeeService empService = (EmployeeService)appContext.getBean(position);
empService.create();
}
}
(3)控制器类方法:
var counter=0;
function call(number=-1){
counter +=number;
if(counter==0){
alert("finished");
}}
P.S。:我已经添加了具有不同EmployeeService类型的服务层 为了获得额外的灵活性,但是你可以使用它(原样)或者 这取决于你的create()逻辑的复杂程度 不同的员工类型。
<强>更新: 如果用户想要添加新类型的员工,那么在没有编程的情况下创建类型是不可能的吗?
以上设计符合/符合流行的OOP Open/Closed principle,它表示我们应该能够在不修改现有类的情况下添加新类(新员工类型或新功能)。因此,您可以添加任意数量的新员工类型,而无需修改现有类。