Design Patterns#
1. Simple Factory Pattern#
Simple Factory Pattern: Static Factory Pattern
static: is a member variable and method of the class. It does not require creating an object and can be called by the class name; it is shared by all objects of the class.
Throw Exception // Custom exception, score management 1-100, anything outside 1-100 should catch an exception.
In Java, throws is placed in the method declaration, indicating that this method may throw an exception.
throw: throws an exception in the code.
If the attribute is not protected or private, the default access level is package-private, accessible within the same package.
private < package-private < protected < public. protected is used for inheritance, in the parent class.
The difference between default access and protected is between packages.
Subclasses can access the parent's protected (non-package subclasses).
The method in the interface is public abstract void fly()
1.1 Negative Code#
package simpleFactory.negative;
abstract class Weapon {
abstract void display();
}
class MachineGun extends Weapon {
@Override
void display() {
// TODO Auto-generated method stub
System.out.println("Machine Gun");
}
}
class Pistol extends Weapon {
@Override
void display() {
// TODO Auto-generated method stub
System.out.println("Pistol");
}
}
public class DemoN {
public static void main(String[] args) {
Weapon w1 = new MachineGun();
w1.display();
Weapon w2 = new Pistol();
w2.display();
}
/**
* The client needs to only carry the specific subclass name, increasing the difficulty for the user to program.
*/
}
1.2 Positive Code#
package simpleFactory.negative;
abstract class Weapon {
abstract void display();
}
class MachineGun extends Weapon {
@Override
void display() {
// TODO Auto-generated method stub
System.out.println("Machine Gun");
}
}
class Pistol extends Weapon {
@Override
void display() {
// TODO Auto-generated method stub
System.out.println("Pistol");
}
}
public class DemoN {
public static void main(String[] args) {
Weapon w1 = new MachineGun();
w1.display();
Weapon w2 = new Pistol();
w2.display();
}
/**
* The client needs to only carry the specific subclass name, increasing the difficulty for the user to program.
*/
}
2. Factory Method Pattern#
2.1 Negative Code#
package factory.negative;
abstract class Weapon {
abstract void display();
}
class MachineGun extends Weapon {
@Override
void display() {
// TODO Auto-generated method stub
System.out.println("Machine Gun");
}
}
class Pistol extends Weapon {
@Override
void display() {
// TODO Auto-generated method stub
System.out.println("Pistol");
}
}
class SniperRifle extends Weapon {
@Override
void display() {
// TODO Auto-generated method stub
System.out.println("Sniper Rifle!");
}
}
class WeaponFactory {
public static Weapon createWeapon(String type) {
Weapon w = null;
switch(type) {
case "Pistol":
w = new Pistol();
break;
case "Machine Gun":
w = new MachineGun();
break;
case "Sniper Rifle":
w = new SniperRifle();
break;
default:
System.out.println("Cannot produce this weapon: " + type);
}
return w;
}
}
public class DemoN {
public static void main(String[] args) {
Weapon pistol = WeaponFactory.createWeapon("Pistol");
pistol.display();
Weapon machineGun = WeaponFactory.createWeapon("Machine Gun");
machineGun.display();
Weapon sr = new SniperRifle();
sr.display();
}
}
2.2 Positive Code#
package factory.positive;
abstract class Weapon {
abstract void display();
}
class MachineGun extends Weapon {
@Override
void display() {
// TODO Auto-generated method stub
System.out.println("Machine Gun");
}
}
class Pistol extends Weapon {
@Override
void display() {
// TODO Auto-generated method stub
System.out.println("Pistol");
}
}
class SniperRifle extends Weapon {
@Override
void display() {
// TODO Auto-generated method stub
System.out.println("Sniper Rifle!");
}
}
interface WeaponFactory {
Weapon createWeapon();
}
class MachineGunFactory implements WeaponFactory {
@Override
public Weapon createWeapon() {
// TODO Auto-generated method stub
return new MachineGun();
}
}
class SniperRifleFactory implements WeaponFactory {
@Override
public Weapon createWeapon() {
// TODO Auto-generated method stub
return new SniperRifle();
}
}
class PistolFactory implements WeaponFactory {
@Override
public Weapon createWeapon() {
// TODO Auto-generated method stub
return new Pistol();
}
}
public class DemoP {
public static void main(String[] args) {
WeaponFactory wf1 = new MachineGunFactory();
Weapon w1 = wf1.createWeapon();
w1.display();
WeaponFactory wf2 = new PistolFactory();
Weapon w2 = wf2.createWeapon();
w2.display();
WeaponFactory wf3 = new SniperRifleFactory();
Weapon w3 = wf3.createWeapon();
w3.display();
}
}
3. Abstract Factory Pattern#
3.1 Negative Code#
package abstractFactory.negative;
abstract class Weapon {
abstract void display();
}
/**
* Using factory method pattern without using abstract factory pattern, modern factories need to add production lines - Bullet class
*
* @author ASUS
*
*/
abstract class Bullet {
abstract void display();
}
/**
* Bullet class
* @author ASUS
*
*/
class PistolBullet extends Bullet {
@Override
void display() {
// TODO Auto-generated method stub
System.out.println("Pistol Bullet");
}
}
class MachineGunBullet extends Bullet {
@Override
void display() {
// TODO Auto-generated method stub
System.out.println("Machine Gun Bullet");
}
}
// Bullet factory
interface BulletFactory {
Bullet createBullet();
}
class MachineGun extends Weapon {
@Override
void display() {
// TODO Auto-generated method stub
System.out.println("Machine Gun");
}
}
class Pistol extends Weapon {
@Override
void display() {
// TODO Auto-generated method stub
System.out.println("Pistol");
}
}
class SniperRifle extends Weapon {
@Override
void display() {
// TODO Auto-generated method stub
System.out.println("Sniper Rifle!");
}
}
interface WeaponFactory {
Weapon createWeapon();
}
class MachineGunFactory implements WeaponFactory {
@Override
public Weapon createWeapon() {
// TODO Auto-generated method stub
return new MachineGun();
}
}
class MachineGunBulletFactory implements BulletFactory {
@Override
public Bullet createBullet() {
// TODO Auto-generated method stub
return new MachineGunBullet();
}
}
class SniperRifleFactory implements WeaponFactory {
@Override
public Weapon createWeapon() {
// TODO Auto-generated method stub
return new SniperRifle();
}
}
class PistolFactory implements WeaponFactory {
@Override
public Weapon createWeapon() {
// TODO Auto-generated method stub
return new Pistol();
}
}
// Pistol bullet factory
class PistolBulletFactory implements BulletFactory {
@Override
public Bullet createBullet() {
// TODO Auto-generated method stub
return new PistolBullet();
}
}
public class DemoN {
public static void main(String[] args) {
WeaponFactory wf1 = new MachineGunFactory();
Weapon w1 = wf1.createWeapon();
w1.display();
WeaponFactory wf2 = new PistolFactory();
Weapon w2 = wf2.createWeapon();
w2.display();
WeaponFactory wf3 = new SniperRifleFactory();
Weapon w3 = wf3.createWeapon();
w3.display();
BulletFactory bf1 = new MachineGunBulletFactory();
Bullet b1 = bf1.createBullet();
b1.display();
}
}
3.2 Positive Code#
package abstractFactory.positive;
abstract class Weapon {
abstract void display();
}
/**
* Using factory method pattern without using abstract factory pattern, modern factories need to add production lines - Bullet class
*
* @author ASUS
*
*/
abstract class Bullet {
abstract void display();
}
/**
* Bullet class
* @author ASUS
*
*/
class PistolBullet extends Bullet {
@Override
void display() {
// TODO Auto-generated method stub
System.out.println("Pistol Bullet");
}
}
class MachineGunBullet extends Bullet {
@Override
void display() {
// TODO Auto-generated method stub
System.out.println("Machine Gun Bullet");
}
}
// Abstract factory
interface ArsenalFactory {
Bullet createBullet();
Weapon createWeapon();
}
class MachineGun extends Weapon {
@Override
void display() {
// TODO Auto-generated method stub
System.out.println("Machine Gun");
}
}
class MachineGunFactory implements ArsenalFactory {
@Override
public Bullet createBullet() {
// TODO Auto-generated method stub
return new MachineGunBullet();
}
@Override
public Weapon createWeapon() {
// TODO Auto-generated method stub
return new MachineGun();
}
}
class PistolFactory implements ArsenalFactory {
@Override
public Bullet createBullet() {
// TODO Auto-generated method stub
return new PistolBullet();
}
@Override
public Weapon createWeapon() {
// TODO Auto-generated method stub
return new Pistol();
}
}
class Pistol extends Weapon {
@Override
void display() {
// TODO Auto-generated method stub
System.out.println("Pistol");
}
}
public class DemoP {
public static void main(String[] args) {
ArsenalFactory af1 = new MachineGunFactory();
Weapon w1 = af1.createWeapon();
Bullet b1 = af1.createBullet();
w1.display();
b1.display();
}
}
4. Builder Pattern#
4.1 Negative Code#
package builder.negative;
class LoggerQiang {
private String eye;
private String ear;
private String mouth;
public String getEye() {
return eye;
}
public void setEye(String eye) {
this.eye = eye;
}
public String getEar() {
return ear;
}
public void setEar(String ear) {
this.ear = ear;
}
public String getMouth() {
return mouth;
}
public void setMouth(String mouth) {
this.mouth = mouth;
}
@Override
public String toString() {
return "LoggerQiang [Eye=" + eye + ", Ear=" + ear + ", Mouth=" + mouth + "]";
}
}
public class DemoN_A {
public static void main(String[] args) {
System.out.println("——————Happy LoggerQiang————");
LoggerQiang qiang = new LoggerQiang();
qiang.setEar("Ears up");
qiang.setEye("Eyes wide open");
qiang.setMouth("Mouth corners up");
System.out.println(qiang);
}
/**
* The client directly assembles LoggerQiang.
*/
}
package builder.negative;
class LoggerQiang {
private String eye;
private String ear;
private String mouth;
public String getEye() {
return eye;
}
public void setEye(String eye) {
this.eye = eye;
}
public String getEar() {
return ear;
}
public void setEar(String ear) {
this.ear = ear;
}
public String getMouth() {
return mouth;
}
public void setMouth(String mouth) {
this.mouth = mouth;
}
@Override
public String toString() {
return "LoggerQiang [Eye=" + eye + ", Ear=" + ear + ", Mouth=" + mouth + "]";
}
}
// Happy LoggerQiang
class HappyQiang {
private LoggerQiang qiang = new LoggerQiang();
public LoggerQiang build() {
this.qiang.setEar("Ears up");
this.qiang.setEye("Eyes wide open");
this.qiang.setMouth("Mouth corners up");
return this.qiang;
}
}
class DisappointedQiang {
private LoggerQiang qiang = new LoggerQiang();
public LoggerQiang build() {
this.qiang.setEar("Ears down");
this.qiang.setEye("Eyes drooping");
this.qiang.setMouth("Mouth corners down");
return this.qiang;
}
}
public class DemoN_B {
public static void main(String[] args) {
System.out.println("Happy LoggerQiang");
HappyQiang qiang = new HappyQiang();
LoggerQiang hq = qiang.build();
System.out.println(hq);
System.out.println("Disappointed LoggerQiang");
DisappointedQiang qiang2 = new DisappointedQiang();
LoggerQiang dq = qiang2.build();
System.out.println(dq);
}
}
4.2 Positive Code#
package builder.positive;
class LoggerQiang {
private String eye;
private String ear;
private String mouth;
public String getEye() {
return eye;
}
public void setEye(String eye) {
this.eye = eye;
}
public String getEar() {
return ear;
}
public void setEar(String ear) {
this.ear = ear;
}
public String getMouth() {
return mouth;
}
public void setMouth(String mouth) {
this.mouth = mouth;
}
@Override
public String toString() {
return "LoggerQiang [Eye=" + eye + ", Ear=" + ear + ", Mouth=" + mouth + "]";
}
}
interface Builder {
void setEye();
void setEar();
void setMouth();
LoggerQiang getResult();
}
class HappyQiangBuilder implements Builder {
private LoggerQiang lq = new LoggerQiang();
@Override
public void setEye() {
// TODO Auto-generated method stub
this.lq.setEye("Eyes wide open");
}
@Override
public void setEar() {
// TODO Auto-generated method stub
this.lq.setEar("Ears up");
}
@Override
public void setMouth() {
// TODO Auto-generated method stub
this.lq.setMouth("Mouth corners up");
}
@Override
public LoggerQiang getResult() {
// TODO Auto-generated method stub
return this.lq;
}
}
class DisappointedQiangBuilder implements Builder {
private LoggerQiang lq = new LoggerQiang();
@Override
public void setEye() {
// TODO Auto-generated method stub
this.lq.setEye("Eyes drooping");
}
@Override
public void setEar() {
// TODO Auto-generated method stub
this.lq.setEar("Ears down");
}
@Override
public void setMouth() {
// TODO Auto-generated method stub
this.lq.setMouth("Mouth corners down");
}
@Override
public LoggerQiang getResult() {
// TODO Auto-generated method stub
return this.lq;
}
}
class Director {
private Builder builder;
public Director(Builder builder) {
super();
this.builder = builder;
}
public LoggerQiang build() {
this.builder.setEar();
this.builder.setEye();
this.builder.setMouth();
return this.builder.getResult();
}
}
public class DemoP {
public static void main(String[] args) {
System.out.println("Happy LoggerQiang");
Builder hqb = new HappyQiangBuilder();
LoggerQiang lq1 = new Director(hqb).build();
System.out.println(lq1);
System.out.println("Disappointed LoggerQiang");
Builder dbq = new DisappointedQiangBuilder();
LoggerQiang lq2 = new Director(dbq).build();
System.out.println(lq2);
}
}
5. Prototype Pattern#
5.1 Negative Code#
package prototype.negative;
class Weather {
private String city;
private String date;
private String weatherPhenomenon;
private String airQuality;
private String wind;
public Weather(String city, String date, String weatherPhenomenon, String airQuality, String wind) {
super();
this.city = city;
this.date = date;
this.weatherPhenomenon = weatherPhenomenon;
this.airQuality = airQuality;
this.wind = wind;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public String getWeatherPhenomenon() {
return weatherPhenomenon;
}
public void setWeatherPhenomenon(String weatherPhenomenon) {
this.weatherPhenomenon = weatherPhenomenon;
}
public String getAirQuality() {
return airQuality;
}
public void setAirQuality(String airQuality) {
this.airQuality = airQuality;
}
public String getWind() {
return wind;
}
public void setWind(String wind) {
this.wind = wind;
}
@Override
public String toString() {
return "Weather [City=" + city + ", Date=" + date + ", Weather Phenomenon=" + weatherPhenomenon + ", Air Quality="
+ airQuality + ", Wind=" + wind + "]";
}
}
public class DemoN {
public static void main(String[] args) {
Weather today = new Weather("Zhangjiajie", "October 24, 2021", "Light Rain", "Good", "Northeast Wind Light Breeze");
System.out.println(today);
System.out.println("The next day only the date and weather phenomenon change, no other elements need to change");
Weather tomorrow = new Weather("Zhangjiajie", "October 25, 2021", "Cloudy", "Good", "Northeast Wind Light Breeze");
System.out.println(tomorrow);
}
}
5.2.1 Positive Code — A#
package prototype.positive.a;
class WeatherDate {
private String year;
private String month;
private String day;
public WeatherDate(String year, String month, String day) {
super();
this.year = year;
this.month = month;
this.day = day;
}
public String getYear() {
return year;
}
public void setYear(String year) {
this.year = year;
}
public String getMonth() {
return month;
}
public void setMonth(String month) {
this.month = month;
}
public String getDay() {
return day;
}
public void setDay(String day) {
this.day = day;
}
@Override
public String toString() {
return "WeatherDate [Year=" + year + ", Month=" + month + ", Day=" + day + "]";
}
}
class Weather implements Cloneable {
private String city;
private WeatherDate date;
private String weatherPhenomenon;
private String airQuality;
private String wind;
public Weather(String city, WeatherDate date, String weatherPhenomenon, String airQuality, String wind) {
super();
this.city = city;
this.date = date;
this.weatherPhenomenon = weatherPhenomenon;
this.airQuality = airQuality;
this.wind = wind;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public WeatherDate getDate() {
return date;
}
public void setDate(WeatherDate date) {
this.date = date;
}
public String getWeatherPhenomenon() {
return weatherPhenomenon;
}
public void setWeatherPhenomenon(String weatherPhenomenon) {
this.weatherPhenomenon = weatherPhenomenon;
}
public String getAirQuality() {
return airQuality;
}
public void setAirQuality(String airQuality) {
this.airQuality = airQuality;
}
public String getWind() {
return wind;
}
public void setWind(String wind) {
this.wind = wind;
}
@Override
public String toString() {
return "Weather [City=" + city + ", Date=" + date + ", Weather Phenomenon=" + weatherPhenomenon + ", Air Quality="
+ airQuality + ", Wind=" + wind + "]";
}
@Override
protected Object clone() throws CloneNotSupportedException {
// TODO Auto-generated method stub
Object obj = null;
obj = super.clone();
return obj;
}
}
public class DemoP {
public static void main(String[] args) throws CloneNotSupportedException {
Weather today = new Weather("Zhangjiajie", new WeatherDate("2021", "10", "24"), "Light Rain", "Good", "Northeast Wind Light Breeze");
System.out.println(today);
System.out.println("The next day only the date and weather phenomenon change, no other elements need to change");
Weather tomorrow = (Weather) today.clone();
tomorrow.getDate().setDay("25");
tomorrow.setWeatherPhenomenon("Cloudy");
System.out.println(tomorrow);
System.out.println("Output today again\n" + today); // Shallow clone today and the previous today is different
}
}
5.2.2 Positive Code — B#
package prototype.positive.b;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
interface WeatherPrototype {
Object cloneMe() throws Exception;
}
class Weather implements WeatherPrototype, Serializable {
private String city;
private String date;
private String weatherPhenomenon;
private String airQuality;
private String wind;
public Weather(String city, String date, String weatherPhenomenon, String airQuality, String wind) {
super();
this.city = city;
this.date = date;
this.weatherPhenomenon = weatherPhenomenon;
this.airQuality = airQuality;
this.wind = wind;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public String getWeatherPhenomenon() {
return weatherPhenomenon;
}
public void setWeatherPhenomenon(String weatherPhenomenon) {
this.weatherPhenomenon = weatherPhenomenon;
}
public String getAirQuality() {
return airQuality;
}
public void setAirQuality(String airQuality) {
this.airQuality = airQuality;
}
public String getWind() {
return wind;
}
public void setWind(String wind) {
this.wind = wind;
}
@Override
public String toString() {
return "Weather [City=" + city + ", Date=" + date + ", Weather Phenomenon=" + weatherPhenomenon + ", Air Quality="
+ airQuality + ", Wind=" + wind + "]";
}
@Override
public Object cloneMe() throws Exception {
// TODO Auto-generated method stub
Object obj = null;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(this);
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
obj = ois.readObject();
return obj;
}
}
public class DemoP {
public static void main(String[] args) throws Exception {
Weather today = new Weather("Zhangjiajie", "October 24, 2021", "Light Rain", "Good", "Northeast Wind Light Breeze");
System.out.println(today);
System.out.println("The next day only the date and weather phenomenon change, no other elements need to change");
Weather tomorrow = (Weather) today.cloneMe();
tomorrow.setDate("October 25, 2021");
tomorrow.setWeatherPhenomenon("Cloudy");
System.out.println(tomorrow);
}
}
5.2.3 Positive Code — C#
package prototype.positive.c;
class WeatherDate implements Cloneable {
private String year;
private String month;
private String day;
public WeatherDate(String year, String month, String day) {
super();
this.year = year;
this.month = month;
this.day = day;
}
public String getYear() {
return year;
}
public void setYear(String year) {
this.year = year;
}
public String getMonth() {
return month;
}
public void setMonth(String month) {
this.month = month;
}
public String getDay() {
return day;
}
public void setDay(String day) {
this.day = day;
}
@Override
public String toString() {
return "WeatherDate [Year=" + year + ", Month=" + month + ", Day=" + day + "]";
}
@Override
protected Object clone() throws CloneNotSupportedException {
// TODO Auto-generated method stub
return super.clone();
}
}
class Weather implements Cloneable {
private String city;
private WeatherDate date;
private String weatherPhenomenon;
private String airQuality;
private String wind;
public Weather(String city, WeatherDate date, String weatherPhenomenon, String airQuality, String wind) {
super();
this.city = city;
this.date = date;
this.weatherPhenomenon = weatherPhenomenon;
this.airQuality = airQuality;
this.wind = wind;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public WeatherDate getDate() {
return date;
}
public void setDate(WeatherDate date) {
this.date = date;
}
public String getWeatherPhenomenon() {
return weatherPhenomenon;
}
public void setWeatherPhenomenon(String weatherPhenomenon) {
this.weatherPhenomenon = weatherPhenomenon;
}
public String getAirQuality() {
return airQuality;
}
public void setAirQuality(String airQuality) {
this.airQuality = airQuality;
}
public String getWind() {
return wind;
}
public void setWind(String wind) {
this.wind = wind;
}
@Override
public String toString() {
return "Weather [City=" + city + ", Date=" + date + ", Weather Phenomenon=" + weatherPhenomenon + ", Air Quality="
+ airQuality + ", Wind=" + wind + "]";
}
@Override
protected Object clone() throws CloneNotSupportedException {
// TODO Auto-generated method stub
Object obj = null;
obj = super.clone();
this.date = (WeatherDate) this.date.clone();
return obj;
}
}
public class DemoP { // Deep clone
public static void main(String[] args) throws CloneNotSupportedException {
Weather today = new Weather("Zhangjiajie", new WeatherDate("2021", "10", "24"), "Light Rain", "Good", "Northeast Wind Light Breeze");
System.out.println(today);
System.out.println("The next day only the date and weather phenomenon change, no other elements need to change");
Weather tomorrow = (Weather) today.clone();
tomorrow.getDate().setDay("25");
tomorrow.setWeatherPhenomenon("Cloudy");
System.out.println(tomorrow);
System.out.println("Output today again\n" + today);
}
}
6. Singleton Pattern#
6.1 Negative Code#
package singleton.negative;
class Moon {
private double radius = 1738.14;
private String state; // Shape
public Moon(String state) {
super();
this.state = state;
}
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
@Override
public String toString() {
return "Moon [Radius=" + radius + ", Shape=" + state + "]";
}
}
class Bear {
private String name;
public Bear(String name) {
super();
this.name = name;
}
public void look(Moon moon) {
System.out.println(this.name + " sees the moonstone: " + moon);
}
}
public class DemoN {
public static void main(String[] args) {
Moon m1 = new Moon("Full Moon");
Moon m2 = new Moon("Half Moon");
Bear big = new Bear("Bear Big");
Bear little = new Bear("Bear Little");
big.look(m1);
little.look(m2);
// There can only be one moon in the sky, which contradicts the facts
}
}
6.2 Positive Code#
package singleton.positive.A;
/**
* Eager Singleton Pattern
* (1) No need to consider the issue of multiple threads accessing at the same time
* (2) Call speed and response time are better than lazy singleton pattern
* (3) Resource utilization is not as good as lazy singleton, system loading time is relatively long
*
* @author ASUS
*
*/
class Moon {
private final double radius = 1738.14;
private String state; // Shape
// (1) Static private member
private static final Moon instance = new Moon();
// Private constructor, cannot create new objects from outside
private Moon() {
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
// Public factory method, or unique object
public static Moon getInstance() {
return instance;
}
@Override
public String toString() {
return "Moon [Radius=" + radius + ", Shape=" + state + "]";
}
}
class Bear {
private String name;
public Bear(String name) {
super();
this.name = name;
}
public void look(Moon moon) {
System.out.println(this.name + " sees the moon: " + moon);
}
}
public class DemoP_1 {
public static void main(String[] args) {
// Moon m1 = new Moon(""); cannot create a new object because the constructor is private
Moon m1 = Moon.getInstance();
Moon m2 = Moon.getInstance();
m1.setState("Full Moon");
m2.setState("Half Moon");
Bear big = new Bear("Bear Big");
Bear little = new Bear("Bear Little");
big.look(m1);
little.look(m2);
System.out.println(m1.hashCode());
System.out.println(m2.hashCode());
}
}
package singleton.positive.B;
/**
* Lazy Singleton Pattern
* (1) Implements delayed loading // loads when needed
* (2) Must handle multiple threads accessing resources at the same time
* (3) Must control through mechanisms such as double-checked locking, which will affect system performance
*
* @author ASUS
*
*/
class Moon {
private final double radius = 1738.14;
private String state; // Shape
// (1) Static private member
private static Moon instance = null; // Not a constant, no need for final
// Private constructor, cannot create new objects from outside
private Moon() {
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
// Public factory method, or unique object
public static synchronized Moon getInstance() {
if (instance == null)
instance = new Moon();
return instance;
}
@Override
public String toString() {
return "Moon [Radius=" + radius + ", Shape=" + state + "]";
}
}
class Bear {
private String name;
public Bear(String name) {
super();
this.name = name;
}
public void look(Moon moon) {
System.out.println(this.name + " sees the moon: " + moon);
}
}
public class DemoP_2 {
public static void main(String[] args) {
// Moon m1 = new Moon(""); cannot create a new object because the constructor is private
Moon m1 = Moon.getInstance();
Moon m2 = Moon.getInstance();
m1.setState("Full Moon");
m2.setState("Half Moon");
Bear big = new Bear("Bear Big");
Bear little = new Bear("Bear Little");
big.look(m1);
little.look(m2);
System.out.println(m1.hashCode());
System.out.println(m2.hashCode());
}
}
package singleton.positive.C;
/**
* Static Inner Class Singleton Pattern
* (1) Thread-safe, no delayed loading, efficiency and eager style are the same, has the advantages of both lazy and eager styles
*
* @author ASUS
*
*/
class Moon {
private final double radius = 1738.14;
private String state; // Shape
// (1) Static inner class
private static class MoonInstance {
private static Moon instance = new Moon();
}
// Private constructor, cannot create new objects from outside
private Moon() {
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
// Public factory method, or unique object
public static Moon getInstance() {
return MoonInstance.instance;
}
@Override
public String toString() {
return "Moon [Radius=" + radius + ", Shape=" + state + "]";
}
}
class Bear {
private String name;
public Bear(String name) {
super();
this.name = name;
}
public void look(Moon moon) {
System.out.println(this.name + " sees the moon: " + moon);
}
}
public class DemoP_3 {
public static void main(String[] args) {
// Moon m1 = new Moon(""); cannot create a new object because the constructor is private
Moon m1 = Moon.getInstance();
Moon m2 = Moon.getInstance();
m1.setState("Full Moon");
// m2.setState("Half Moon");
Bear big = new Bear("Bear Big");
Bear little = new Bear("Bear Little");
big.look(m1);
little.look(m2);
System.out.println(m1.hashCode());
System.out.println(m2.hashCode());
}
}
7. Template Method Pattern#
7.1 Negative Code#
package templateMethod.negative;
class LoggerQiang {
public void workOn() { // Plot 1
System.out.println("LoggerQiang is preparing to chop trees!");
System.out.println("LoggerQiang has set off");
System.out.println("LoggerQiang uses a chainsaw to chop trees!");
System.out.println("LoggerQiang drives to transport wood");
System.out.println("LoggerQiang does not need to sell wood!");
System.out.println("LoggerQiang has lunch");
}
}
class LoggerQiang2 {
public void workOn() { // Plot 1
System.out.println("LoggerQiang is preparing to chop trees!");
System.out.println("LoggerQiang has set off");
System.out.println("LoggerQiang uses an axe to chop trees!");
System.out.println("LoggerQiang uses a tricycle to transport wood");
System.out.println("LoggerQiang sells wood!");
System.out.println("LoggerQiang has lunch");
}
}
public class DemoN {
public static void main(String[] args) {
new LoggerQiang().workOn();
System.out.println("Plot 2");
new LoggerQiang2().workOn();
}
/**
* Disadvantages
* (1) The logging process system, but uses different specific methods
* (2) Violates the Open/Closed Principle
* (3) Violates the Dependency Inversion Principle
*/
}
7.2 Positive Code#
package templateMethod.positive;
abstract class LoggerTemplate {
protected void ready() {
System.out.println("LoggerQiang is preparing...");
}
protected void setout() {
System.out.println("LoggerQiang has set off...");
}
protected void sellToother() {
System.out.println("LoggerQiang sells wood by himself...");
}
protected void sellToli() {
System.out.println("LoggerQiang sells wood to Boss Li...");
}
protected boolean isSell() {
return true;
}
public void eat() {
System.out.println("LoggerQiang has lunch...");
}
protected abstract void cutTree();
protected abstract void transport();
// Template method
public final void workOn() {
this.ready();
this.setout();
this.cutTree();
this.transport();
if (isSell()) // If true, LoggerQiang sells wood by himself
this.sellToother();
else
this.sellToli();
this.eat();
}
}
class LoggerQiang extends LoggerTemplate {
@Override
protected void cutTree() {
// TODO Auto-generated method stub
System.out.println("Chopping trees with a chainsaw");
}
@Override
protected void transport() {
// TODO Auto-generated method stub
System.out.println("Transporting wood with a truck");
}
}
class LoggerQiang1 extends LoggerTemplate {
@Override
protected void cutTree() {
// TODO Auto-generated method stub
System.out.println("Chopping trees with an axe...");
}
@Override
protected void transport() {
// TODO Auto-generated method stub
System.out.println("Transporting wood with a tricycle...");
}
public boolean isSell() {
return false;
}
}
public class DemoP {
public static void main(String[] args) {
System.out.println("Plot 1————————");
LoggerTemplate a = new LoggerQiang();
a.workOn();
System.out.println("Plot 2————————");
LoggerTemplate b = new LoggerQiang1();
b.workOn();
} // Complies with the Open/Closed Principle
}
8. Mediator Pattern#
8.1 Negative Code#
package mediator.negative;
class BankAccount {
private double money;
public BankAccount(double money) {
super();
this.money = money;
}
public double getMoney() {
return money;
}
public void setMoney(double money) {
this.money = money;
}
public void deposit(double money) {
this.money += money;
}
public void withdraw(double money) {
this.money -= money;
}
}
class Sale {
private int number = 5;
private double price = 111;
private BankAccount bank = new BankAccount(100);
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public BankAccount getBank() {
return bank;
}
public void setBank(BankAccount bank) {
this.bank = bank;
}
public void sellHouse(int saleNumber) { // Sell house
Purchase purchase = new Purchase(); // Buyer
purchase.buyHouse(saleNumber);
double money = saleNumber * price; // Sale amount
this.bank.deposit(money); // Seller deposits
this.number = this.number - saleNumber; // Decrease house quantity
}
@Override
public String toString() {
return "Sale [Quantity=" + number + ", Unit Price=" + price + ", Account=" + bank.getMoney() + "]";
}
}
class Purchase {
private int number;
private BankAccount bank = new BankAccount(2000);
public void buyHouse(int buyNumber) {
this.number += buyNumber;
Sale sale = new Sale();
sale.setNumber(sale.getNumber() - buyNumber);
double money = sale.getPrice() * buyNumber;
this.bank.withdraw(money);
}
@Override
public String toString() {
return "Purchase [Quantity=" + number + ", Account=" + bank.getMoney() + "]";
}
}
public class DemoN {
public static void main(String[] args) {
Sale sale = new Sale();
Purchase pur = new Purchase();
System.out.println("___Status before transaction——————");
System.out.println("Seller " + sale);
System.out.println("Buyer " + pur);
sale.sellHouse(2);
pur.buyHouse(2);
System.out.println("Status after transaction");
System.out.println("Seller " + sale);
System.out.println("Buyer " + pur);
}
}
8.2 Positive Code#
package mediator.positive;
abstract class AbstractMediator {
protected Sale sale;
protected Purchase purchase;
public AbstractMediator() {
super();
this.sale = new Sale(this);
this.purchase = new Purchase(this);
}
public void register(AbstractColleague coll) {
String name = coll.getClass().getSimpleName();
if (name.equalsIgnoreCase("Sale"))
this.sale = (Sale) coll;
else if (name.equalsIgnoreCase("Purchase"))
this.purchase = (Purchase) coll;
}
abstract void sellHouse(int number);
abstract void buyHouse(int number);
}
class Mediator extends AbstractMediator {
public Mediator() {
}
@Override
void sellHouse(int number) {
// TODO Auto-generated method stub
this.sale.setNumber(this.sale.getNumber() - number);
double money = this.sale.getPrice() * number;
this.sale.getBank().deposit(money);
}
@Override
void buyHouse(int number) {
// TODO Auto-generated method stub
this.purchase.setNumber(this.purchase.getNumber() + number);
double money = this.sale.getPrice() * number;
this.purchase.getBank().withdraw(money);
}
}
abstract class AbstractColleague {
protected AbstractMediator mediator;
public AbstractColleague() {
super();
}
public AbstractColleague(AbstractMediator mediator) {
super();
this.mediator = mediator;
}
}
class Sale extends AbstractColleague {
private BankAccount bank;
private int number = 5;
private double price = 111;
public Sale() {
}
public Sale(AbstractMediator mediator) {
super(mediator);
this.bank = new BankAccount();
mediator.register(this);
}
public BankAccount getBank() {
return bank;
}
public void setBank(BankAccount bank) {
this.bank = bank;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public void sellHouse(int saleNumber) {
this.mediator.sellHouse(saleNumber);
}
@Override
public String toString() {
return "Sale [Bank Account=" + bank.getMoney() + ", Quantity=" + number + ", Unit Price=" + price + "]";
}
}
class Purchase extends AbstractColleague {
private int number;
private BankAccount bank;
public Purchase(AbstractMediator mediator) {
super(mediator);
this.bank = new BankAccount();
this.mediator.register(this);
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
public BankAccount getBank() {
return bank;
}
public void setBank(BankAccount bank) {
this.bank = bank;
}
public void buyHouse(int number) {
this.mediator.buyHouse(number);
}
@Override
public String toString() {
return "Purchase [Quantity=" + number + ", Account=" + bank.getMoney() + "]";
}
}
class BankAccount extends AbstractColleague {
private double money = 0;
public double getMoney() {
return money;
}
public void setMoney(double money) {
this.money = money;
}
public void deposit(double money) {
this.money = this.money + money;
}
public void withdraw(double money) {
this.money = this.money - money;
}
@Override
public String toString() {
return "BankAccount [money=" + money + "]";
}
}
public class Demo {
public static void main(String[] args) {
// TODO Auto-generated method stub
AbstractMediator mediator = new Mediator();
Sale sale = new Sale(mediator);
Purchase pur = new Purchase(mediator);
pur.getBank().deposit(99999);
System.out.println("___Status before transaction——————");
System.out.println("Seller " + sale);
System.out.println("Buyer " + pur);
sale.sellHouse(2);
pur.buyHouse(2);
System.out.println("Status after transaction");
System.out.println("Seller " + sale);
System.out.println("Buyer " + pur);
}
}
9. Command Pattern#
9.1 Negative Code:#
package command.negative;
class Cook {
public void beef() {
System.out.println("A plate of beef");
}
public void duck() {
System.out.println("A plate of soy sauce duck");
}
public void chineseCabbage() {
System.out.println("A big cabbage");
}
}
public class Demo {
// Responsibility is unclear, lacks a waiter role
// Needs to adopt the command pattern
public static void main(String[] args) {
new Cook().beef();
new Cook().chineseCabbage();
}
}
9.2 Positive Code:#
package command.positive;
import javax.swing.*;
import java.util.ArrayList;
import java.util.List;
class Cook {
public void beef() {
System.out.println("A plate of beef");
}
public void duck() {
System.out.println("A plate of soy sauce duck");
}
public void chineseCabbage() {
System.out.println("A big cabbage");
}
}
// Abstract command
abstract class Command {
protected Cook cook;
public Command(Cook cook) {
this.cook = cook;
}
abstract void execute();
}
class BeefCommand extends Command {
public BeefCommand(Cook cook) {
super(cook);
}
@Override
void execute() {
this.cook.beef();
}
}
class DuckCommand extends Command {
public DuckCommand(Cook cook) {
super(cook);
}
@Override
void execute() {
this.cook.duck();
}
}
class ChineseCabbage extends Command {
public ChineseCabbage(Cook cook) {
super(cook);
}
@Override
void execute() {
this.cook.chineseCabbage();
}
}
class Waiter {
private Command command;
public Command getCommand() {
return command;
}
public void setCommand(Command command) {
this.command = command;
}
public void orderDishes() {
this.command.execute();
}
}
class WaitList {
private List<Command> menu = new ArrayList<>();
public void addCommand(Command command) {
this.menu.add(command);
}
public void orderDishes() {
for (Command command : menu) {
command.execute();
}
}
}
public class Demo {
public static void main(String[] args) {
Cook wang = new Cook();
Command beef = new BeefCommand(wang);
Command duck = new DuckCommand(wang);
Command cabbage = new ChineseCabbage(wang);
Waiter xiaoer = new Waiter();
xiaoer.setCommand(beef);
xiaoer.orderDishes();
xiaoer.setCommand(duck);
xiaoer.orderDishes();
xiaoer.setCommand(cabbage);
xiaoer.orderDishes();
System.out.println("Second case: order together (not one by one)");
WaitList waitList = new WaitList();
waitList.addCommand(cabbage);
waitList.addCommand(duck);
waitList.addCommand(beef);
waitList.orderDishes();
}
}
10. Strategy Pattern#
10.1 Negative Code:#
10.2 Positive Code:#
Decorator Pattern#
Facade Pattern (Experiment 3's Question)#
Experiment Code:
package facadePattern;
public abstract class AbstractFacade {
public abstract void execute();
}
package facadePattern;
class FileOperation {
public void read() {
System.out.println("File operation");
}
}
class XMLDataConvertor {
public void convert() {
System.out.println("XML format conversion");
}
}
class DataAnalysis {
public void handle() {
System.out.println("Data analysis");
}
}
class ReportDisplay {
public void display() {
System.out.println("Result display");
}
}
package facadePattern;
public class FileFacade extends AbstractFacade {
private XMLDataConvertor xmlDataConvertor;
private DataAnalysis dataAnalysis;
private ReportDisplay reportDisplay;
public FileFacade() {
this.xmlDataConvertor = new XMLDataConvertor();
this.dataAnalysis = new DataAnalysis();
this.reportDisplay = new ReportDisplay();
}
@Override
public void execute() {
xmlDataConvertor.convert();
dataAnalysis.handle();
reportDisplay.display();
}
}
package facadePattern;
class FileOperation {
public void read() {
System.out.println("File operation");
}
}
class XMLDataConvertor {
public void convert() {
System.out.println("XML format conversion");
}
}
class DataAnalysis {
public void handle() {
System.out.println("Data analysis");
}
}
class ReportDisplay {
public void display() {
System.out.println("Result display");
}
}
package facadePattern;
public class Client {
public static void main(String[] args) {
FileFacade f = new FileFacade(); // Class that does not require format conversion
f.execute();
System.out.println("-----");
XMLFacade x = new XMLFacade(); // Class that requires format conversion
x.execute();
}
}