Java学习篇-常见设计模式

44 阅读7分钟

背景

本篇主要是java学习过程中编写的练手代码,都是很基础的东西,但又觉得以后可能会用到,特此记录。

常见设计模式

将常见的几种设计模式进行实现,由于之前是C++er,因此实现主要是基于之前学习C++时看的设计模式代码进行修改的。

参考资料:subingwen.cn/design-patt… 这个博客介绍的设计模式简单易懂且全面,力推,不过是用C++实现的。

由于上述博客介绍的很详细,在此就不在介绍各设计模式了。

单例模式

// 懒汉模式
public class Singleton {
    private volatile static Singleton singleton = null;
    private Singleton() {}
    public void print() {
        System.out.println("Singleton");
    }
    public static Singleton getSingleton() {
        if (singleton == null) {
            synchronized (Singleton.class) {
                if (singleton == null) {
                    singleton = new Singleton();
                }
            }
        }
        return singleton;
    }
    public static void main(String[] args) {
        Singleton sgn = Singleton.getSingleton();
        sgn.print();
    }
}

// 饿汉模式
public class Singleton {
    private Singleton() {}

    public void print() {
        System.out.println("helloworld");
    }
    private static class SingletonInstance {
        private static final Singleton INSTANCE = new Singleton();
    }
    public static Singleton getInstance() {
        return SingletonInstance.INSTANCE;
    }

    public static void main(String[] args) {
        Singleton sgn = Singleton.getInstance();
        sgn.print();
    }
}

简单工厂模式

interface Smile {
    void transform();
    void ability();
}
/*
abstract class Smile {
    public abstract void transform();
    public abstract void ability();
}
*/
class SheepSmile implements Smile {
    public void transform() {
        System.out.println("变成人兽 -- 山羊人形态...");
    }
    public void ability() {
        System.out.println("将手臂变成绵羊角的招式 -- 巨羊角");
    }
}
class LionSmile implements Smile {
    public void transform() {
        System.out.println("变成人兽 -- 狮子人形态...");
    }
    public void ability() {
        System.out.println("火遁.豪火球之术");
    }
}
class BatSmile implements Smile {
    public void transform() {
        System.out.println("变成人兽 -- 蝙蝠人形态...");
    }
    public void ability() {
        System.out.println("声纳引箭之万剑归宗...");
    }
}
public class SimpleFactory {
    enum Type {
        SHEEP, LION, BAT
}
    public Smile CreateSmile(Type type) {
        Smile res = null;
        switch (type) {
            case SHEEP:
                res = new SheepSmile();
                break;
            case LION:
                res = new LionSmile();
                break;
            case BAT:
                res = new BatSmile();
                break;
            default:
                break;
        }
        return res;
    }
    public static void main(String[] args) {
        SimpleFactory factory = new SimpleFactory();
        Smile ob = factory.CreateSmile(Type.BAT);
        ob.transform();
        ob.ability();
    }
}

工厂模式

class SheepSmile implements Smile {
    public void transform() {
        System.out.println("变成人兽 -- 山羊人形态...");
    }
    public void ability() {
        System.out.println("将手臂变成绵羊角的招式 -- 巨羊角");
    }
}
class LionSmile implements Smile {
    public void transform() {
        System.out.println("变成人兽 -- 狮子人形态...");
    }
    public void ability() {
        System.out.println("火遁.豪火球之术");
    }
}
class BatSmile implements Smile {
    public void transform() {
        System.out.println("变成人兽 -- 蝙蝠人形态...");
    }
    public void ability() {
        System.out.println("声纳引箭之万剑归宗...");
    }
}
interface SmileFactory {
    public Smile createSmile();
}
class SheepFactory implements SmileFactory {
    public Smile createSmile() {
        return new SheepSmile();
    }
}
class LionFactory implements SmileFactory {
    public Smile createSmile() {
        return new LionSmile();
    }
}
class BatFactory implements SmileFactory {
    public Smile createSmile() {
        return new BatSmile();
    }
}
public class Factory {
    public static void main(String[] args) {
        SmileFactory factory = new LionFactory();
        Smile smile = factory.createSmile();
        smile.ability();
    }
}

