Skip to content

Instantly share code, notes, and snippets.

@yclim95
Last active November 17, 2018 10:51
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save yclim95/893ede0150accd2a66695d67262d128e to your computer and use it in GitHub Desktop.
Save yclim95/893ede0150accd2a66695d67262d128e to your computer and use it in GitHub Desktop.
Java Design Patterns and Architecture Part II

#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);
		}
	}

}

For FULL Codes Click Here

##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.

For FULL Codes Click Here

##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.

  1. Data Access Object Interface - This interface defines the standard operations to be performed on a model object(s).

  2. 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.

  3. Model Object or Value Object - This object is simple POJO containing get/set methods to store data retrieved using DAO class.

For FULL Codes Click Here

##Lesson 9 : Data Access Object Pattern (DAO) Factories

For FULL Codes Click Here

##Lesson 10 : JUnit Basic -> Testing DAO Tesing is vital when writing database code.....

For FULL Codes Click Here

##Lesson 11 : Extending DAO for Multiple Databases

For FULL Codes Click Here

##Lesson 12 : Save to Memory

For FULL Codes Click Here

##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

For FULL Codes Click Here

##Lesson 14 : Facades Facades basically means using a class to simplify the usage of other methods & objects.

For FULL Codes Click Here

##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

For FULL Codes Click Here

##Resources

  1. Back to Java Design Patterns and Architecture Part I
  2. Back to Main Content
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment