Java设计模式---单例 工厂 代理模式

这篇具有很好参考价值的文章主要介绍了Java设计模式---单例 工厂 代理模式。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Java单例模式详解

一、引言

单例模式是设计模式中的一种,属于创建型模式。在软件工程中,单例模式确保一个类只有一个实例,并提供一个全局访问点。这种模式常用于那些需要频繁实例化然后引用,且创建新实例的开销较大的类,例如数据库连接池、缓存管理等。

二、单例模式定义

意图:保证一个类仅有一个实例,并提供一个访问它的全局访问点。

主要解决:一个全局使用的类频繁地创建与销毁所造成的资源浪费问题。

何时使用:当您想控制实例数目,节省系统资源的时候。

如何解决:判断系统是否已经有这个单例,如果有则返回,如果没有则创建。

关键代码:构造函数是私有的。

三、Java实现单例模式的几种方式

  1. 懒汉式(线程不安全)
public class Singleton {
    private static Singleton instance;

    private Singleton() {}

    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

这种方式在多线程环境下不能保证单例,因为多个线程可能同时进入if条件判断内部,导致创建多个实例。

  1. 懒汉式(线程安全,同步方法)
public class Singleton {
    private static Singleton instance;

    private Singleton() {}

    public static synchronized Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

通过在getInstance方法上加synchronized关键字使其变为同步方法,解决了多线程环境下的安全性问题,但每次获取实例都要进行同步,性能损耗较大。

  1. 懒汉式(线程安全,双重检查锁定 - DCL,推荐使用)
public class Singleton {
    private volatile static Singleton instance;

    private Singleton() {}

    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

双重检查锁定机制,首先判断实例是否存在,若不存在才进行同步处理,这样既保证了线程安全,又避免了每次都进行同步带来的性能损耗。

  1. 饿汉式(静态内部类)
public class Singleton {
    private Singleton() {}

    private static class SingletonHolder {
        private static final Singleton INSTANCE = new Singleton();
    }

    public static Singleton getInstance() {
        return SingletonHolder.INSTANCE;
    }
}

静态内部类的方式在类加载时就完成了初始化,既保证了线程安全,也避免了同步带来的性能影响,同时也能保证单例对象的唯一性。

  1. 枚举式(最安全,推荐使用)
public enum Singleton {
    INSTANCE;

    public void whateverMethod() {
        // ...
    }
}

枚举类型的单例模式不仅能防止反射和反序列化的攻击,而且写法简单,易于理解,是实现单例的最佳选择。

四、注意事项

  • 单例模式虽然能节约系统资源,但也可能造成全局状态过多,增加系统的复杂度。
  • 对于可序列化类的单例模式,需要重写readResolve方法以防止反序列化时生成新的对象。

以上就是Java单例模式的详细解读,实际开发过程中应根据具体场景选择合适的实现方式。

Java工厂设计模式详解

一、引言

工厂模式是面向对象设计模式中的一种,主要用来解决对象创建的问题,封装了对象的创建过程,使客户端不需要知道具体的实现类就能创建所需的对象。根据抽象程度的不同,工厂模式分为简单工厂模式、工厂方法模式和抽象工厂模式。

二、工厂模式分类与定义

