2016-11-13 93 views
3

我有一个类层次结构:Employee - >(Manager,Waiter,Cook)。 我想使用Spring MVC控制器构建一个Web窗体,以便能够在DB中创建并保存继承Employee的所有类型。 因此,当推送表单时,我必须将某个Model绑定到View(JSP - 页面)。问题是我的用户将使用{Waiter,Cook,Manager}的下拉列表来决定创建哪种类型。基于这些信息,我想创建实例并将它们保存在数据库中。 我该怎么做? 标准方法意味着我将绑定像这样的形式:Spring MVC:使用动态bean对象的输入表格

@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(); 
    } 

有没有更可爱和接受的方法来做到这一点?

回答

3

问题是,我的用户将决定使用{Waiter,Cook,Manager}的 下拉列表创建哪种类型。基于此信息,我想要创建实例并将它们保存在数据库中。

,我认为你的目标是松耦合的设计,以增加新的类型的员工&创作&节省逻辑,而无需修改现有类的,你需要遵循以下步骤:

(1)创建员工接口或抽象类型

(2)创建管理器,服务员,厨师类型(所有工具/延伸雇员型)

(3)创建EmployeeService接口类型与实施ManagerServiceWaiterService等。通过编写参与了create特定逻辑(如下文所述,这是增加了更多的灵活性,如果你有复杂的创建为每种类型的逻辑)

(4)添加showEmployeeForm() & createEmployee()Controller和使用ApplicationContext(根据用户所选输入检索对象)动态获取各自的EmployeeService对象。请注意,我们有单独的服务类(beans),我们使用ApplicationContext来获得正确的bean(服务员服务,管理服务,厨师服务)以调用各自的create()

的代码如下所示:

(1)创建雇员接口或抽象类型

(2)创建管理器,服务员,厨师类(所有的工具/延伸雇员型)

@Component 
public class Manager implements Employee { 
//define props 
} 

(2)的EmployeeService接口:

public interface EmployeeService { 
    public void create(); 
} 

** ManagerService类:**

@Service("ManagerService") 
public class ManagerService extends EmployeeService { 
    public void create(Manager manager) { 
     //add Manager save logic 
    } 
} 

WaiterService类:

@Service("WaiterService") 
public class WaiterService extends EmployeeService { 
    public void create(Waiter waiter) { 
    //add Waiter save logic 
    } 
} 

ChefService类:

@Service("ChefService") 
public void create(Chef chef) { 
     //add Chef save logic 
    } 
} 

(3)控制器类方法:

@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(); 
     } 
    } 

PS:我已添加有不同的EmployeeService类型 为额外的灵活性的服务层,但它是高达你使用它(因为它是)或 ,这不取决于您的create()逻辑对于不同的Employee类型有多复杂。

UPDATE: 如果用户希望增加一个新类型的员工,这将是不可能的,无需编程创建类型?

上述设计遵循/符合流行的OOP Open/Closed principle,其中说我们应该能够添加新类(新员工类型或新功能),而无需修改现有类。因此,您可以添加任意数量的新员工类型而无需修改现有类。

+0

谢谢!我正在考虑在这里实现多态而不是切换块..但没有想到将其移动到服务层!但是你不觉得新的Employee()在这里是有点多余的...在showEmployeeForm()中?由于我将从WebRequest对象中检索所有请求参数以从头构建一个后代,因此我根本不需要Model的Employee,对吧? –

+0

我已经修改了上面的代码,现在可以参考它,具体服务层是纯粹的可选 – developer

+0

是的,但直觉上我认为员工应该是抽象的。我们不能实例化......这个事实打破了Spring的注入逻辑.. –