This pattern creates objects without exposing the creation logic of each object.
The Client Class
public class Client {
public static void main(String[] args) {
MagicalComputerFactory.create("Macbook");
MagicalComputerFactory.create("Windows");
}
}
The Computer Interface
public interface Computer {
//we can specify the properties of a computer
}
Class Macbook, a concrete implementation of the interface
public class Macbook implements Computer {
//we can specify the properties of a macbook
}
Class WindowsPc, a concrete implementation of the interface
public class WindowsPC implements Computer {
//we can specify the properties of a windows pc
}
The Factory class
//factory method hides the type of object and the process that is used to create the object
public class MagicalComputerFactory implements Computer{
public static Computer create(String type) {
switch(type) {
case "Macbook":
System.out.println("Created a macbook");
return new Macbook();
default:
System.out.println("Created a windows pc");
return new WindowsPC();
}
}
}
The Client Class
public class Client {
//A singleton implementation to create stars
public static void main(String [] args) {
Star star = Star.getStar();
if(star != null) {
System.out.println("A star appeared in the solar system!");
}
}
}
The Singleton Star
public class Star {
//there can only be one star in this solar system!
private Star() {}
private static Star star = new Star();
public static Star getStar() {
if(star == null) {
star = new Star();
}
return star;
}
}
The Client Class
public class Client {
//the purpose is that we do not have enough memory to create humans, so we now use ape instead
public static void main(String [] args) {
Human human = new Adapter(new ApeKing());
human.talk();
}
}
Human Interface
public interface Human {
public abstract void talk();
}
Concrete implementation of the Human Interface
public class USCitizen implements Human {
public void talk() {
System.out.println("Humans talking");
}
}
The Ape Interface
public interface Ape {
abstract public void extremities();
public abstract void groan();
}
Concrete Implementation of Ape
public class ApeKing implements Ape{
public void extremities() {
System.out.println("2 legs and 2 arms");
}
public void groan() {
System.out.println("Primates making sounds");
}
}
The ape to human adapter
//adapting apes to humans
public class Adapter implements Human{
private Ape ape;
public Adapter(Ape ape) {
this.ape = ape;
}
//the method for humans is now being used for an object of ape, thus adapting a human to an ape.
public void talk() {
ape.groan();
}
}
The Client Class
public class Client {
public static void main(String [] args) {
Athelete john = new WeightLifter(new WorkOut(), new Recover());
john.train();
Athelete serena = new Swimmer (new WorkOut(), new Recover());
serena.train();
}
}
Abstract Athelete Class
public abstract class Athelete {
protected Training training1;
protected Training training2;
protected Athelete(Training training1, Training training2) {
this.training1 = training1;
this.training2 = training2;
}
abstract public void train();
}
Interface Training
public interface Training {
abstract public void train();
}
WeightLifter Class
//this is a refined abstraction
public class WeightLifter extends Athelete{
protected WeightLifter(Training training1, Training training2) {
super(training1, training2);
}
@Override
public void train() {
System.out.println("Weight Lifter John: ");
training1.train();
training2.train();
}
}
Swimmer Class
//another refined abstraction
public class Swimmer extends Athelete{
protected Swimmer(Training training1, Training training2) {
super(training1, training2);
}
@Override
public void train() {
System.out.println("Swimmer Serena: ");
training1.train();
training2.train();
}
}
WorkOut Class
//this is a concrete implementor
public class WorkOut implements Training{
@Override
public void train() {
System.out.println("Worked out");
}
}
Recover Class
//this is another concrete implementor
public class Recover implements Training{
@Override
public void train() {
System.out.println("Taking a rest to recover");
}
}
The Client Class
public class Client {
//these are League of Legend Character names
public static void main(String [] args) {
Champion ashe = new ADC("Ashe");
Champion jhin = new ADC("Jhin");
Champion yuumi = new Support("Yuumi");
Champion leona = new Support("Leona");
Category ADCs = new Category();
ADCs.addChamp(ashe);
ADCs.addChamp(jhin);
Category Supports = new Category();
Supports.addChamp(yuumi);
Supports.addChamp(leona);
Category BotLanePairs = new Category();
BotLanePairs.addChamp(ADCs);
BotLanePairs.addChamp(Supports);
BotLanePairs.showChamp();
}
}
The Champion Interface
public interface Champion {
abstract public void showChamp();
}
Categories Class
import java.util.ArrayList;
//this is a composite
public class Category implements Champion {
private ArrayListlist = new ArrayList();
@Override
public void showChamp() {
for(Champion c : list) {
c.showChamp();
}
}
public void addChamp(Champion c) {
list.add(c);
}
public void removeChamp(Champion c) {
list.remove(c);
}
}
Concrete Implementation of the interface
//this is a leaf
public class ADC implements Champion{
public String name;
public ADC(String n) {
this.name = n;
}
@Override
public void showChamp() {
System.out.println(name);
}
}
Another Concrete/Leaf Class
//this is another leaf
public class Support implements Champion{
public String name;
public Support(String n) {
this.name = n;
}
@Override
public void showChamp() {
System.out.println(name);
}
}
Creates a substitute/wrapper that steps in between the client and the subject they want to access
The Client CLass
public class Client {
//an internet proxy as example
public static void main(String [] args) {
Proxy proxy = new Proxy();
try {
proxy.connect("google.com");
proxy.connect("random.com");
}catch(Exception e) {
System.out.println(e.getMessage());
}
}
}
The Internet Interface
public interface Internet {
abstract public void connect(String domain)throws Exception;
}
The Proxy Class
import java.util.ArrayList;
public class Proxy implements Internet{
private static ArrayList bannedSites = new ArrayList();
private Internet internet = new RealInternet();
static{
bannedSites.add("random.com");
bannedSites.add("shabi.com");
}
@Override
public void connect(String domain) throws Exception{
if(bannedSites.contains(domain)) {
throw new Exception("Access Denied");
}
internet.connect(domain);
}
}
Actually connects to the site
public class RealInternet implements Internet{
public void connect(String domain) {
System.out.println("Connecting to : "+domain);
}
}
Client Class
public class Client {
public static void main(String [] args) {
Handler h1 = new USDHandler(), h2 = new CADHandler(), h3 = new EURHandler();
h1.setSuccessor(h2);
h2.setSuccessor(h3);
Currency [] currencies = {new Currency("CAD"), new Currency( "USD"), new Currency( "CNY"), new Currency( "JPY"), new Currency("EUR"), new Currency( "USD")};
for(Currency s : currencies) h1.handle(s);
}
}
Handler Interface
public interface Handler {
public abstract void setSuccessor(Handler h);
abstract public void handle(Currency money);
}
The Currency Class
public class Currency {
String type;
public Currency(String type) {
this.type = type;
}
public String getType() {
return type;
}
}
Concrete Handler 1
public class CADHandler implements Handler{
private Handler h;
@Override
public void setSuccessor(Handler h) {
// TODO Auto-generated method stub
this.h = h;
}
@Override
public void handle(Currency money) {
// TODO Auto-generated method stub
if(money.getType().contentEquals("CAD")) {
System.out.println("Handled");
return;
}
h.handle(money);
}
}
Concrete Handler 2
public class EURHandler implements Handler { private Handler h; @Override public void setSuccessor(Handler h) { // TODO Auto-generated method stub this.h = h; } @Override public void handle(Currency money) { // TODO Auto-generated method stub if(money.getType().contentEquals("EUR")) { System.out.println("Handled"); return; } System.out.println("Enable to handle request"); } }
Concrete Handler 3
public class USDHandler implements Handler{ private Handler h; @Override public void setSuccessor(Handler h) { this.h = h; } @Override public void handle(Currency money) { if(money.getType().contentEquals("USD")) { System.out.println("Handled"); return; } h.handle(money); } }
Defines a general structure of an algorithm with the ability to change the logic in specific embodiments or cases
Client Class
import java.util.Random;
public class Client {
public static void main(String [] args) {
Random r = new Random();
SoftwareDeveloper John = new JuniorDeveloper(r.nextInt()*500, "Junior Front End Dev");
SoftwareDeveloper Joe = new SeniorDeveloper(r.nextInt()*500, "Senior Front End Dev");
John.work();
John.interview();
John.getPaid();
Joe.work();
Joe.interview();
Joe.getPaid();
}
}
Template Class (A template for developers)
public class SoftwareDeveloper {
int employeeID;
String jobTitle;
int pay = 50000;
public SoftwareDeveloper(int id, String jt) {
this.employeeID = id;
this.jobTitle = jt;
}
public void work() {
System.out.println("Software Developer is coding....");
}
public void interview() {
System.out.println(jobTitle+" is interviewing potential new hires");
}
public void getPaid() {
System.out.println(jobTitle+" is getting paid "+pay);
}
}
Junior Developer
public class JuniorDeveloper extends SoftwareDeveloper{
public JuniorDeveloper(int id, String jt) {
super(id, jt);
}
public void interview() {
System.out.println("Junior Developer is not allowed to interview other people");
}
}
Senior Developer
public class SeniorDeveloper extends SoftwareDeveloper{
public SeniorDeveloper(int id, String jt) {
super(id, jt);
}
public void getPaid() {
System.out.println("Senior Developers get paid: $"+120000);
}
}
A one to many dependencies; when one object changes state, all of its dependencies are notified and changed automatically
Client Class
public class Client {
public static void main(String [] args) {
UnemployedCSGraduates csg = new UnemployedCSGraduates();
HeadHunter joe = new HeadHunter();
Recruiter facebook = new Recruiter();
Recruiter google = new Recruiter();
csg.registerObserver(joe);
csg.registerObserver(facebook);
csg.registerObserver(google);
csg.notifyObserver();
csg.unregisterObserver(google);
csg.notifyObserver();
}
}
The Employer Interface
//an entirely new interface to promote low coupling between subject and observer
public interface Employer {
abstract public void getNotification(String grad);
}
An Implementation of Observer
//this is an observer
public class HeadHunter implements Employer {
@Override
public void getNotification(String s) {
System.out.println("Headhunter notified about the availablity of : "+s);
}
}
Another Observer
//this is another concrete observer
public class Recruiter implements Employer {
@Override
public void getNotification(String grad) {
System.out.println("Recruiter notified about the availability of "+grad);
}
}
The Object to be observed on
import java.util.ArrayList; import java.util.Observer; // this is the subject of the application public class UnemployedCSGraduates { ArrayListlistOfGrads = new ArrayList (); //a list of all new Grads ArrayList observerCollection = new ArrayList (); // the collection of all observers, i.e. employers looking for new cs grads in this context public UnemployedCSGraduates() { listOfGrads.add(new NewGrad("Carter", 50)); listOfGrads.add(new NewGrad("Bob", 55)); listOfGrads.add(new NewGrad("Lin", 90)); // and so on } public void registerObserver(Employer ob) { observerCollection.add(ob); } public void unregisterObserver(Employer ob) { observerCollection.remove(ob); } public void notifyObserver() { for(Employer ob : observerCollection) { for(NewGrad n : listOfGrads) { ob.getNotification(n.getName()); } } } class NewGrad{ String name; int mark; public NewGrad(String n, int i) { this.name = n; this.mark = i; } public String getName() { return name; } } }
Client Class
public class Client {
public static void main(String [] args) {
Context context = new Context();
context.alert();
context.setAlert(new PresidentialAlert());
context.alert();
}
}
Alert Interface
public interface GovAlertState {
abstract public void alert();
}
Context Class
// Context: part of the state object, connected through weak aggregation
public class Context {
public GovAlertState alert;
public Context() {
alert = new AmberAlert();
}
public void setAlert(GovAlertState newAlert) {
this.alert = newAlert;
}
//alerts are accessed through the context i.e. handled through the context
public void alert() {
this.alert.alert();
}
}
A Concrete State
//concrete implementation of the state
public class AmberAlert implements GovAlertState{
@Override
public void alert() {
System.out.println("Sending out Amber Alert on Child Abduction");
}
}
Another Concrete State
//concrete implementation of the state public class PresidentialAlert implements GovAlertState { @Override public void alert() { System.out.println("Sending out Presidential Alert"); } }
Client program and a family of algorithms can be called independently; the family of algorithms share a common interface
The Client (main) Class
public class PokemonGame {
public static void main(String [] args) {
SuperMove thunderbolt = new ThunderBolt();
SuperSupportMove taunt = new Taunt();
Pokemon pikachu = new Pikachu(thunderbolt, taunt);
pikachu.defaultMove();
pikachu.defaultSupportMove();
pikachu.superMove();
pikachu.superSupportMove();
pikachu.setSuperMove(new FireBlast());
pikachu.setSuperSupportMove(new SwordDance());
pikachu.superMove();
pikachu.superSupportMove();
}
}
The Pokemon Class
//using pokemon to demonstrate strategy design pattern
// every pokemon has default 2 moves and as they level up, they learn moves 3 and 4, which are interchangeable
public class Pokemon {
SuperMove supermove;
SuperSupportMove supersupportmove;
public Pokemon(SuperMove sm, SuperSupportMove ssm) {
supermove = sm;
supersupportmove = ssm;
}
public void defaultMove() {
System.out.println("Used quick attack");
}
public void defaultSupportMove() {
System.out.println("Used tail whip!");
}
public void superMove() {
supermove.useMove();
}
public void superSupportMove() {
supersupportmove.useMove();
}
public void setSuperMove(SuperMove sm) {
this.supermove = sm;
}
public void setSuperSupportMove(SuperSupportMove ssm) {
this.supersupportmove = ssm;
}
}
A SuperMove Interface (A strategy)
public interface SuperMove {
public void useMove();
}
A SuperSupportMove Interface (Another Strategy)
public interface SuperSupportMove {
public void useMove();
}
Pikachu (An implementation of Pokemon)
public class Pikachu extends Pokemon{ public Pikachu(SuperMove sm, SuperSupportMove ssm) { super(sm, ssm); whichPoke(); } public void whichPoke() { System.out.println("Pikachu: "); } }
A Concrete Strategy
public class FireBlast implements SuperMove { @Override public void useMove() { System.out.println("Used Fire Blast!"); } }
Another Concrete Strategy
public class ThunderBolt implements SuperMove { @Override public void useMove() { System.out.println("Used Thunderbolt!"); } }
Another Concrete Strategy
public class Taunt implements SuperSupportMove { @Override public void useMove() { System.out.println("Used Taunt!"); } }
Last one...
public class SwordDance implements SuperSupportMove { @Override public void useMove() { System.out.println("Used Swords' Dance!"); } }
Centralize operations on an object structure to allow polymorphism and vary independently
Client Class
//our purpose is to calculate to cost of visiting all the shops
public class Client {
public static void main(String [] args) {
int cost = 0;
Shop [] luxuryBrandItems = new Shop [] {
new Chanel("Medium Quilted Boy Flap Bag", 5500), new Chanel("Small Quilted Boy Flap Bag", 4600), new LV("Monogram Canvas Speedy Bandouliere 40 Bag", 1490)
};
GirlFriend gf = new GirlFriend();
for(Shop s: luxuryBrandItems) {
cost += s.accept(gf);
}
System.out.println("Total cost of the trip is: $"+cost);
}
}
Visitor Interface
//this is the visitor interface
public interface Visitor {
public int visit(LV lv);
public int visit(Chanel chanel);
}
Concrete Visitor
//a concrete implementation of visitor
public class GirlFriend implements Visitor {
@Override
public int visit(LV lv) {
System.out.println("Purchased: "+lv.getItem()+" and it costed $"+lv.getPrice());
return lv.getPrice();
}
@Override
public int visit(Chanel chanel) {
System.out.println("Purchased: "+chanel.getBag()+" and it costed $"+chanel.getPrice());
return chanel.getPrice();
}
}
Shop Interface, to be visited
//this is the elements interface
public interface Shop {
public int accept(Visitor visitor);
}
Concrete Shop
//a concrete implementation of shop public class LV implements Shop{ private String item; private int price; public LV(String item, int price) { this.item = item; this.price = price; } public String getItem() { return item; } public int getPrice() { return price; } @Override public int accept(Visitor visitor) { return visitor.visit(this); } }
Another Concrete Shop
//a concrete implementation of shop public class Chanel implements Shop { private String bag; private int price; public Chanel(String itemName, int price) { this.bag = itemName; this.price = price; } public String getBag() { return bag; } public int getPrice() { return price; } @Override public int accept(Visitor visitor) { return visitor.visit(this); } }