设计模式


设计模式

单例模式

定义

确保类中只有一个实例,并且提供一个全局访问点。

实现

  • 饿汉式-线程安全
/**
 * 饿汉式-线程安全
 */
public class SingleHungry {

    /**
     * 类初始化的时候就加载这个对象
     */
    private static final SingleHungry singleHungry = new SingleHungry();

    private SingleHungry() {
    }

    public static SingleHungry getInstance() {
        return singleHungry;
    }
}
  • 懒汉式-线程不安全
/**
 * 懒汉式-线程不安全
 */
public class SingleSlacker {

    private static SingleSlacker singleSlacker = null;

    private SingleSlacker() {
    }

    /**
     * 运行的时候加载这个对象
     * @return
     */
    public static SingleSlacker getInstance() {
        if (singleSlacker == null) {
            singleSlacker = new SingleSlacker();
        }
        return singleSlacker;
    }
}
  • 懒汉式-双重同步锁
/**
 * 懒汉式-双重同步锁
 */
public class SingleSlackerLock {

    private static volatile SingleSlackerLock singleSlackerLock = null;

    private SingleSlackerLock() {
    }

    /**
     * 运行时加载
     * @return
     */
    public static SingleSlackerLock getInstance() {
        if (singleSlackerLock == null) {
            synchronized (SingleSlackerLock.class) {
                if (singleSlackerLock == null) {
                    singleSlackerLock = new SingleSlackerLock();
                }
            }
        }
        return singleSlackerLock;
    }
}

优缺点

  • 优点

只生成一个实例,对性能的开销比较少,能提高系统效率,同时能严格控制访问。

  • 缺点

由于只有一个实例,因此类的职责会过重,同时没有抽象类,扩展有一定局限。

简单工厂

定义

有一个工厂对象决定创建对应的产品实例。

实现

  • 定义接口
/**
 * 定义接口
 */
public interface ICourse {
    /**
     * 定义方法
     */
    void record();
}
  • 定义实现类
/**
 * 定义 JavaCourse 类。实现接口
 */
public class JavaCourse implements ICourse {
    @Override
    public void record() {
        System.out.println("Java 课程");
    }
}

/**
 * 定义 PhpCourse 类。实现接口
 */
public class PhpCourse implements ICourse {
    @Override
    public void record() {
        System.out.println("Php 课程");
    }
}
  • 定义工厂类
/**
 * 定义工厂类,实现对应方法调用
 */
public class CourseFactory {

    public ICourse create(String name) {
        if ("java".equals(name)) {
            return new JavaCourse();
        } else if ("php".equals(name)) {
            return new PhpCourse();
        } else {
            return null;
        }
    }
}
  • 测试方法
public class SimpleFactoryTest {
    public static void main(String[] args) {
        CourseFactory courseFactory = new CourseFactory();

        ICourse java = courseFactory.create("java");
        java.record();

        ICourse php = courseFactory.create("php");
        php.record();
    }
}

优缺点

  • 优点

对客户端隐藏相关细节,只关注结果。

  • 缺点

工厂类的职责过重,不利于扩展复杂的产品结构。

工厂方法

定义

定义一个用于创建对象的接口,让子类决定实例化哪一个类。

实现

  • 定义抽象类
/**
 * 定义抽象类
 */
public abstract class Product {
    /**
     * 定义公共接口方法
     */
    public void publicMethod() {
        System.out.println("这是一个公共接口");
    }

    /**
     * 声明抽象方法
     */
    public abstract void abstractMethod();
}
  • 定义实现类
/**
 * 定义具体的类,实现抽线类 Product
 */
public class ConcreteProduct extends Product {
    @Override
    public void abstractMethod() {
        System.out.println("具体类:ConcreteProduct");
    }
}

/**
 * 定义具体的类,实现抽线类 Product
 */
public class AbstractProduct extends Product {
    @Override
    public void abstractMethod() {
        System.out.println("具体类:AbstractProduct");
    }
}
  • 定义抽象工厂
/**
 * 抽象工厂类,为工厂具体实现类提供扩展
 */
public abstract class Factory {
    public abstract  <T extends Product> T createProduct(Class<T> t);
}
  • 定义抽象工厂的实现类
/**
 * 抽象工厂类的实现
 */
public class ConcreteFactory extends Factory {
    @Override
    public <T extends Product> T createProduct(Class<T> t) {
        Product product = null;
        try {
            product = (T)Class.forName(t.getName()).newInstance();
        } catch (Exception e) {
            System.out.println("创建失败");
        }
        return (T)product;
    }
}
  • 测试类
