Dears,

This blog is moved to a new blog at:

The new update will be found at that new blog, please follow it!
This blog is no more updated.
Thanks for your visit!

Tuesday, February 11, 2014

Variations of the MVC model

Objective

This post will introduce some variations of MVC model which are popularly used in the reality. Particularly, we will consider and discuss about: MVC model using bean entity, MVC model using pure entity, and strictly MVC model.

Demonstration example

We will use a desktop application of hotel reservation management whose users are hotel employees such as receptionist, seller, manager, and system admin. We consider the module of room management: add, edit, and delete hotel room's information.
Assume that we have a table named as tblRoom in the database (named hotel) with these attributes:



- id: room id
- name: room name
- type: type of room, e.g. single, double, tween
- displayPrice: the current price of the room, this could changed by tourist season
- description: some additional description about the room, such as garden or see view...

Objective is to create a module which enable to add a new room into this database, with respecting the MVC model. We will design and code this module with three variations of MVC model:
- MVC with bean entity
- MVC with pure entity
- Strictly MVC model

MVC with bean entity

The main feature of this variation is to use bean entity which contains all entity attributes and database access methods (bean entity = pure entity + DAO). This means that bean entity class play the role of both pure entity class and control class. Consequently, in some simple application like this, we do not need any more the control class.
That's why this variation remains only two classes:
- RoomBean: bean entity class of room
- AddRoomFrm: view class for add new room function.



And the order of activities is the follow:
1. A hotel room manager enters the room information into the form of AddRoomFrm class and clicks on the "Add Room" button
2. The button clicked event processing method of AddRoomFrm is triggered, it calls the addRoom() method of RoomBean class to save the entered info into the DB.
3. The RoomBean class run the called method
4. The success is returned to the AddRoomFrm class
5. The AddRoomFrm class displays the success message on the form to the manager.



Class RoomBean.java
package mvcBean;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;

public class RoomBean {
    private String id;
    private String name;
    private String type;
    private float displayPrice;
    private String description;
    public RoomBean() {
        super();
    }
    public RoomBean(String id, String name, String type, float displayPrice,
            String description) {
        super();
        this.id = id;
        this.name = name;
        this.type = type;
        this.displayPrice = displayPrice;
        this.description = description;
    }
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getType() {
        return type;
    }
    public void setType(String type) {
        this.type = type;
    }
    public float getDisplayPrice() {
        return displayPrice;
    }
    public void setDisplayPrice(float displayPrice) {
        this.displayPrice = displayPrice;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
   
    public void addRoom(){
        String dbUrl = "jdbc:mysql://localhost:3306/hotel";
        String dbClass = "com.mysql.jdbc.Driver";
        String sql = "INSERT INTO tblRoom(id, name, type, displayPrice, description) VALUES(?,?,?,?,?)";
        try{
            Class.forName(dbClass);
            Connection con = DriverManager.getConnection (dbUrl, "root", "12345678");
            PreparedStatement ps = con.prepareStatement(sql);
            ps.setString(1, getId());
            ps.setString(2, getName());
            ps.setString(3, getType());
            ps.setFloat(4, getDisplayPrice());
            ps.setString(5, getDescription());
           
            ps.executeUpdate();
            con.close();
        }catch(Exception e){
            e.printStackTrace();
        }       
    }
}

Class AddRoomFrm.java
package mvcBean;

import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class AddRoomFrm extends JFrame implements ActionListener{
    private JTextField txtID;
    private JTextField txtName;
    private JTextField txtType;
    private JTextField txtDisplayPrice;
    private JTextField txtDescription;
    private JButton btnSubmit;
    private JButton btnReset;
   
    public AddRoomFrm(){
        super("Room management pure-MVC");
       
        txtID = new JTextField(15);
        txtName = new JTextField(15);
        txtType = new JTextField(15);
        txtDisplayPrice = new JTextField(15);
        txtDescription = new JTextField(15);
        btnSubmit = new JButton("Submit");
        btnReset = new JButton("Reset");
       
        JPanel content = new JPanel();
        content.setLayout(new GridLayout(6,2));
        content.add(new JLabel("ID:"));     content.add(txtID);
        content.add(new JLabel("Name:"));     content.add(txtName);
        content.add(new JLabel("Type:"));     content.add(txtType);
        content.add(new JLabel("Display price:"));     content.add(txtDisplayPrice);
        content.add(new JLabel("Description:"));     content.add(txtDescription);
        content.add(btnReset);     content.add(btnSubmit);
         
        btnSubmit.addActionListener(this);
        btnReset.addActionListener(this);
       
        this.setContentPane(content);
        this.pack();
       
        this.addWindowListener(new WindowAdapter(){
            public void windowClosing(WindowEvent e){
                System.exit(0);
            }
        });
    }
   
    public void actionPerformed(ActionEvent e) {
        JButton btn = (JButton) e.getSource();
        if(btn.equals(btnSubmit)){
            btnSubmit_actionperformed();
        }else if(btn.equals(btnReset)){
            btnReset_actionperformed();
        }       
    }
   
    public void btnSubmit_actionperformed() {
        RoomBean room = new RoomBean();
        room.setId(txtID.getText());
        room.setName(txtName.getText());
        room.setType(txtType.getText());
        room.setDisplayPrice(Float.parseFloat(txtDisplayPrice.getText()));
        room.setDescription(txtDescription.getText());
       
        room.addRoom();
       
        JOptionPane.showMessageDialog(this, "Add room successfullly!");
    }
   
    public void btnReset_actionperformed() {
        txtID.setText("");
        txtName.setText("");
        txtType.setText("");
        txtDisplayPrice.setText("");
        txtDescription.setText("");
    }
}

Class Test.java
package mvcBean;

public class Test {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        AddRoomFrm arf = new AddRoomFrm();
        arf.setVisible(true);
    }
}