抽象工厂模式

// 船体
abstract class ShipBody {
    public abstract String getShipBody();
}
class WoodBody extends ShipBody {
    @Override
    public String getShipBody() {
        return "用木材制作船体!";
    }
}
class IronBody extends ShipBody {
    @Override
    public String getShipBody() {
        return "用钢铁制作船体!";
    }
}
class MetalBody extends ShipBody {
    @Override
    public String getShipBody() {
        return "用合金制作船体!";
    }
}
// 武器
abstract class Weapon {
    public abstract String getWeapon();
}
class Gun extends Weapon {
    @Override
    public String getWeapon() {
        return "武器--枪";
    }
}
class Laser extends Weapon {
    @Override
    public String getWeapon() {
            return "武器--激光";
    }
}
class Cannon extends Weapon {
    @Override
    public String getWeapon() {
        return "武器--机关炮";
    }
}
// 动力
abstract class Engine {
    public abstract String getEngine();
}
class Human extends Engine {
    @Override
    public String getEngine() {
        return "动力--人";
    }
}
class Diesel extends Engine {
    @Override
    public String getEngine() {
        return "动力--内燃机";
    }
}
class Nuclear extends Engine {
    @Override
    public String getEngine() {
        return "动力--核能";
    }
}
class Ship {
    ShipBody body;
    Weapon weapon;
    Engine engine;
    Ship(ShipBody body, Weapon weapon, Engine engine) {
        this.body = body;
        this.weapon = weapon;
        this.engine = engine;
    }
    public String getProperty() {
        return body.getShipBody() + weapon.getWeapon() + engine.getEngine();
    }
}
abstract class Factory {
    public abstract Ship createShip();
}
class BasicFactory extends Factory {
    @Override
    public Ship createShip() {
        Ship ship = new Ship(new WoodBody(), new Gun(), new Human());
        System.out.println("《基础型》战船生产完毕");
        return ship;
    }
}
class StandardFactory extends Factory {
    @Override
    public Ship createShip() {
        Ship ship = new Ship(new IronBody(), new Cannon(), new Diesel());
        System.out.println("《标准型》战船生产完毕");
        return ship;
    }
}
class UltimateFactory extends Factory {
    @Override
    public Ship createShip() {
        Ship ship = new Ship(new MetalBody(), new Laser(), new Nuclear());
        System.out.println("《旗舰型》战船生产完毕");
        return ship;
    }
}
public class AbstractFactory {
    public static void main(String[] args) {
        Factory factory = new StandardFactory();
        Ship ship = factory.createShip();
        System.out.println(ship.getProperty());
    }
}

代理模式

abstract class Communication {
    public abstract void communicate();
}
class Speaker extends Communication {
    @Override
    public void communicate() {
        System.out.println("开始说话...");
        System.out.println("通话时发生类一系列的表情变化...");
    }
}
class DenDenMushi extends Communication {
    private boolean isAgent = false;
    private Speaker speaker = null;
    DenDenMushi() {
        isAgent = true;
        speaker = new Speaker();
    }
    public boolean isAgent() {
        return isAgent;
    }
    @Override
    public void communicate() {
        if (isAgent()) {
            System.out.println("电话虫开始实时模仿通话者的语言和表情...");
            speaker.communicate();
        }
    }
}
public class AgentPattern {
    public static void main(String[] args) {
        Communication comm = new Speaker();
        comm.communicate();
        System.out.println("===================");
        comm = new DenDenMushi();
        comm.communicate();
    }
}

观察者模式