  1. 简单工厂模式(Simple Factory Pattern)

意图:提供一个用于创建对象的接口,让子类决定实例化哪一个类。

结构:由一个工厂类负责创建不同类的产品对象。

// 简单工厂角色
public class ShapeFactory {
    public Shape getShape(String type) {
        if ("CIRCLE".equals(type)) {
            return new Circle();
        } else if ("RECTANGLE".equals(type)) {
            return new Rectangle();
        } else if ("SQUARE".equals(type)) {
            return new Square();
        } else {
            throw new IllegalArgumentException("Invalid shape type");
        }
    }
}

// 抽象产品角色
abstract class Shape {
    abstract void draw();
}

// 具体产品角色
class Circle extends Shape {
    @Override
    void draw() {
        System.out.println("Drawing a circle...");
    }
}

// 其他具体产品类...
  1. 工厂方法模式(Factory Method Pattern)

意图:定义一个用于创建对象的接口,但让子类决定实例化哪个类。工厂方法使一个类的实例化延迟到其子类。

结构:定义一个创建产品对象的接口,让子类决定生产什么产品。

// 抽象工厂角色
interface ShapeFactory {
    Shape createShape();
}

// 具体工厂角色
class CircleFactory implements ShapeFactory {
    @Override
    Shape createShape() {
        return new Circle();
    }
}

// 其他具体工厂类...

// 抽象产品角色
abstract class Shape {
    abstract void draw();
}

// 具体产品角色
class Circle extends Shape {
    @Override
    void draw() {
        System.out.println("Drawing a circle...");
    }
}

// 其他具体产品类...
  1. 抽象工厂模式(Abstract Factory Pattern)

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

结构:提供一个接口,用于创建相关或相互依赖对象家族的一系列对象,而无需指定具体类。

// 抽象工厂角色
interface ColorFactory {
    Color getColor();
}

interface ShapeFactory {
    Shape getShape();
}

// 具体工厂角色
class RedColorFactory implements ColorFactory {
    @Override
    Color getColor() {
        return new RedColor();
    }
}

class CircleShapeFactory implements ShapeFactory {
    @Override
    Shape getShape() {
        return new Circle();
    }
}

// 抽象产品角色
interface Color {
    void fill();
}

interface Shape {
    void draw();
}

// 具体产品角色
class RedColor implements Color {
    @Override
    void fill() {
        System.out.println("Filling with red color...");
    }
}

class Circle implements Shape {
    @Override
    void draw() {
        System.out.println("Drawing a circle...");
    }
}

// 其他具体产品类...

三、工厂模式优缺点

  • 优点

    • 将对象的创建和使用分离,使得系统耦合度降低。
    • 提高代码的可扩展性,增加新的产品类型时只需要添加新的工厂或产品类,不影响已有的代码。
  • 缺点

    • 当产品种类较多时,会导致类爆炸,因为每新增一种产品就需要新增对应的工厂类。
    • 违反开闭原则,如果需要新增一个产品,除了新增产品类外,可能还需要修改工厂类或抽象工厂类。

四、适用场景

  • 当一个类不知道它所必须创建的对象的确切类时。
  • 当一个类希望它的使用者指定它所创建的对象类型时。
  • 当类将职责委托给多个帮助子类中的某一个,并且用户希望可以动态地决定这个职责委托给哪个子类时。

通过上述介绍,您应该对Java中的工厂设计模式有了较为深入的理解。在实际开发中,可以根据需求选择合适的工厂模式来组织代码,提高程序的灵活性和可维护性。

Java代理设计模式详解

一、引言

代理设计模式(Proxy Design Pattern)是软件设计中常用的行为型设计模式之一,它为其他对象提供一个代理以控制对这个对象的访问。在Java编程中,代理模式的主要目的是为了在不改变原始目标类代码的基础上,通过引入一个额外的代理类来扩展或增强原有对象的功能。

1.1 定义

代理模式定义如下:
代理模式:给某个对象提供一个代理,并由代理对象控制对原对象的引用。代理模式能够在客户端与目标对象之间增加一层间接层,从而实现对目标对象功能的增强、控制或者过滤。

1.2 模式结构

  • Subject(抽象主题): 定义了真实主题和代理主题的公共接口,这样代理可以作为真实主题的替代品。
  • RealSubject(真实主题): 实际完成工作的类,也是代理所代表的真实对象。
  • Proxy(代理): 保存一个对真实主题的引用,并且提供一个与真实主题相同的接口以便于在任何时候都可以将请求转发给真实主题处理;同时,在转发请求前或后执行附加操作。

1.3 应用场景

