Tidak ada pedoman desain (yaitu defacto ) yang disepakati bersama untuk MVC. Ini tidak sepenuhnya sulit untuk dilakukan sendiri tetapi membutuhkan perencanaan kelas Anda dan banyak waktu dan kesabaran.
Alasan tidak ada solusi pasti adalah karena ada banyak cara untuk melakukan MVC, semua dengan pro dan kontra mereka. Jadi, cerdaslah tentang hal itu dan lakukan yang terbaik untuk Anda.
Untuk menjawab pertanyaan Anda, Anda sebenarnya juga ingin memisahkan pengontrol dari tampilan (sehingga Anda dapat menggunakan logika aturan bisnis yang sama untuk aplikasi Swing dan aplikasi konsol). Dalam contoh Swing Anda ingin memisahkan controller dari JWindow
widget apa pun di Swing. Cara yang biasa saya lakukan (sebelum menggunakan kerangka kerja aktual) adalah membuat antarmuka untuk tampilan yang digunakan pengontrol:
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());
}
}
Untuk solusi ini selama startup Anda perlu mendaftarkan controller ke tampilan.
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
}
}
Ini mungkin ide yang baik untuk membuat wadah-IOC untuk melakukan semua pengaturan untuk Anda sebagai gantinya.
Bagaimanapun, dengan cara ini Anda dapat mengimplementasikan tampilan konsol saja, menggunakan pengontrol yang sama:
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
}
Bagian yang menyenangkan adalah bagaimana melakukan penanganan acara. Saya menerapkan ini dengan membiarkan tampilan mendaftar sendiri ke controller menggunakan antarmuka, ini dilakukan menggunakan pola Observer (jika Anda menggunakan .NET Anda akan menggunakan event handler sebagai gantinya). Berikut adalah contoh "pengamat dokumen" yang sederhana, yang memberi sinyal ketika dokumen telah disimpan atau dimuat.
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);
}
}
Dengan begitu, tampilan dapat memperbarui dirinya dengan benar karena berlangganan pembaruan dokumen. Yang harus dilakukan hanyalah mengimplementasikan DocumentObserver
antarmuka:
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
}
// ...
}
Saya harap contoh-contoh yang memotivasi ini memberi Anda beberapa ide tentang bagaimana melakukannya sendiri. Namun saya sangat menyarankan Anda untuk mempertimbangkan menggunakan kerangka kerja di Jawa yang melakukan sebagian besar hal untuk Anda, atau Anda akan berakhir memiliki banyak kode boilerplate yang membutuhkan waktu lama untuk menulis. Ada beberapa Rich Client Platforms (RCP) yang dapat Anda gunakan yang mengimplementasikan beberapa fungsi dasar yang paling mungkin Anda butuhkan, seperti penanganan dokumen di seluruh aplikasi dan banyak penanganan acara dasar.
Ada beberapa yang bisa saya pikirkan dari kepala saya: Eclipse dan Netbeans RCP.
Anda masih perlu mengembangkan pengontrol dan model untuk diri Anda sendiri, tetapi itu sebabnya Anda menggunakan ORM. Contohnya adalah Hibernate .
Kontainer IoC memang keren, tapi ada kerangka kerja untuk ini juga. Seperti Spring (yang juga menangani data juga antara lain).