引用

https://segmentfault.com/a/1190000023963515
https://www.runoob.com/design-pattern/observer-pattern.html
https://www.jianshu.com/p/7cbb6b0bbabc

抽象工厂

工厂是抽象的,产品是抽象的,而且有多个产品需要创建,因此,这个抽象工厂会对应到多个实际工厂,每个实际工厂负责创建多个实际产品

提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

作用

允许使用抽象的接口来创建一组相关产品,而不需要知道或关心实际生产出的具体产品是什么,这样就可以从具体产品中被解耦。

代码实现

public class Main {
    public static void main(String[] args) {
        IFactory factory = new FactoryA();
        IProduct product = factory.createProduct();
        product.run();
    }
}

class FactoryA implements IFactory {
    @Override
    public IProduct createProduct() {
        return new ProductA();
    }
}

class ProductA implements IProduct {
    @Override
    public void run() {
        System.out.println("这是产品A");
    }
}

interface IFactory {
    public IProduct createProduct();
}

interface IProduct {
    public void run();
}

单例模式

单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。

作用

一个全局使用的类频繁地创建与销毁

代码实现

高版本的JVM加载class并没有初始化静态变量,直到第一次调用getInstance()才会执行createInstance()方法(此处用new亦同理),也就是JVM本身就是懒加载static变量的

public class Main {
    public static void main(String[] args) {
        Singleton s = null;
        System.out.println(Singleton.class);
        s = Singleton.getInstance(); // create singleton instance...
        System.out.println(s);
    }
}

class Singleton {

    static {
        System.out.println("init Singleton class...");
    }

    private static Singleton instance = createInstance();

    private static Singleton createInstance() {
        System.out.println("create singleton instance...");
        return new Singleton();
    }

    private Singleton() {
    }

    public static Singleton getInstance() {
        return instance;
    }
}

装饰器模式

装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。

这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。

作用

动态地给一个对象添加一些额外的职责。就增加功能来说,相比生成子类更为灵活。

代码实现

public class Main {
    public static void main(String[] args) {
        ITarget target=new Target();
        ITarget decorator=new Decorator(target);
        decorator.run();
    }
}

interface ITarget {
    void run();
}

class Target implements ITarget {
    @Override
    public void run() {
        System.out.println("目标实现");
    }
}

class Decorator implements ITarget {
    private final ITarget target;

    public Decorator(ITarget target) {
        this.target = target;
    }

    @Override
    public void run() {
        System.out.println("目标装饰开始");
        target.run();
        System.out.println("目标装饰结束");
    }
}

观察者模式

观察者模式(Observer)又称发布-订阅模式(Publish-Subscribe:Pub/Sub)。它是一种通知机制,让发送通知的一方(被观察方)和接收通知的一方(观察者)能彼此分离,互不影响。

作用

一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作

代码实现

public class Main {
    public static void main(String[] args) {
        Store store=new Store();
        UserA userA=new UserA();
        UserB userB=new UserB();
        store.addObserver(userA);
        store.addObserver(userB);
        store.addNewProduct("手电",12.68);
    }
}

class Store {
    private final List<ProductObserver> observers = new ArrayList<>();
    private final Map<String, Product> products = new HashMap<>();

    // 注册观察者:
    public void addObserver(ProductObserver observer) {
        this.observers.add(observer);
    }

    // 取消注册:
    public void removeObserver(ProductObserver observer) {
        this.observers.remove(observer);
    }

    public void addNewProduct(String name, double price) {
        Product p = new Product(name, price);
        products.put(p.name, p);
        // 通知观察者:
        observers.forEach(o -> o.onPublished(p));
    }

    public void setProductPrice(String name, double price) {
        Product p = products.get(name);
        p.price = price;
        // 通知观察者:
        observers.forEach(o -> o.onPriceChanged(p));
    }
}

class Product {
    String name;
    double price;
    
    public Product(String name, double price) {
        this.name = name;
        this.price = price;
    }
}

interface ProductObserver {
    void onPublished(Product p);
    void onPriceChanged(Product p);
}

class UserA implements ProductObserver{
    @Override
    public void onPublished(Product p) {
        System.out.println("用户A,产品添加:"+p.name+"价格"+p.price);
    }
    @Override
    public void onPriceChanged(Product p) {
        System.out.println("用户A,产品变更:"+p.name+"价格"+p.price);
    }
}
class UserB implements ProductObserver{
    @Override
    public void onPublished(Product p) {
        System.out.println("用户B,产品添加:"+p.name+"价格"+p.price);
    }
    @Override
    public void onPriceChanged(Product p) {
        System.out.println("用户B,产品变更:"+p.name+"价格"+p.price);
    }
}

生产者消费者模型

①生产者持续生产,直到仓库放满产品,则停止生产进入等待状态;仓库不满后继续生产;
②消费者持续消费,直到仓库空,则停止消费进入等待状态;仓库不空后,继续消费;
③生产者可以有多个,消费者也可以有多个;

实现方式

①使用wait()和notify()
②使用Lock和Condition
③使用信号量Semaphore
④使用JDK自带的阻塞队列
⑤使用管道流

代码实现

wait+synchronized实现

class Producer implements Runnable {
        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                try {
                    Thread.sleep(3000);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                synchronized (LOCK) {
                    while (count == FULL) {
                        try {
                            LOCK.wait();
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                    count++;
                    System.out.println(Thread.currentThread().getName() + "生产者生产,目前总共有" + count);
                    LOCK.notifyAll();
                }
            }
        }
    }
    class Consumer implements Runnable {
        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (LOCK) {
                    while (count == 0) {
                        try {
                            LOCK.wait();
                        } catch (Exception e) {
                        }
                    }
                    count--;
                    System.out.println(Thread.currentThread().getName() + "消费者消费,目前总共有" + count);
                    LOCK.notifyAll();
                }
            }
        }
    }

阻塞队列实现

public class Main {
    private static Integer count = 0;
    //创建一个阻塞队列
    final BlockingQueue blockingQueue = new ArrayBlockingQueue<>(10);

    public static void main(String[] args) {
        Main main = new Main();
        new Thread(main.new Producer()).start();
        new Thread(main.new Consumer()).start();
        new Thread(main.new Producer()).start();

    }

    class Producer implements Runnable {
        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                try {
                    Thread.sleep(3000);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                try {
                    blockingQueue.put(1);
                    count++;
                    System.out.println(Thread.currentThread().getName()
                            + "生产者生产,目前总共有" + count);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    class Consumer implements Runnable {
        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e1) {
                    e1.printStackTrace();
                }
                try {
                    blockingQueue.take();
                    count--;
                    System.out.println(Thread.currentThread().getName()
                            + "消费者消费,目前总共有" + count);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}