public class FactoryMethodTest {
    public static void main(String[] args) {
        // 实例化工厂
        Factory factory = new ConcreteFactory();
        // 实例 ConcreteProduct 类
        ConcreteProduct concreteProduct = factory.createProduct(ConcreteProduct.class);
        concreteProduct.publicMethod();
        concreteProduct.abstractMethod();

        // 实例 AbstractProduct 类
        AbstractProduct abstractProduct = factory.createProduct(AbstractProduct.class);
        abstractProduct.publicMethod();
        abstractProduct.abstractMethod();
    }
}

如果去掉抽象工厂类 Factory ,那么就成了简单工厂模式,代码如下:

/**
* 简单工厂实现类
*/
public class ConcreteFactory {
  public static <T extends Product> T createProduct(Class<T> t) {
      Product product = null;
      try {
          product = (T)Class.forName(t.getName()).newInstance();
      } catch (Exception e) {
          System.out.println("创建失败");
      }
      return (T)product;
  }
}

优缺点

  • 优点

程序的可扩展性比较高。

  • 缺点

系统复杂性抽象性难道增加。

动态代理

定义

通过代理对象来调用目标类。

实现

静态代理

  • 定义接口
/**
 * 定义接口
 */
public interface UserService {
    void saveUser();
}
  • 定义实现类
/**
 * 实现接口,实现类不做任何的操作
 */
public class UserServiceImpl implements UserService {
    @Override
    public void saveUser() {
        System.out.println("用户保存方法");
    }
}
  • 定义代理类
/**
 * 定义代理对象,这里执行对代理对象的操作
 * 如果后续增加新的操作,只需要修改对应的实现类即可
 */
public class UserProxy {

    private final UserService userService;

    public UserProxy(UserService userService) {
        this.userService = userService;
    }

    public void saveUser() {
        userService.saveUser();
    }
}
  • 定义测试类
public class StaticProxyTest {
    public static void main(String[] args) {
        // 实例化对象 UserService
        UserService userService = new UserServiceImpl();
        // 实例化代理对象 UserProxy
        UserProxy userProxy = new UserProxy(userService);
        userProxy.saveUser();
    }
}

动态代理

JDK 动态代理
  • 引入 pom.xml 文件
<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>3.2.5</version>
</dependency>
  • 定义接口
/**
 * 定义接口
 */
public interface UserService {
    void saveUser();
}
  • 定义实现类
/**
 * 实现接口,实现类不做任何的操作
 */
public class UserServiceImpl implements UserService {
    @Override
    public void saveUser() {
        System.out.println("用户保存方法");
    }
}
  • 定义代理类
public class UserHandler implements InvocationHandler {

    private final UserService userService;

    public UserHandler(UserService userService) {
        this.userService = userService;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        return method.invoke(userService, args);
    }
}
  • 定义测试类
public class DynamicProxyJDKTest {
    public static void main(String[] args) {
        // 实例化对象
        UserService userService = new UserServiceImpl();
        // 实例化代理类对象
        UserHandler userHandler = new UserHandler(userService);

        ClassLoader classLoader = userService.getClass().getClassLoader();
        Class<?>[] interfaces = userService.getClass().getInterfaces();
        UserService userProxy = (UserService) Proxy.newProxyInstance(classLoader, interfaces, userHandler);
        userProxy.saveUser();
    }
}
CGLIB 动态代理
  • 定义接口
/**
 * 定义接口
 */
public interface UserService {
    void saveUser();
}
  • 定义实现类
/**
 * 实现接口,实现类不做任何的操作
 */
public class UserServiceImpl implements UserService {
    @Override
    public void saveUser() {
        System.out.println("用户保存方法");
    }
}

/**
 * OrderServiceImpl 类没有实现任何接口
 */
public class OrderServiceImpl {
    public void saveOrder() {
        System.out.println("订单保存方法");
    }
}
  • 定义代理类
public class UserInterceptor implements MethodInterceptor {
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        return methodProxy.invokeSuper(o, objects);
    }
}
  • 定义测试类
