Не існує загальноприйнятих (тобто дефакто ) інструкцій щодо проектування MVC. Зробити це не зовсім важко, але вимагає певного планування своїх занять та багато часу та терпіння.
Причина відсутності певного рішення полягає в тому, що існує декілька способів зробити MVC, все з їх плюсами і мінусами. Тому просто будьте уважні до цього і робіть те, що вам найбільше підходить.
Щоб відповісти на ваше запитання, ви також хочете від'єднати контролер від подання (щоб ви могли використовувати ту саму логіку бізнес-правил як для додатка Swing, так і для консольного додатка). У прикладі Swing ви хочете від'єднати контролер від JWindow
та будь-якого віджета в Swing. Як я раніше (перш ніж використовувати фактичні рамки), це створити інтерфейс для подання, яке використовує контролер:
public interface PersonView {
void setPersons(Collection<Person> persons);
}
public class PersonController {
private PersonView view;
private PersonModel model;
public PersonController(PersonView view, PersonModel model) {
this.view = view;
this.model = model;
}
// ... methods to affect the model etc.
// such as refreshing and sort:
public void refresh() {
this.view.setPersons(model.getAsList());
}
public void sortByName(boolean descending) {
// do your sorting through the model.
this.view.setPersons(model.getSortedByName());
}
}
Для цього рішення під час запуску потрібно зареєструвати контролер у поданні.
public class PersonWindow extends JWindow implements PersonView {
PersonController controller;
Model model;
// ... Constructor etc.
public void initialize() {
this.controller = new PersonController(this, this.model);
// do all the other swing stuff
this.controller.refresh();
}
public void setPersons(Collection<Person> persons) {
// TODO: set the JList (in case that's you are using)
// to use the given parameter
}
}
Можливо, буде гарною ідеєю створити IoC-контейнер, щоб замість нього виконати всі налаштування.
Так чи інакше, ви можете реалізувати представлення лише консолей, використовуючи ті ж контролери:
public class PersonConsole implements PersonView {
PersonController controller;
Model model;
public static void main(String[] args) {
new PersonConsole().run();
}
public void run() {
this.model = createModel();
this.controller = new PersonController(this, this.model);
this.controller.refresh();
}
public void setPersons(Collection<Person> persons) {
// just output the collection to the console
StringBuffer output = new StringBuffer();
for(Person p : persons) {
output.append(String.format("%s%n", p.getName()));
}
System.out.println(output);
}
public void createModel() {
// TODO: create this.model
}
// this could be expanded with simple console menu with keyboard
// input and other console specific stuff
}
Найцікавіша частина - як робити обробку подій. Я реалізував це, дозволивши перегляду зареєструватися в контролері за допомогою інтерфейсу, це робиться за допомогою шаблону Observer (якщо ви використовуєте .NET, ви б замість цього використовували обробники подій). Ось приклад простого "спостерігача за документами", який подає сигнал, коли документ був збережений або завантажений.
public interface DocumentObserver {
void onDocumentSave(DocModel saved);
void onDocumentLoad(DocModel loaded);
}
// in your controller you implement register/unregister methods
private List<DocumentObserver> observers;
// register observer in to the controller
public void addObserver(DocumentObserver o) {
this.observers.add(o);
}
// unregisters observer from the controller
public void removeObserver(DocumentObserver o) {
this.observers.remove(o);
}
public saveDoc() {
DocModel model = model.save();
for (DocumentObserver o : observers) {
o.onDocumentSave(model);
}
}
public loadDoc(String path) {
DocModel model = model.load(path);
for (DocumentObserver o : observers) {
o.onDocumentLoad(model);
}
}
Таким чином, представлення даних може належним чином оновлюватись, оскільки підписується на оновлення документа. Все, що потрібно зробити - це реалізувати DocumentObserver
інтерфейс:
public class DocumentWindow extends JWindow
implements DocView, DocumentObserver {
//... all swing stuff
public void onDocumentSave(DocModel saved) {
// No-op
}
public void onDocumentLoad(DocModel loaded) {
// do what you need with the loaded model to the
// swing components, or let the controller do it on
// the view interface
}
// ...
}
Я сподіваюся, що ці мотиваційні приклади дають вам кілька ідей, як це зробити самостійно. Однак я настійно раджу вам розглянути можливість використання фреймворків на Java, які роблять більшу частину речей за вас, інакше у вас з’явиться багато кодового коду, який потрібно тривалий час писати. Існує декілька платформ клієнтських програм (RCP), які можна використовувати, щоб реалізувати деякі основні функціональні можливості, які вам, швидше за все, потрібні, такі як обробка документів в масштабах додатків та багато основних подій.
Є пара, яку я можу придумати з голови: Eclipse та Netbeans RCP.
Ще потрібно розробити контролери та моделі для себе, але саме тому ви використовуєте ORM. Прикладом може бути сплячий режим .
Контейнери IoC - це все круто, але для цього також є рамки. Наприклад, Spring (який також здійснює обробку даних, а також між іншим).