2016-11-13 3 views
3

У меня есть иерархия классов: Employee -> (Manager, Waiter, Cook). Я пытаюсь создать веб-форму с помощью Spring MVC-контроллера, чтобы иметь возможность создавать и сохранять в БД все типы, наследующие Employee. Итак, при форсировании формы я должен привязать некоторую модель к представлению (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) Создать Employee интерфейс или абстрактный типа класса

(2) Создание диспетчера, официант, типов Chef (все орудия/расширяет тип сотрудника)

(3) Создание EmployeeService типа интерфейса и внедрение ManagerService, WaiterService и т.д .. написав специфическую логику, участвующую в create (Как указано ниже, это добавляется для большей гибкости, если вы сложные создать логику для каждого типа)

(4) Добавить showEmployeeForm() & createEmployee() к вашим Controller и динамически обрабатывать объект EmployeeService, используя ApplicationContext (который извлекает объект на основе выбранного ввода от пользователя). Просто имейте в виду, что у нас есть отдельные классы обслуживания (бобы), и мы используем ApplicationContext, чтобы получить правильный bean-компонент (услугу Официанта, сервис менеджера, сервис шеф-повара), чтобы вызвать соответствующие create().

код следует ниже:

(1) Создание интерфейса Сотрудник или абстрактный тип класса

(2) Создание менеджера, официанта, классы Chef (все орудия/расширяет тип работника)

@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() для разных типов сотрудников.

UPDATE: Если пользователь хочет добавить новый тип сотрудников, будет невозможно создать тип без программирования?

Вышеупомянутая конструкция соответствует/соответствует популярному ООП Open/Closed principle, в котором говорится, что мы должны иметь возможность добавлять новые классы (новые типы сотрудников или новые функции) без изменения существующих классов. Таким образом, вы можете добавить любое количество новых типов сотрудников без изменения существующих классов.

+0

Спасибо! Я думал о внедрении полиморфизма здесь вместо блока switch ... но не догадывался переместить его на сервисный уровень! Но разве вы не думаете, что новый Employee() является избыточным здесь ... в showEmployeeForm()? Поскольку я получаю все параметры запроса из объекта WebRequest для создания потомка с нуля, мне совсем не нужна модель Employee, верно? –

+0

Я изменил приведенный выше код, вы можете отсылать его сейчас. Специфический сервисный уровень является чисто необязательным. – developer

+0

Да, но интуитивно я считаю, что Сотрудник должен быть абстрактным. что мы не можем создать экземпляр ... этот факт нарушает логику инъекции Spring. –

Смежные вопросы