public class DynamicProxyCglibTest {
    public static void main(String[] args) {
        // 定义动态代理类
        Enhancer enhancerUser = new Enhancer();
        enhancerUser.setSuperclass(UserServiceImpl.class);
        enhancerUser.setCallback(new UserInterceptor());
        // 定义被代理的对象
        UserService userService = (UserService) enhancerUser.create();
        userService.saveUser();

        // 定义动态代理类
        Enhancer enhancerOrder = new Enhancer();
        enhancerOrder.setSuperclass(OrderServiceImpl.class);
        enhancerOrder.setCallback(new UserInterceptor());
        // 定义被代理的对象
        OrderServiceImpl orderService = (OrderServiceImpl) enhancerOrder.create();
        orderService.saveOrder();

    }
}

优缺点

  • 优点

JDK 动态代理,原生 JAVA 支持,不需要任何外部依赖。

CGLIB 动态代理通过继承的方式,无论目标对象有没有实现接口都可以代理。

  • 缺点

JDK 动态代理只支持接口的动态代理。

CGLIB 需要引入外部依赖,无法处理 final 的情况。

适配器模式

定义

将一个类的接口转换成另外一个接口。

实现

  • 定义需要适配的类
/**
 * 需要适配的类
 */
public class AdapterClass {

    public void request() {
        System.out.println("这是需要适配的类");
    }
}
  • 定义目标接口
/**
 * 目标接口
 */
public interface ObjectiveInterface {
    void objectRequest();
}
  • 定义适配的类
/**
 * 定义适配器类
 */
public class AdapterClassInterface extends AdapterClass implements ObjectiveInterface {
    @Override
    public void objectRequest() {
        super.request();
    }
}
  • 定义测试类
public class AdapterModelTest {
    // 对目标接口的具体实现
    public void requestAdapter(ObjectiveInterface objectiveInterface) {
        objectiveInterface.objectRequest();
    }
    public static void main(String[] args) {
        AdapterModelTest adapterModelTest = new AdapterModelTest();
        AdapterClassInterface adapterClassInterface = new AdapterClassInterface();
        // 通过适配器实现调用
        adapterModelTest.requestAdapter(adapterClassInterface);
    }
}

优缺点

  • 优点

程序的高扩展和复用性增加。

  • 缺点

过多的适配器使用会使得系统的复杂度增加。

模板模式

定义

一个抽象类中有一个主方法,同时有多个子方法。定义其它的类,继承这个抽象类,重写抽象方法,通过调用抽象类实现子类的调用。

实现

  • 定义抽象类
/**
 * 定义抽象类
 */
public abstract class TemplateClass {
    // 定义接口
    public abstract void initialize();
    public abstract void start();
    public abstract void end();

    // 定义模板方法
    public final void template() {
        initialize();
        start();
        end();
    }
}
  • 定义实现类
/**
 * 定义实现类 UserService,重写抽象类的方法
 */
public class UserService extends TemplateClass {

    @Override
    public void initialize() {
        System.out.println("user initialize");
    }

    @Override
    public void start() {
        System.out.println("user start");
    }

    @Override
    public void end() {
        System.out.println("user end");
    }
}

/**
 * 定义实现类 OrderService,重写抽象类的方法
 */
public class OrderService extends TemplateClass {

    @Override
    public void initialize() {
        System.out.println("order initialize");
    }

    @Override
    public void start() {
        System.out.println("order start");
    }

    @Override
    public void end() {
        System.out.println("order end");
    }
}
  • 定义测试类
public class TemplateModelTest {
    public static void main(String[] args) {
        TemplateClass templateUser = new UserService();
        templateUser.initialize();
        templateUser.start();
        templateUser.end();

        TemplateClass templateOrder = new OrderService();
        templateOrder.initialize();
        templateOrder.start();
        templateOrder.end();
    }
}

优缺点

  • 优点

封装的代码不需要改变,行为有子类控制,有利于代码维护。

  • 缺点

每一个不同实现都需要一个子类来实现,会增加系统的复杂度。

观察者模式

定义

定义对象间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖的对象皆得到通知并被自动更新。

实现

  • 定义观察者接口
/**
 * 定义观察者接口 ObserverInterface
 */
public interface ObserverInterface {
    void response();
}
  • 实现观察者接口
/**
 * 实现观察者接口
 */
public class ObserverClass implements ObserverInterface {
    @Override
    public void response() {
        System.out.println("观察者 ObserverClass 收到了消息 ......");
    }
}

/**
 * 实现观察者接口
 */
public class WatchClass implements ObserverInterface {
    @Override
    public void response() {
        System.out.println("观察者 WatchClass 收到了消息 ......");
    }
}
  • 定义被观察者接口
