#Java Design Patterns and Architecture Part II
##Lesson 6 : The Singleton Pattern
The singleton pattern allows you to have a single global instance of a class, available from any part of your program. This can make your code hard to follow if you're not careful, so you should use singleton cautiously.
The Singleton's purpose is to control object creation, limiting the number of obejcts to one only. Since there is only one Singleton instance, any instance fields of a Singleton will occur only once per class, just like static fields. Singletons often control access to resources such as database connections or sockets.
To sum it off, Let's say that you want to have your Database access anywhere ....multiple places.... BUT you only want to have that particular(1) object of that class.... Then use Singleton pattern.
Database.java
package com.yclim.designpatterns.demo1.model;
public class Database {
private static Database instance = new Database();
private Database(){ //Prevent from using new()
}
public static Database getInstance(){
return instance;
}
//Previously
/*
private static Database instanceOld;
public static Database getInstanceOld() {
if(instanceOld == null) {
instanceOld = new Database();
}
return instanceOld;
}
*/
public void connect(){
System.out.println("connect to database");
}
public void disconnect(){
System.out.println("disconnect from database");
}
}
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 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.JPasswordField;
import javax.swing.JTextField;
import com.yclim.designpatterns.demo1.model.Database;
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 JPasswordField repeatPassField;
private LoginListener loginListener;
public View(Model model) throws HeadlessException {
super("MVC Demo");
this.model = model;
// Create
nameField = new JTextField(10);
passField = new JPasswordField(10);
repeatPassField = new JPasswordField(10);
okButton = new JButton("Create User");
// 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.LINE_END;
gc.gridx = 1;
gc.gridy = 3;
gc.weightx = 1;
gc.weighty = 1;
gc.insets = new Insets(0, 0, 0, 10);
gc.fill = GridBagConstraints.NONE;
add(new JLabel("Repeat password: "), gc);
gc.anchor = GridBagConstraints.LINE_START;
gc.gridx = 2;
gc.gridy = 3;
gc.weightx = 1;
gc.weighty = 1;
gc.insets = new Insets(0, 0, 0, 0);
gc.fill = GridBagConstraints.NONE;
add(repeatPassField, gc);
gc.anchor = GridBagConstraints.FIRST_LINE_START;
gc.gridx = 2;
gc.gridy = 4;
gc.weightx = 1;
gc.weighty = 100;
gc.fill = GridBagConstraints.NONE;
add(okButton, gc);
okButton.addActionListener(this);
//Database database = new Database() ==> Instead of doing this we can .....
//Database database = Database.getInstance();
addWindowListener(new WindowAdapter() {
@Override
public void windowOpened(WindowEvent e) {
//Method Chaining
Database.getInstance().connect();
}
@Override
public void windowClosing(WindowEvent e) {
Database.getInstance().disconnect();
}
});
setSize(600, 500);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
@Override
public void actionPerformed(ActionEvent e) {
String password = new String(passField.getPassword());
String repeatPassword = new String(repeatPassField.getPassword());
if(password.equals(repeatPassword)){
String name = nameField.getText();
fireLoginEvent(new LoginFormEvent(name, password) );
}else {
JOptionPane.showMessageDialog(this, "Passwords do not match.",
"Error", JOptionPane.WARNING_MESSAGE);
}
}// 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);
}
}
}
##Lesson 7 : Beans The bean pattern (although calling it a "pattern" is saying a lot) is very useful as a "transfer object" in the Observer pattern or DAO pattern.
##Lesson 8 : Data Access Object Pattern (DAO) Data Access Object Pattern or DAO pattern is used to separate low level data accessing API or operations from high level business services. Following are the participants in Data Access Object Pattern.
-
Data Access Object Interface - This interface defines the standard operations to be performed on a model object(s).
-
Data Access Object concrete class - This class implements above interface. This class is responsible to get data from a data source which can be database / xml or any other storage mechanism.
-
Model Object or Value Object - This object is simple POJO containing get/set methods to store data retrieved using DAO class.
##Lesson 9 : Data Access Object Pattern (DAO) Factories
##Lesson 10 : JUnit Basic -> Testing DAO Tesing is vital when writing database code.....
##Lesson 11 : Extending DAO for Multiple Databases
##Lesson 12 : Save to Memory
##Lesson 13 : Factory Pattern The factory pattern involves creating one or more "factory methods" that instantiates and return objects, configuring them if necessary and making decisions about precisely which objects to return, encapsulating and hiding these hideous details from the user of your API (which may be yourself).
Animal.java
public interface Animal {
public void speak();
public void eat();
}
AbstractAnimal.java
public class AbstractAnimal {
public void eat() {
System.out.println("Chomp chomp chomp");
}
}
Cat.java
/*
* Imagine that this class requires lots of configuration
* before use, e.g. via constructor parameters
*/
public class Cat extends AbstractAnimal implements Animal{
@Override
public void speak() {
System.out.println("Meouw!");
}
}
Dog.java
/*
* Imagine that this class requires lots of configuration
* before use, e.g. via constructor parameters
*/
public class Dog extends AbstractAnimal implements Animal{
@Override
public void speak() {
System.out.println("Woof!");
}
}
AnimalFactory.java
public class AnimalFactory {
public static final int CAT = 0;
public static final int DOG = 1;
public static Animal createAnimal(int type) {
switch(type) {
case CAT:
return new Cat();
case DOG:
return new Dog();
}
return null;
}
}
App.java
/*
* Factory pattern
* Want to create objects implementing some interface
* or having same parent
* Creating an object is complex
* e.g. lots of constructor parameters
* Possible to simplify choice of objects
*/
public class App {
public static void main(String[] args) {
Animal animal = AnimalFactory.createAnimal(AnimalFactory.CAT);
animal.speak();
animal.eat();
}//ENDof MAIN
}
OUTPUT
Meouw!
Chomp chomp chomp
##Lesson 14 : Facades Facades basically means using a class to simplify the usage of other methods & objects.
##Lesson 15 : Adapter Pattern
###What is Adapter Pattern ?
The Adapter pattern is simply a class that adapts the functionality of one class to some required interface
or set of methods.
##When You use it ?
You can use it whenever you need a class that implements
some particular interface
and only have a class
with the required functionality that implements a different interface
##Resources