MVC with pure entity

This is the standard variation of MVC model with three classes: model (pure model - the model class has only attributes as getter/setter methods), view, and control. In this variation, the control class plays the role of a data access object (DAO).
So, in our example, we have three classes:
- Room: pure entity of room
- AddRoomFrm: view class
- RoomDAO: control class with the role of DAO class


 And the order of activities is the follow:
1. A hotel room manager enters the room information into the form of AddRoomFrm class and clicks on the "Add Room" button
2. The button clicked event processing method of AddRoomFrm is triggered, it calls the method(s) of Room class to create an entity object of room.
3. The Room class returns the object to the view class.
4. The view class calls the addRoom() method of RoomDAO class to save the entered info which is already packaged in an entity object of room into the DB.
5. The RoomDAO class run the called method
6. The success is returned to the AddRoomFrm class
7. The AddRoomFrm class displays the success message on the form to the manager.



Class Room.java
package mvcPure;

public class Room {
    private String id;
    private String name;
    private String type;
    private float displayPrice;
    private String description;
   
    public Room() {
        super();
    }
   
    public Room(String id, String name, String type, float displayPrice,
            String description) {
        super();
        this.id = id;
        this.name = name;
        this.type = type;
        this.displayPrice = displayPrice;
        this.description = description;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public float getDisplayPrice() {
        return displayPrice;
    }

    public void setDisplayPrice(float displayPrice) {
        this.displayPrice = displayPrice;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }
}


Class RoomDAO.java
package mvcPure;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;

public class RoomDAO {
    private Connection con;
   
    public RoomDAO(){
        String dbUrl = "jdbc:mysql://localhost:3306/hotel";
        String dbClass = "com.mysql.jdbc.Driver";

        try {
            Class.forName(dbClass);
            con = DriverManager.getConnection (dbUrl, "root", "12345678");
        }catch(Exception e) {
            e.printStackTrace();
        }
    }
   