abstract class NewAgency{
    protected ArrayList<Observer> list = new ArrayList<>();
    public abstract void notify(String msg);
    public void attach(Observer ob) {
        list.add(ob);
    }
    public void deatch(Observer ob) {
        list.remove(ob);
    }
}
class Morgans extends NewAgency {
    @Override
    public void notify(String msg) {
        System.out.println("摩根斯新闻社报纸的订阅者一共有 " + list.size() + " 人");
        for (Observer ob : list) {
            ob.update(msg);
        }
    }
}
class Gossip extends NewAgency {
    @Override
    public void notify(String msg) {
        System.out.println("八卦新闻社报纸的订阅者一共有 " + list.size() + " 人");
        for (Observer ob : list) {
            ob.update(msg);
        }
    }
}
abstract class Observer {
    protected String name;
    protected NewAgency news;
    Observer(String name, NewAgency news) {
        this.name = name;
        this.news = news;
        this.news.attach(this);
    }
    public void unsubscribe() {
        this.news.deatch(this);
    }
    public abstract void update(String msg);
}
class Dragon extends Observer {
    Dragon(String name, NewAgency news) {
        super(name, news);
    }
    @Override
    public void update(String msg) {
        System.out.println("路飞的老爸革命军龙收到消息:" + msg);
    }
}
class Shanks extends Observer {
    Shanks(String name, NewAgency news) {
        super(name, news);
    }
    @Override
    public void update(String msg) {
            System.out.println("路飞的引路人红发香克斯收到消息:" + msg);
    }
}
class Bartolomeo extends Observer {
    Bartolomeo(String name, NewAgency news) {
        super(name, news);
    }
    @Override
    public void update(String msg) {
        System.out.println("路飞的头号粉丝巴托洛米奥收到消息:" + msg);
    }
}
public class ObserverPattern {
    public static void main(String[] args) {
        Morgans ms = new Morgans();
        Gossip gossip = new Gossip();
        Dragon dragon = new Dragon("蒙奇.D.龙", ms);
        Shanks shanks = new Shanks("香克斯", ms);
        Bartolomeo barto = new Bartolomeo("8️巴托洛米奥", gossip);
        ms.notify("蒙奇D路飞成为新世界的新的四皇之一,赏金30亿贝里!");
        ms.deatch(dragon);
        ms.notify("蒙奇D路飞成为新世界的新的四皇之一,赏金30亿贝里!");
        System.out.println("==================================");
        gossip.notify("女帝汉库克想要嫁给路飞,给路飞生猴子!");
    }
}

生产者-消费者模式

// 三种方式