  • 访问控制:如权限验证,只有经过代理对象确认之后才能访问真实对象的方法。
  • 功能增强:例如在方法调用前后添加日志记录、事务管理等。
  • 虚拟代理:延迟加载,如图片预加载、数据库连接池中的连接对象创建等。
  • 远程代理:用于分布式系统中,代理对象负责与远程对象通信。
  • 缓存代理:缓存结果以提高性能,当请求数据时先检查代理是否有缓存的结果。
  • AOP(面向切面编程):Spring框架AOP模块底层就使用了动态代理技术。

二、Java中的代理实现方式

在Java中,代理主要分为两种类型:

2.1 静态代理

静态代理是在编译期间就已经确定代理类,代理类和被代理类的关系在代码中硬编码。

public interface Subject {
    void request();
}

public class RealSubject implements Subject {
    @Override
    public void request() {
        // 真实对象的实际业务逻辑
    }
}

public class ProxySubject implements Subject {
    private RealSubject realSubject;

    public ProxySubject(RealSubject realSubject) {
        this.realSubject = realSubject;
    }

    @Override
    public void request() {
        beforeRequest(); // 在调用实际方法前的操作
        realSubject.request();
        afterRequest(); // 在调用实际方法后的操作
    }

    private void beforeRequest() {
        // 添加前置逻辑,比如权限校验
    }

    private void afterRequest() {
        // 添加后置逻辑,比如日志记录
    }
}

2.2 动态代理

Java提供了动态生成代理类的技术,主要有两种实现机制:

2.2.1 JDK动态代理

JDK动态代理基于接口实现,通过java.lang.reflect.Proxy类和InvocationHandler接口。

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class JdkProxy implements InvocationHandler {
    private Object target;

    public Object bind(Object target) {
        this.target = target;
        return Proxy.newProxyInstance(
                target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                this
        );
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        beforeInvoke(method);
        Object result = method.invoke(target, args);
        afterInvoke(method);
        return result;
    }

    private void beforeInvoke(Method method) {
        // 前置处理
    }

    private void afterInvoke(Method method) {
        // 后置处理
    }
}

// 使用示例
RealSubject realSubject = new RealSubject();
Subject proxy = (Subject) new JdkProxy().bind(realSubject);
proxy.request();
2.2.2 CGLIB代理

CGLIB库是一个强大的高性能代码生成库,可以在运行期扩展Java类与实现Java接口。它可以创建出一个被代理类的子类,因此不需要接口也能进行代理。CGLIB常用于Spring AOP框架中,对于没有实现接口的目标类也能提供代理支持。

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class CglibProxy implements MethodInterceptor {
    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        beforeInvoke(method);
        Object result = proxy.invokeSuper(obj, args);
        afterInvoke(method);
        return result;
    }

    private void beforeInvoke(Method method) {
        // 前置处理
    }

    private void afterInvoke(Method method) {
        // 后置处理
    }

    public Object createProxy(Class<?> clazz) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(clazz);
        enhancer.setCallback(this);
        return enhancer.create();
    }

    // 使用示例
    RealSubject realSubject = (RealSubject) new CglibProxy().createProxy(RealSubject.class);
    ((Subject) realSubject).request();
}

// 注意:这里假设RealSubject并未实现任何接口

三、总结

Java代理设计模式是一种重要的设计思想,它帮助开发者在不影响原始类的情况下,对类的行为进行扩展和控制。在实际开发中,无论是通过静态代理还是动态代理,都能在很多场合发挥重要作用,尤其是在框架设计、服务治理、性能优化以及AOP等领域得到广泛应用。学习并掌握代理模式有助于提升代码的灵活性和可维护性。文章来源地址https://www.toymoban.com/news/detail-820852.html

到了这里,关于Java设计模式---单例 工厂 代理模式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java与设计模式(1):简单工厂模式

    简单工厂模式(Simple Factory Pattern)是一种创建型设计模式,它提供了一种创建对象的方式,将对象的创建逻辑封装在一个工厂类中,而不是直接在客户端代码中进行实例化。 在简单工厂模式中,有三个主要角色: 工厂类(Factory Class):负责创建具体对象的工厂类。它通常包

    2024年02月11日
    浏览(49)
  • Java设计模式-简单工厂(Simple Factory)模式

    简单工厂(Simple Factory)模式,又称为静态工厂方法(Static Factory Method)模式。 由一个工厂类来创建具体产品,即创建具体类的实例。 简单工厂模式从概念上涉及三个角色: 抽象产品角色:是具体类的父类,规定了所有类的共同行为。一般是抽象类、或者接口。 具体产品角

