banner
tiaotiaotang

tiaotiaotang

互联网科技爱好者/后端开发入门,学习ing
微信公众号

Design Patterns

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

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.