设计模式

2022-10-05  本文已影响0人  bowen_wu

设计模式

概述

单例模式

public class World {
    // 当前单例问题 => 1. 反射  2. 反序列化  3. 需要在类加载的时候就初始化
    // public static World SINGLETON_WORLD = new World();

    private static World SINGLETON_WORLD;

    public static World getInstance() {
        if (SINGLETON_WORLD == null) {
            // 问题:多线程的情况下可能会同时进入
            SINGLETON_WORLD = new World();
        }
        return SINGLETON_WORLD;
    }

    // 双锁检测,在工作中上述两种情况就能够满足了
    public static World getInstance() {
        if (SINGLETON_WORLD == null) {
            synchronized (World.class) {
                if (SINGLETON_WORLD == null) {
                    SINGLETON_WORLD = new World();
                }
            }
        }

        return SINGLETON_WORLD;
    }

    private World() {
    }
}

// Effective Java 推荐 => enum 由虚拟机保证 SINGLETON_INSTANCE 只有一份
// enum 默认继承 Enum 类,不能再继承其他类,但是可以实现接口
public enum Singleton {
    SINGLETON_INSTANCE;
}

工厂方法/抽象工厂方法

public class Car {
    private Car(String name) {
    }

    private Car(String name, String color) {
    }

    // 工厂方法 => 
    //      1. 有业务倾向的名字  
    //      2. 构造器不能 return null,工厂方法可以,更加灵活  
    //      3. 可以将构造器封装起来,外界都通过工厂方法去获取实例  
    //      4. 可以根据传入的参数进行一些业务逻辑处理,case:返回 Car 的子类
    public static Car ofName(String name) {
        if (name == null) {
            return null;
        }
    }

    public static void main(String[] args) {
        new Car("a");
        Car.ofName("a");
    }
}

适配器模式 Adapter

建造者模式

public class Book {
    private String preface;
    private String head;
    private String content;
    private String thanks;

    public static final class BookBuilder {
        private String preface;
        private String head;
        private String content;
        private String thanks;

        private BookBuilder() {
        }

        public static BookBuilder aBook() {
            return new BookBuilder();
        }

        public BookBuilder withPreface(String preface) {
            this.preface = preface;
            return this;
        }

        public BookBuilder withHead(String head) {
            this.head = head;
            return this;
        }

        public BookBuilder withContent(String content) {
            this.content = content;
            return this;
        }

        public BookBuilder withThanks(String thanks) {
            this.thanks = thanks;
            return this;
        }

        public Book build() {
            Book book = new Book();
            book.head = this.head;
            book.preface = this.preface;
            book.thanks = this.thanks;
            book.content = this.content;
            return book;
        }
    }

    public static void main(String[] args) {
        Book book = BookBuilder.aBook().withPreface("preface")
                .withHead("Head")
                .withContent("content")
                .build();
    }
}

代理模式

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

public class ProxyPattern {
    public static void main(String[] args) {
        ServiceProvider serviceProvider = (ServiceProvider) Proxy.newProxyInstance(ProxyPattern.class.getClassLoader(),
                // 动态代理
                new Class[]{ServiceProvider.class},
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        // 动态的,可以灵活的根据业务需求去处理
                        return null;
                    }
                }
        );
        serviceProvider.sayHello("Hi!");
    }

    static class LoadBalancerServiceProvider implements ServiceProvider {
        // 静态代理
        private final List<ServiceProvider> serviceProviderList;
        private final AtomicInteger currentIndex = new AtomicInteger(0);

        public LoadBalancerServiceProvider(List<ServiceProvider> serviceProviderList) {
            this.serviceProviderList = serviceProviderList;
        }

        @Override
        public String sayHello(String name) {
            ServiceProvider currentServiceProvider = serviceProviderList.get(currentIndex.getAndAdd(1) % serviceProviderList.size());
            return currentServiceProvider.sayHello(name);
        }
    }
}

interface ServiceProvider {
    String sayHello(String name);
}

装饰器模式

import java.util.Arrays;

public class Decorator {
    public static void main(String[] args) {
        // 需求 => 监控 list 所有的修改操作,当修改的时候打印日志
        List<String> list = Arrays.asList();
        list.add("a");
        list.add("b");

        List<String> decoratedList = new LoggingListDecorator(list);

        // 装饰可以嵌套 => 此时会打印出两条日志
        List<String> decoratedList2 = new LoggingListDecorator(decoratedList);
    }

    private static class LoggingListDecorator implements List<String> {
        private List<String> delegate;

        public LoggingListDecorator(List<String> delegate) {
            this.delegate = delegate;
        }

        // 之后所有覆盖的方法都调用 delegate 相应的方法
    }
}

组合模式

public class Calculator {
    public static void main(String[] args) {
        // 1 + 2 + 3 + 4
        Expression expression = new AddExpression(new NumberExpression(1),
                new AddExpression(new NumberExpression(2),
                        new AddExpression(new NumberExpression(3), new NumberExpression(4))
                )
        );

        System.out.println(expression.evaluate());
        //    +
        //  1   +
        //    2   +
        //      3   4
    }

    static class AddExpression implements Expression {
        Expression left;
        Expression right;

        public AddExpression(Expression left, Expression right) {
            this.left = left;
            this.right = right;
        }

        @Override
        public int evaluate() {
            return left.evaluate() + right.evaluate();
        }
    }

    static class NumberExpression implements Expression {
        private final int value;

        public NumberExpression(int value) {
            this.value = value;
        }

        @Override
        public int evaluate() {
            return value;
        }
    }
}

interface Expression {
    int evaluate();
}

模板方法


策略模式