// 方式一 wait/notifyAll实现
public class PC_wait_notifyAll {
    static class Producer implements Runnable {
        private List<Integer> list;
        private int maxLength;
        public Producer(List<Integer> list, int maxLength) {
            this.list = list;
            this.maxLength = maxLength;
        }
        @Override
        public void run() {
            while (true) {
                synchronized(list) {
                    try{
                        while (list.size() == maxLength) {
                            System.out.println("生产者" + Thread.currentThread().getName() + "  list以达到最大容量,进行wait");
                            list.wait();
                            System.out.println("生产者" + Thread.currentThread().getName() + "  退出wait");
                        }
                        Random random = new Random();
                        int i = random.nextInt();
                        System.out.println("生产者" + Thread.currentThread().getName() + " 生产数据" + i);
                        list.add(i);
                        list.notifyAll();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    static class Consumer implements Runnable {
        private  List<Integer> list;
        public Consumer(List list) {
            this.list = list;
        }
        @Override
        public void run() {
            while (true) {
                synchronized (list) {
                    try{
                        while (list.isEmpty()) {
                            System.out.println("消费者" + Thread.currentThread().getName() + "  list为空,进行wait");
                            list.wait();
                            System.out.println("消费者" + Thread.currentThread().getName() + "  退出wait");
                        }
                        Integer element = list.remove(0);
                        System.out.println("消费者" + Thread.currentThread().getName() + "  消费数据:" + element);
                        list.notifyAll();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    public static void main(String[] args) {
        LinkedList linkedList = new LinkedList();
        ExecutorService service = Executors.newFixedThreadPool(15);
        for (int i = 0; i < 5; ++i) {
            service.submit(new Producer(linkedList, 8));
        }
        for (int i = 0; i < 10; ++i) {
            service.submit(new Consumer(linkedList));
        }
    }
}

// 方式二 await/signal
public class PC_await_signalAll {
    private static ReentrantLock lock = new ReentrantLock();
    private static Condition full = lock.newCondition();
    private static Condition empty = lock.newCondition();
    public static void main(String[] args) {
        LinkedList linkedList = new LinkedList();
        ExecutorService executorService = Executors.newFixedThreadPool(15);
        for (int i = 0; i < 5; ++i) {
            executorService.submit(new Producer(linkedList, 8, lock));
        }
        for (int i = 0; i < 10; ++i) {
            executorService.submit(new Consumer(linkedList, lock));
        }
    }
    static class Producer implements Runnable {
        private List<Integer> list;
        private int maxLength;
        private Lock lock;

        public Producer(List<Integer> list, int maxLength, Lock lock) {
            this.list = list;
            this.maxLength = maxLength;
            this.lock = lock;
        }
        @Override
        public void run() {
            while (true) {
                lock.lock();
                try{
                    while (list.size() == maxLength) {
                        System.out.println("生产者" + Thread.currentThread().getName() + "  list以达到最大容量,进行wait");
                        full.await();
                        System.out.println("生产者" + Thread.currentThread().getName() + "  退出wait");
                    }
                    Random random = new Random();
                    int i = random.nextInt();
                    System.out.println("生产者" + Thread.currentThread().getName() + " 生产数据" + i);
                    list.add(i);
                    empty.signalAll();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }

            }
        }
    }
    static class Consumer implements Runnable {
        private  List<Integer> list;
        private Lock lock;
        public Consumer(List list, Lock lock) {
            this.list = list;
            this.lock = lock;
        }
        @Override
        public void run() {
            while (true) {
                lock.lock();
                try{
                    while (list.isEmpty()) {
                        System.out.println("消费者" + Thread.currentThread().getName() + "  list为空,进行wait");
                        empty.await();
                        System.out.println("消费者" + Thread.currentThread().getName() + "  退出wait");
                    }
                    Integer element = list.remove(0);
                    System.out.println("消费者" + Thread.currentThread().getName() + "  消费数据:" + element);
                    full.signalAll();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }
        }
    }
}

// 方式三 BlockingQueue实现
public class PC_BlockingQueue {
    private static LinkedBlockingQueue<Integer> queue = new LinkedBlockingQueue<>();
    
    public static void main(String[] args) {
        ExecutorService service = Executors.newFixedThreadPool(15);
        for (int i = 0; i < 5; ++i) {
            service.submit(new Productor(queue));
        }
        for (int i = 0; i < 10; ++i) {
            service.submit(new Consumer(queue));
        }
    }
    static class Productor implements Runnable {
        private BlockingQueue queue;
        
        public Productor(BlockingQueue queue) {
            this.queue = queue;
        }
        @Override
        public void run() {
            try {
                while (true) {
                    Random random = new Random();
                    int i = random.nextInt();
                    System.out.println("生产者" + Thread.currentThread().getName() + "生产数据" + i);
                    queue.put(i);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    static class Consumer implements Runnable {
        private BlockingQueue queue;

        public Consumer(BlockingQueue queue) {
            this.queue = queue;
        }
        @Override
        public void run() {
            try {
                while (true) {
                    Integer element = (Integer) queue.take();
                    System.out.println("消费者" + Thread.currentThread().getName() + "正在消费数据" + element);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

发布/订阅(事件总线)框架

简述

基于事件总线的发布/订阅框架

基本版

  • 支持发布事件(post)、订阅事件(subscribe)、 解除订阅(unsubscribe)

    • 一个事件可以有 多个订阅者,发送事件可以在任意线程发生
    • 发布订阅:当发送A类型事件时,所有已订阅A类型事件的 订阅者会接收到回调
    • 解除订阅: 某个订阅者解除A类型事件后,再有A类型的事件产生时,不再接收到回调
  • 考虑线程安全问题

进阶版

  • 支持多线程事件消费能力,订阅事件时,支持消费线程的方式,如在事件发送方线程消费、在异步线程池消费

代码

github:github.com/noResign/Ev…

参考资料

juejin.cn/post/684490…

注意点

  • 要放入map的对象,得重写hashCode和equals方法
  • 测试的时候可以等所有订阅者注册完了在进行发布,这里使用的是CountDownLatch进行协调。如果不这样可能造成某个事件无人订阅
  • 事件-订阅者的映射使用了CopyOnWriteArrayList存订阅者们,具有线程安全。但由于在写操作时会产生额外开销