    2024年02月16日
    浏览(39)
  • [设计模式Java实现附plantuml源码~创建型] 集中式工厂的实现~简单工厂模式

    前言: 为什么之前写过Golang 版的设计模式,还在重新写Java 版? 答:因为对于我而言,当然也希望对正在学习的大伙有帮助。Java作为一门纯面向对象的语言,更适合用于学习设计模式。 为什么类图要附上uml 因为很多人学习有做笔记的习惯,如果单纯的只是放一张图片,那

    2024年01月19日
    浏览(50)
  • C++面试:单例模式、工厂模式等简单的设计模式 & 创建型、结构型、行为型设计模式的应用技巧

            理解和能够实现基本的设计模式是非常重要的。这里,我们将探讨两种常见的设计模式:单例模式和工厂模式,并提供一些面试准备的建议。 目录 单例模式 (Singleton Pattern) 工厂模式 (Factory Pattern) 面试准备  1. 理解设计模式的基本概念 2. 掌握实现细节 3. 讨论优缺

    2024年02月01日
    浏览(67)
  • 【Java基础教程】(十五)面向对象篇 · 第九讲:抽象类和接口——定义、限制与应用的细节,初窥模板设计模式、工厂设计模式与代理设计模式~

    掌握 抽象类和接口的定义、使用、区别、常见设计模式; 抽象类是代码开发中的重要组成部分,利用抽象类可以明确地定义子类需要覆写的方法,这样相当于在语法程度上对子类进行了严格的定义限制,代码的开发也就更加标准。下面具体介绍抽象类的概念。 普通类可以直

    2024年02月16日
    浏览(48)
  • 【设计模式】单例模式、工厂方法模式、抽象工厂模式

    1. 单例模式 (Singleton Pattern): 场景: 在一个应用程序中,需要一个全局唯一的配置管理器,确保配置信息只有一个实例。 2. 工厂方法模式 (Factory Method Pattern): 场景: 创建一组具有相似功能但具体实现不同的日志记录器。 3. 抽象工厂模式 (Abstract Factory Pattern): 场景: 创建不同

    2024年01月15日
    浏览(61)
  • 结构型设计模式-单例模式/工厂模式/抽象工厂

    创建型设计模式-单例模式/工厂模式/抽象工厂 行为型设计模式:模板设计模式/观察者设计模式/策略设计模式 C#反射机制实现开闭原则的简单工厂模式 设计模式可以分为三种类型: 创建型设计模式、结构型设计模式和行为型设计模式 。 创建型设计模式:这些模式涉及到 对

    2024年02月11日
    浏览(53)
  • 设计模式(单例模式,工厂模式),线程池

    目录 什么是设计模式? 单例模式 饿汉模式 懒汉模式 工厂模式 线程池 线程池种类 ThreadPoolExcutor的构造方法: 手动实现一个线程池  计算机行业程序员水平层次不齐,为了 让所有人都能够写出规范的代码, 于是就有了设计模式, 针对一些典型的场景,给出一些典型的解决方案 单例

    2024年02月11日
    浏览(40)
  • 设计模式-创建型模式(单例、工厂、建造、原型)

    设计模式:软件设计中普遍存在(反复出现)的各种问题,所提出的解决方案。 面向对象三大特性:封装、继承、多态。 面向对象设计的SOLID原则: (1)开放封闭原则:一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。即软件实体应尽量在不修改原有代码的情

    2024年02月08日
    浏览(53)
  • Python入门【​编辑、组合、设计模式_工厂模式实现 、设计模式_单例模式实现、工厂和单例模式结合、异常是什么?异常的解决思路 】(十七)

    👏作者简介:大家好,我是爱敲代码的小王,CSDN博客博主,Python小白 📕系列专栏:python入门到实战、Python爬虫开发、Python办公自动化、Python数据分析、Python前后端开发 📧如果文章知识点有错误的地方,请指正!和大家一起学习,一起进步👀 🔥如果感觉博主的文章还不错的

    2024年02月14日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包