    public void addRoom(Room room){
        String sql = "INSERT INTO tblRoom(id, name, type, displayPrice, description) VALUES(?,?,?,?,?)";
        try{
            PreparedStatement ps = con.prepareStatement(sql);
            ps.setString(1, room.getId());
            ps.setString(2, room.getName());
            ps.setString(3, room.getType());
            ps.setFloat(4, room.getDisplayPrice());
            ps.setString(5, room.getDescription());
           
            ps.executeUpdate();
        }catch(Exception e){
            e.printStackTrace();
        }       
    }
}

Class AddRoomFrm.java
package mvcPure;

import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class AddRoomFrm extends JFrame implements ActionListener{
    private JTextField txtID;
    private JTextField txtName;
    private JTextField txtType;
    private JTextField txtDisplayPrice;
    private JTextField txtDescription;
    private JButton btnSubmit;
    private JButton btnReset;
   
    public AddRoomFrm(){
        super("Room management pure-MVC");
       
        txtID = new JTextField(15);
        txtName = new JTextField(15);
        txtType = new JTextField(15);
        txtDisplayPrice = new JTextField(15);
        txtDescription = new JTextField(15);
        btnSubmit = new JButton("Submit");
        btnReset = new JButton("Reset");
       
        JPanel content = new JPanel();
        content.setLayout(new GridLayout(6,2));
        content.add(new JLabel("ID:"));     content.add(txtID);
        content.add(new JLabel("Name:"));     content.add(txtName);
        content.add(new JLabel("Type:"));     content.add(txtType);
        content.add(new JLabel("Display price:"));     content.add(txtDisplayPrice);
        content.add(new JLabel("Description:"));     content.add(txtDescription);
        content.add(btnReset);     content.add(btnSubmit);
         
        btnSubmit.addActionListener(this);
        btnReset.addActionListener(this);
       
        this.setContentPane(content);
        this.pack();
       
        this.addWindowListener(new WindowAdapter(){
            public void windowClosing(WindowEvent e){
                System.exit(0);
            }
        });
    }
   
    public void actionPerformed(ActionEvent e) {
        JButton btn = (JButton) e.getSource();
        if(btn.equals(btnSubmit)){
            btnSubmit_actionperformed();
        }else if(btn.equals(btnReset)){
            btnReset_actionperformed();
        }
       
    }
   
    public void btnSubmit_actionperformed() {
        Room room = new Room();
        room.setId(txtID.getText());
        room.setName(txtName.getText());
        room.setType(txtType.getText());
        room.setDisplayPrice(Float.parseFloat(txtDisplayPrice.getText()));
        room.setDescription(txtDescription.getText());
       
        RoomDAO rd = new RoomDAO();
        rd.addRoom(room);
       
        JOptionPane.showMessageDialog(this, "Add room successfullly!");
    }
   
    public void btnReset_actionperformed() {
        txtID.setText("");
        txtName.setText("");
        txtType.setText("");
        txtDisplayPrice.setText("");
        txtDescription.setText("");
    }
}

Class Test.java
package mvcPure;

public class Test {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        AddRoomFrm arf = new AddRoomFrm();
        arf.setVisible(true);
    }
}


Strictly MVC model

In this variation, the control class is the King: it has all control rights, from the right to treat the button click event in the view form to the one to control the database access. That why the control class has some inner classes for this purpose (see more on this variation at the post: mvc-model-example-with-login-application.html).
So we have four classes in total:
- Room: pure entity of room
- AddRoomFrm: view class
- RoomControl: the King control class
- AddRoomListener: an inner class of the control class to process the Add room button click event.(This class is difined inside the class of control)



And thus the order of activities is the follow:
1. A hotel room manager enters the room information into the form of AddRoomFrm class and clicks on the "Add Room" button
2. The button clicked event triggers the event processing method of the inner class AddRoomListener, it calls the get Room() method of the view class to get information entered from the form.
3. The getRoom()  of the view class is executed
4. It calls the method(s) of Room class to create an entity object of room.
5. The Room class returns the object to the view class.
6. The view class returns the packaged object to the inner class.
7. The inner class calls the addRoom() method of RoomControl class to save the entered info which is already packaged in an entity object of room into the DB.
8. The RoomCotrol class run the called method
9. The success is returned to the inner class
10. The inner class calls displayMessage() method of the view class to display the success message
11. The AddRoomFrm class displays the success message on the form to the manager.




Class Room.java
package mvcNew;

public class Room {
    private String id;
    private String name;
    private String type;
    private float displayPrice;
    private String description;
   
    public Room() {
        super();
    }
   