// 1. 打折的逻辑和具体的业务逻辑完全分离
// 2. 如果策略变更,之前的代码都不需要更改,只需要添加一个类
// 3. 代码编译的时候,具体的策略可能还不存在
public class Discount {
    public double discount(double amount, DiscountStrategy discountStrategy) {
        return discountStrategy.calculate(amount);
//    public double discount(double amount, String customerType) {
//        switch (customerType) {
//            case "VIP":
//                return amount * 0.8;
//            case "VIPAndCoupon":
//                return amount * 0.8 - 100;
//            default:
//                return amount;
//        }
    }
}

interface DiscountStrategy {
    double calculate(double value);
}

class VIPStrategy implements DiscountStrategy {
    @Override
    public double calculate(double value) {
        return value * 0.8;
    }
}

class VIPAndCouponStrategy implements DiscountStrategy {
    @Override
    public double calculate(double value) {
        return value * 0.8 - 100;
    }
}

class NormalStrategy implements DiscountStrategy {
    @Override
    public double calculate(double value) {
        return value;
    }
}

享元模式 Flyweight

public class Flyweight {
    public static void main(String[] args) {
        // i 和 j 两个对象是一模一样的 => 因为有缓存 -128 - 127 都被缓存下来了
        Integer i = 1;
        Integer j = 1;
    }
}

外观模式/门面模式 Facade

public class ShitMountains {
    // 遗留系统,有很多很多逻辑细节
    private void foo() {
    }

    private void bar() {
    }

    private void baz() {
    }
}

class FacadeForShitMountains {
    // 以后只需要和 Facade 打交道,调用者并不知道具体的细节
    // 之后其他调用者只调用 Facade 提供的接口
    // 如果想更换遗留系统,只需要将 Facade 更新实现即可
    public process() {
        ShitMountains shitMountains = new ShitMountains();
        shitMountains.foo();
        shitMountains.bar();
    }
}

class System {
    public process() {
        FacadeForShitMountains facadeForShitMountains = new FacadeForShitMountains();
        facadeForShitMountains.process();

//        ShitMountains shitMountains = new ShitMountains();
//        shitMountains.foo();
//        shitMountains.bar();
    }
}

命令模式 Command

import java.util.List;

public class Commander {
    public static void main(String[] args) {
        // 和具体的命令耦合在一起
//        Eat eat = new Eat();
//        eat.run();
//
//        Sleep sleep = new Sleep();
//        sleep.run();

        List<Command> commands = getCommandList();
        commands.forEach(Command::run);
    }

    private static List<Command> getCommandList() {
        // 可以从其他地方获取命令,如 Eat 或 Sleep
        return null;
    }
}

interface Command {
    // Command 就是一个 Runnable
    void run();
}

class Eat implements Command {
    @Override
    public void run() {
        System.out.println("eat!");
    }
}

class Sleep implements Command {
    @Override
    public void run() {
        System.out.println("sleep!");
    }
}

责任链模式

观察者模式/发布订阅模式

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class RadioStation {
    public static void main(String[] args) {
        EventBus eventBus = EventBus.INSTANCE;
        Car car = new Car(eventBus);
        car.subscribe("100.1");
        eventBus.publish("100.1", "ring!");
    }
}

interface Listener {
    void processMessage(String message);
}

enum EventBus {
    INSTANCE;

    final Map<String, List<Listener>> map = new HashMap<>();

    public void subscribe(String channel, Listener listener) {
        List<Listener> listeners = map.getOrDefault(channel, new ArrayList<>());
        listeners.add(listener);
        map.put(channel, listeners);
    }

    public void publish(String channel, String message) {
        map.getOrDefault(channel, new ArrayList<>()).forEach(listener -> listener.processMessage(message));
    }
}

class Car implements Listener {
    EventBus eventBus;

    public Car(EventBus eventBus) {
        this.eventBus = eventBus;
    }

    public void subscribe(String channel) {
        eventBus.subscribe(channel, this);
    }

    @Override
    public void processMessage(String message) {
        System.out.println(message);
    }
}

迭代器模式

import java.util.Iterator;

public class IteratorPattern {
    public static void main(String[] args) {
        ArrayList list1 = new ArrayList();
//        for (Object element : list1.elements) {
//            System.out.println(element);
//        }
        list1.forEach(System.out::println);

        LinkedList list2 = new LinkedList();
//        Node currentNode = list2.head;
//        while (currentNode != null) {
//            System.out.println(currentNode.value);
//            currentNode = currentNode.next;
//        }
        list2.forEach(System.out::println);
    }
}

class ArrayListIterator implements Iterator {
    int current = 0;
    Object[] elements;

    public ArrayListIterator(Object[] elements) {
        this.elements = elements;
    }

    @Override
    public boolean hasNext() {
        return current < elements.length;
    }

    @Override
    public Object next() {
        return elements[current++];
    }
}

class ArrayList implements Iterable {
    Object[] elements;

    @Override
    public Iterator iterator() {
        return new ArrayListIterator(elements);
    }
}

class LinkedListIterator implements Iterator {
    Node head;

    public LinkedListIterator(Node head) {
        this.head = head;
    }

    @Override
    public boolean hasNext() {
        return head.next != null;
    }

    @Override
    public Object next() {
        Node next = head.next;
        head = next;
        return next;
    }
}

class LinkedList implements Iterable {
    Node head;

    @Override
    public Iterator iterator() {
        return new LinkedListIterator(head);
    }
}

class Node {
    Object value;
    Node next;
}

访问者模式 Visitor

// 给定一个 Java 文件,返回这个 Java 文件中所有的类定义

知识点

  1. 开闭原则 => 在面向对象编程领域中,开闭原则规定软件中的对象(类、模块、函数等等)应该对于扩展是开放的,但是对于修改是封闭的,这意味着一个实体是允许在不改变它的源代码的前提下变更它的行为
上一篇 下一篇

猜你喜欢

热点阅读