MVC에 대해 일반적으로 합의 된 (즉, 사실상의 ) 설계 지침은 없습니다. 혼자서하는 것이 어렵지는 않지만 수업에 대한 계획과 많은 시간과 인내심이 필요합니다.
확실한 해결책이없는 이유는 장단점을 가지고 MVC를 수행하는 여러 가지 방법이 있기 때문입니다. 따라서 그것에 대해 현명하고 자신에게 가장 적합한 것을하십시오.
귀하의 질문에 대답하기 위해 실제로 컨트롤러를 뷰에서 분리하려고합니다 (따라서 Swing 앱과 콘솔 앱 모두에 동일한 비즈니스 규칙 논리를 사용할 수 있습니다). Swing 예제에서는 Swing의 JWindow
및 어떤 위젯에서 컨트롤러를 분리하려고합니다 . (실제 프레임 워크를 사용하기 전에) 내가했던 방식은 컨트롤러가 사용하는보기에 대한 인터페이스를 만드는 것입니다.
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 (Rich Client Platforms)가 있습니다.
내 머리에서 생각할 수있는 몇 가지가있다 : Eclipse 와 Netbeans RCP.
여전히 스스로 컨트롤러와 모델을 개발해야하지만, ORM을 사용하는 이유입니다. 예는 최대 절전 모드 입니다.
IoC 컨테이너는 모두 멋지지만 이에 대한 프레임 워크도 있습니다. Spring 과 같은 (데이터 처리뿐만 아니라 다른 것들도 수행).