    public Room(String id, String name, String type, float displayPrice,
            String description) {
        super();
        this.id = id;
        this.name = name;
        this.type = type;
        this.displayPrice = displayPrice;
        this.description = description;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public float getDisplayPrice() {
        return displayPrice;
    }

    public void setDisplayPrice(float displayPrice) {
        this.displayPrice = displayPrice;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }
}

Class AddRoomFrm.java
package mvcNew;

import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class AddRoomFrm extends JFrame implements ActionListener{
    private JTextField txtID;
    private JTextField txtName;
    private JTextField txtType;
    private JTextField txtDisplayPrice;
    private JTextField txtDescription;
    private JButton btnSubmit;
    private JButton btnReset;
   
    public AddRoomFrm(){
        super("Room management pure-MVC");
       
        txtID = new JTextField(15);
        txtName = new JTextField(15);
        txtType = new JTextField(15);
        txtDisplayPrice = new JTextField(15);
        txtDescription = new JTextField(15);
        btnSubmit = new JButton("Submit");
        btnReset = new JButton("Reset");
       
        JPanel content = new JPanel();
        content.setLayout(new GridLayout(6,2));
        content.add(new JLabel("ID:"));     content.add(txtID);
        content.add(new JLabel("Name:"));     content.add(txtName);
        content.add(new JLabel("Type:"));     content.add(txtType);
        content.add(new JLabel("Display price:"));     content.add(txtDisplayPrice);
        content.add(new JLabel("Description:"));     content.add(txtDescription);
        content.add(btnReset);     content.add(btnSubmit);
       
        this.setContentPane(content);
        this.pack();
       
        this.addWindowListener(new WindowAdapter(){
            public void windowClosing(WindowEvent e){
                System.exit(0);
            }
        });
    }
   
    public Room getRoom(){
        Room room = new Room();
        room.setId(txtID.getText());
        room.setName(txtName.getText());
        room.setType(txtType.getText());
        room.setDisplayPrice(Float.parseFloat(txtDisplayPrice.getText()));
        room.setDescription(txtDescription.getText());
        return room;       
    }
   
    public void showMessage(String msg){
        JOptionPane.showMessageDialog(this, msg);
    }
   
    public void addSubmitListener(ActionListener log) {
          btnSubmit.addActionListener(log);
        }
   
    public void actionPerformed(ActionEvent e) {
        JButton btn = (JButton) e.getSource();
        if(btn.equals(btnReset)){
            btnReset_actionperformed();
        }       
    }
   
    public void btnReset_actionperformed() {
        txtID.setText("");
        txtName.setText("");
        txtType.setText("");
        txtDisplayPrice.setText("");
        txtDescription.setText("");
    }
}

Class RoomControl.java
package mvcNew;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;

public class RoomControl {
    private Connection con;
    private Room room;
    private AddRoomFrm arf;
   
    public RoomControl(){
        String dbUrl = "jdbc:mysql://localhost:3306/hotel";
        String dbClass = "com.mysql.jdbc.Driver";

        try {
            Class.forName(dbClass);
            con = DriverManager.getConnection (dbUrl, "root", "12345678");
        }catch(Exception e) {
            e.printStackTrace();
        }
       
        arf = new AddRoomFrm();
        arf.addSubmitListener(new AddRoomListener());
        arf.setVisible(true);
       
    }
   
    public void addRoom(Room room){
        String sql = "INSERT INTO tblRoom(id, name, type, displayPrice, description) VALUES(?,?,?,?,?)";
        try{
            PreparedStatement ps = con.prepareStatement(sql);
            ps.setString(1, room.getId());
            ps.setString(2, room.getName());
            ps.setString(3, room.getType());
            ps.setFloat(4, room.getDisplayPrice());
            ps.setString(5, room.getDescription());
           
            ps.executeUpdate();
        }catch(Exception e){
            e.printStackTrace();
        }       
    }
   
    class AddRoomListener implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            try {
                room = arf.getRoom();
                addRoom(room);
                arf.showMessage("Add room successfullly!");
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }
}


Class Test.java
package mvcNew;

public class Test {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        RoomControl rc = new RoomControl();
    }

}




3 comments:

  1. This comment has been removed by the author.

    ReplyDelete
  2. The Jingle Bar at Jingle Bar & Grill | Biloxi, MS - JTM Hub
    Jingle Bar & 평택 출장마사지 Grill. $4.99, 1.49. A $1.99. Delivery or Pickup. Add to 동두천 출장마사지 Cart. Add to Cart. 대전광역 출장마사지 Rating: 4.7 · ‎10 reviews · ‎Price range: from 성남 출장마사지 $4.99 남양주 출장샵

    ReplyDelete