/**
 * 定义被观察者接口 ObservedInterface
 */
public interface ObservedInterface {
    void add(ObserverInterface observer);
    void notice();
    void change();
}
  • 实现被观察者接口
/**
 * 实现被观察者接口
 */
public class ObservedClass implements ObservedInterface {
    public Vector<ObserverInterface> vector;

    @Override
    public void add(ObserverInterface observer) {
        if (vector == null) {
            vector = new Vector<>();
        }
        this.vector.add(observer);
    }

    @Override
    public void notice() {
        for (ObserverInterface observer : vector) {
            observer.response();
        }
    }

    @Override
    public void change() {
        System.out.println("观察者发生了改变 ......");
        notice();
    }
}
  • 定义测试类
public class ObserverModelTest {
    public static void main(String[] args) {
        ObservedInterface observed = new ObservedClass();
        observed.add(new ObserverClass());
        observed.add(new WatchClass());
        observed.change();
    }
}

优缺点

  • 优点

完全的开闭原则,支持广播通讯。

  • 缺点

无法规避循环依赖导致的系统崩溃。

装饰器模式

定义

在不改变原有对象的基础上,提供了扩展对象功能的方案。

实现

  • 定义被装饰对象的接口
/**
 * 定义被装饰对象的接口
 */
public interface DecoratorInterface {
    void execute();
}
  • 实现被装饰对象的接口
/**
 * 实现被装饰对象接口
 */
public class DecoratorClass implements DecoratorInterface {
    @Override
    public void execute() {
        System.out.println("这是一个被装饰的类");
    }
}
  • 定义装饰器类
/**
 * 定义装饰器类 Decorator
 */
public class Decorator implements DecoratorInterface {

    public DecoratorInterface decoratorInterface;

    public Decorator(DecoratorInterface decoratorInterface) {
        this.decoratorInterface = decoratorInterface;
    }

    @Override
    public void execute() {
        decoratorInterface.execute();
    }
}
  • 创建具体的装饰器类
/**
 * 创建具体的装饰器类
 */
public class DecoratorConcrete extends Decorator{
    public DecoratorConcrete(DecoratorInterface decoratorInterface) {
        super(decoratorInterface);
    }

    public void before() {
        System.out.println("DecoratorConcrete 前操作");
    }

    public void after() {
        System.out.println("DecoratorConcrete 后操作");
    }

    public void execute() {
        before();
        decoratorInterface.execute();
        after();
    }
}
  • 定义测试类
public class DecoratorModelTest {
    public static void main(String[] args) {
        DecoratorInterface decoratorInterface = new DecoratorClass();
        Decorator decorator = new DecoratorConcrete(decoratorInterface);
        decorator.execute();
    }
}

优缺点

  • 优点

比继承灵活,在不改变原有对象的情况下给对象进行扩展。

  • 缺点

会增加系统的复杂性。

策略模式

定义

对象有某个行为,在不同的场景中,该行为有不同的实现算法。

实现

  • 定义策略模式接口
/**
 * 定义策略模式接口
 */
public interface StrategyInterface {
    void execute();
}
  • 定义策略模式实现类
/**
 * 策略接口实现类 StrategyClass
 */
public class StrategyClass implements StrategyInterface {
    @Override
    public void execute() {
        System.out.println("这是策略接口实现类 StrategyClass");
    }
}

/**
 * 策略接口实现类 StrategyClass
 */
public class StrategicClass implements StrategyInterface {
    @Override
    public void execute() {
        System.out.println("这是策略接口实现类 StrategicClass");
    }
}
  • 定义策略器的上下文
/**
 * 定义策略器的上下文
 */
public class StrategyContext {
    private final StrategyInterface strategyInterface;

    public StrategyContext(StrategyInterface strategyInterface) {
        this.strategyInterface = strategyInterface;
    }

    public void method() {
        strategyInterface.execute();
    }
}
  • 定义测试类
public class StrategyModelTest {
    public static void main(String[] args) {
        StrategyContext strategyContext = new StrategyContext(new StrategyClass());
        strategyContext.method();

        StrategyContext strategyContexts = new StrategyContext(new StrategicClass());
        strategyContexts.method();
    }
}

优缺点

  • 优点

代码耦合性较低,扩展比较方便。

  • 缺点

策略的增加会加重系统的复杂性。


文章作者: L Q
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 L Q !
  目录