#Java Design Patterns and Architecture Part I
##Lesson 1 : What is Model-View Controller(MVC) ?
- Model ==> Data
....1. Model will notify the **VIEW** (data changed)
....2. BackEND
....3. Responds to requests for information about its state (usually from the **VIEW**)
....4. Responds to instructions to change state (usually from the **CONTROLLER**).
- View ==> GUI ==> A system that interacts with the user
....1. Make Request for DATA from the **MODEL**
....2. Represent the data
....3. Manage the information displayed
- Controller ==> Business LoGic
....1. Informing the **MODEL** & **VIEW** upon receiving response(detect) from User => to change accordingly
##Lesson 2 : Simple MVC structure Using Swing (Example) Notice at the package listing at the below code.... all of them are all in separate packages which is a good practice.... Model, View, Controller, and the Main class should be separated espcially Model and View.
Application.java
/*
* /////// MAIN //////////
*/
package com.yclim.designpatterns.demo1;
import javax.swing.SwingUtilities;
import com.yclim.designpatterns.demo1.controller.Controller;
import com.yclim.designpatterns.demo1.model.Model;
import com.yclim.designpatterns.demo1.view.View;
public class Application {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
runApp();
}
});
}//ENDof MAIN
public static void runApp(){
//Import Model class
Model model = new Model();
//Import MODEL into View
View view = new View(model);
//Controller -> Send commands/ listen to -> Model & View
Controller controller = new Controller(model, view);
}//ENDof RunApp()
}
Controller.java
/*
* /////// CONTROLLER //////////
*/
package com.yclim.designpatterns.demo1.controller;
import com.yclim.designpatterns.demo1.model.Model;
import com.yclim.designpatterns.demo1.view.View;
public class Controller {
private Model model;
private View view;
public Controller(Model model, View view) {
this.model = model;
this.view = view;
}
}
Model.java
/*
* /////// MODEL //////////
*/
package com.yclim.designpatterns.demo1.model;
public class Model { //Does NOT import anything especially VIEW
}
View.java
/*
* /////// VIEW //////////
*/
package com.yclim.designpatterns.demo1.view;
import java.awt.HeadlessException;
import javax.swing.JFrame;
import com.yclim.designpatterns.demo1.model.Model;
public class View extends JFrame{
private Model model;
public View(Model model) throws HeadlessException {
super("MVC Demo");
this.model = model;
}
}
##Lesson 3 : Observer Pattern (How Controller-View)
Observer Pattern is common used in GUI and Event-Driven application. Observer Pattern is a vital pattern for constructing user interfaces
and often useful even in non-user-interface coding.
##Lesson 4 : Application on Observer Pattern (Using Button) Application.java
/*
* /////// MAIN //////////
*/
package com.yclim.designpatterns.demo1;
import javax.swing.SwingUtilities;
import com.yclim.designpatterns.demo1.controller.Controller;
import com.yclim.designpatterns.demo1.model.Model;
import com.yclim.designpatterns.demo1.view.View;
public class Application {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
runApp();
}
});
}//ENDof MAIN
public static void runApp(){
//Import Model class
Model model = new Model();
//Import MODEL into View
View view = new View(model);
//Controller -> Send commands/ listen to -> Model & View
Controller controller = new Controller(model, view);
}//ENDof RunApp()
}
Controller.java
/*
* /////// CONTROLLER //////////
*/
package com.yclim.designpatterns.demo1.controller;
import com.yclim.designpatterns.demo1.model.Model;
import com.yclim.designpatterns.demo1.view.View;
public class Controller {
private Model model;
private View view;
public Controller(Model model, View view) {
this.model = model;
this.view = view;
}
}
Model.java
/*
* /////// MODEL //////////
*/
package com.yclim.designpatterns.demo1.model;
public class Model { //Does NOT import anything especially VIEW
}
View.java
/*
* /////// VIEW //////////
*/
package com.yclim.designpatterns.demo1.view;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.HeadlessException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import com.yclim.designpatterns.demo1.model.Model;
public class View extends JFrame implements ActionListener{
private Model model;
private JButton helloButton;
private JButton goodByeButton;
public View(Model model) throws HeadlessException {
super("MVC Demo");
this.model = model;
helloButton = new JButton("Hello");
goodByeButton = new JButton("GoodBye");
setLayout(new GridBagLayout());
GridBagConstraints gc = new GridBagConstraints();
gc.anchor = GridBagConstraints.CENTER; //Smaller < displayArea
gc.gridx = 1;
gc.gridy = 1;
gc.weightx = 1;
gc.weighty = 1; //Vertical Spaces
gc.fill = GridBagConstraints.NONE;
add(helloButton, gc); //Set Params ==> for Button to appear
gc.anchor = GridBagConstraints.CENTER; //Smaller < displayArea
gc.gridx = 1;
gc.gridy = 2;
gc.weightx = 1;
gc.weighty = 1; //Vertical Spaces
gc.fill = GridBagConstraints.NONE;
add(goodByeButton, gc); //Set Params ==> for Button to appear
/*
* add => List of ....
* set => only 1 thing
*/
helloButton.addActionListener(this); // => run actionPerformed()
goodByeButton.addActionListener(this);
setSize(600,500); //(Width, Heigh)
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
@Override
public void actionPerformed(ActionEvent e) {
JButton source = (JButton) e.getSource(); //Get the reference on which button has inovke this
if (source == helloButton){
System.out.println("Hello there");
}else{
System.out.println("Some other BUTTON");
}
}//ENDof ActionPerformed()
}
##Lesson 5 : Observer Pattern : Implementing From Strach (with MVC)
Application.java
/*
* /////// MAIN //////////
*/
package com.yclim.designpatterns.demo1;
import javax.swing.SwingUtilities;
import com.yclim.designpatterns.demo1.controller.Controller;
import com.yclim.designpatterns.demo1.model.Model;
import com.yclim.designpatterns.demo1.view.View;
public class Application {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
runApp();
}
});
}//ENDof MAIN
public static void runApp(){
//Import Model class
Model model = new Model();
//Import MODEL into View
View view = new View(model);
//Controller -> Send commands/ listen to -> Model & View
Controller controller = new Controller(model, view);
//Passing a reference of CONTROLLER to the VIEW
//View does not know that the thing that is passed is a CONTROLLER
// All it know is that that thing has a method loginPerformed()
view.setLoginListener(controller);
}//ENDof RunApp()
}
Controller.java
/*
* /////// CONTROLLER //////////
*/
package com.yclim.designpatterns.demo1.controller;
import com.yclim.designpatterns.demo1.model.Model;
import com.yclim.designpatterns.demo1.view.LoginFormEvent;
import com.yclim.designpatterns.demo1.view.LoginListener;
import com.yclim.designpatterns.demo1.view.View;
public class Controller implements LoginListener{
private Model model;
private View view;
public Controller(Model model, View view) {
this.model = model;
this.view = view;
}
@Override
public void loginPerformed(LoginFormEvent event) {
System.out.println("Login Event Recieved. " + event.getName() + " ; " + event.getPassword());
}
}
Model.java
/*
* /////// MODEL //////////
*/
package com.yclim.designpatterns.demo1.model;
public class Model { //Does NOT import anything especially VIEW
}
View.java
/*
* /////// VIEW //////////
*/
package com.yclim.designpatterns.demo1.view;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.HeadlessException;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import com.yclim.designpatterns.demo1.model.Model;
public class View extends JFrame implements ActionListener {
private Model model;
private JButton okButton;
private JTextField nameField;
private JPasswordField passField;
private LoginListener loginListener;
public View(Model model) throws HeadlessException {
super("MVC Demo");
this.model = model;
// Create
nameField = new JTextField(10);
passField = new JPasswordField(10);
okButton = new JButton("OK");
// Set Layout
setLayout(new GridBagLayout());
// Give the layout style to the view
GridBagConstraints gc = new GridBagConstraints();
gc.anchor = GridBagConstraints.LAST_LINE_END;
gc.gridx = 1;
gc.gridy = 1;
gc.weightx = 1;
gc.weighty = 1;
gc.insets = new Insets(100, 0, 0, 10);
gc.fill = GridBagConstraints.NONE;
add(new JLabel("Name: "), gc);
gc.anchor = GridBagConstraints.LAST_LINE_START;
gc.gridx = 2;
gc.gridy = 1;
gc.weightx = 1;
gc.weighty = 1;
gc.insets = new Insets(100, 0, 0, 0);
gc.fill = GridBagConstraints.NONE;
add(nameField, gc);
gc.anchor = GridBagConstraints.LINE_END;
gc.gridx = 1;
gc.gridy = 2;
gc.weightx = 1;
gc.weighty = 1;
gc.insets = new Insets(0, 0, 0, 10);
gc.fill = GridBagConstraints.NONE;
add(new JLabel("Password: "), gc);
gc.anchor = GridBagConstraints.LINE_START;
gc.gridx = 2;
gc.gridy = 2;
gc.weightx = 1;
gc.weighty = 1;
gc.insets = new Insets(0, 0, 0, 0);
gc.fill = GridBagConstraints.NONE;
add(passField, gc);
gc.anchor = GridBagConstraints.FIRST_LINE_START;
gc.gridx = 2;
gc.gridy = 3;
gc.weightx = 1;
gc.weighty = 100;
gc.fill = GridBagConstraints.NONE;
add(okButton, gc);
okButton.addActionListener(this);
setSize(600, 500);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
@Override
public void actionPerformed(ActionEvent e) {
String password = new String(passField.getPassword());
String name = nameField.getText();
fireLoginEvent(new LoginFormEvent(name, password) );
}// ENDof ActionPerformed()
public void setLoginListener(LoginListener loginListener) {
this.loginListener = loginListener;
}
public void fireLoginEvent(LoginFormEvent event) {
// Check if loginListener is called
if (loginListener != null) {
loginListener.loginPerformed(event);
}
}
}
LoginListener.java(Interface)
package com.yclim.designpatterns.demo1.view;
public interface LoginListener {
public void loginPerformed(LoginFormEvent event);
}
LoginFormEvent.java
package com.yclim.designpatterns.demo1.view;
public class LoginFormEvent { //Hold Data of a form
private String name;
private String password;
public LoginFormEvent(String name, String password) {
this.name = name;
this.password = password;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
OUTPUT (At Console)
Login Event Recieved. YC ; 123
##Resources