了解单例模式,工厂模式(简单易懂)

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

单例模式

  • 什么是单例? 系统运行期间有且仅有一个实例。
  • 为什么要有单例?系统中的一些对象只需要初始化一次即可,例如:KTV中的播放器或者初始化系统参数
  • 单例模式的要求:
    1. 一个类只有一个实例 只提供私有的构造器。
    private SingletonClass(){  }  
    
    1. 必须自己创建这个实例 定义该类的静态私有对象。
    private static SingletonClass single; 
    
    1. 必须自己向系统提供这个实例。 创建一个公共的静态方法,返回这个实例。
    public static SingletonClass getSingleton(){
        if(single==null){
            initSingleton();
        }
        return single;
    }
    

饿汉模式

不管你用不用我都给你创建这个实例。(官方语言:在类加载的时候创建这个实例)。 天然线程安全的,每个类中获取这个对象的耗时基本一样

下面是饿汉模式,使用静态内部类实现延迟加载。

public class SingleTon {
     
     private SingleTon() {
          
     }
     
     private static SingleTon singleTon;
    
        // 静态内部类
     public static class SingletonHelper{
          private static final SingleTon INSTANCE = new  SingleTon();
     }
     
     public static SingleTon getSingleTon() {
          singleTon = SingletonHelper.INSTANCE;
          return singleTon;
     }
     
}

懒汉模式

在你调用的时候才创建这个实例。不是线程安全,第一次获取此对象会耗时较多

  • 线程安全问题
  • double check 加锁优化
  • 编译器(JIT),CPU有可能对指令执行重新排序,导致使用到尚未初始化的实例(nullpointException),可以通过添加volatile关键字进行修饰,对于volatile修饰的字段,可以防止指令重排。
/**
 * 手写一个单例模式
 */
public class SingletonClass {

    // 1.私有化构造方法,收回创建实例的权限
    private SingletonClass(){

    }
    // 2.自己声明这个实例对象
    private volatile static SingletonClass singletonClass;

    // 3.向系统提供一个公共的方法,获取这个实例
    public static SingletonClass getInstance(){
        if(singletonClass==null){ // 为空才加同步锁,锁的范围越小越好
            synchronized (SingletonClass.class){
                if(singletonClass==null){ // 判断是否为空,防止实例化两次
                    singletonClass = new SingletonClass();
                    // 字节码 其中2和3可能存在重排的问题,如果3在前,在多线程的情况下会出现空指针
                    // 1.分配空间
                    // 2.初始化
                    // 3.引用赋值
                }
            }
        }
        return singletonClass;
    }

}

对比

  1. 线程安全:饿汉式天生就是线程安全的,懒汉式本身是非线程安全的。
  2. 资源加载和性能:饿汉式在类创建的同时就实例化一个静态对象出来,不管之后会不会使用这个单例,都会占据一定的内存,但是相应的,在第一次调用时速度也会更快,因为其资源已经初始化完成,而懒汉式顾名思义,会延迟加载,在第一次使用该单例的时候才会实例化对象出来,第一次调用时要做初始化,如果要做的工作比较多,性能上会有些延迟,之后就和饿汉式一样了。

工厂模式

  1. 什么是工厂? 将对象的创建过程封装在一个工厂类中,通过调用工厂类的方法来获取对象实例,而不需要直接使用new关键字来创建对象
  2. 为什么要有工厂模式? 工厂模式能够提供更好的代码组织结构、更好的封装性、更好的可扩展性和更好的解耦性,从而提高了代码的质量和可维护性
  3. 工厂模式的要求
  • 抽象产品:定义产品的共同接口或抽象类,描述产品的特征和行为。
  • 具体产品:实现抽象产品接口或继承抽象产品类,是工厂创建的目标对象。
// 抽象产品接口
public interface Product {
    void operation1();
    void operation2();
}

// 具体类A
public class ConcreteProductA implements Product {
    @Override
    public void operation1() {
        // 具体类A的操作1
    }

    @Override
    public void operation2() {
        // 具体类A的操作2
    }
}

// 具体类B
public class ConcreteProductB implements Product {
    @Override
    public void operation1() {
        // 具体类B的操作1
    }

    @Override
    public void operation2() {
        // 具体类B的操作2
    }
}
  • 抽象工厂:定义工厂的共同接口或抽象类,描述创建产品的方法。
  • 具体工厂:实现抽象工厂接口或继承抽象工厂类,负责实际创建产品的类。
  • 客户端:使用工厂创建产品的代码,通过工厂接口来创建所需的产品对象。
# 定义抽象工厂接口
class AbstractFactory:
    def create_product_a(self):
        pass

    def create_product_b(self):
        pass

# 实现具体的工厂类
class ConcreteFactory1(AbstractFactory):
    def create_product_a(self):
        return ProductA1()

    def create_product_b(self):
        return ProductB1()

class ConcreteFactory2(AbstractFactory):
    def create_product_a(self):
        return ProductA2()

    def create_product_b(self):
        return ProductB2()

# 定义产品接口
class AbstractProductA:
    def do_something(self):
        pass

class AbstractProductB:
    def do_something(self):
        pass

# 实现具体类
class ProductA1(AbstractProductA):
    def do_something(self):
        print("Product A1")

class ProductA2(AbstractProductA):
    def do_something(self):
        print("Product A2")

class ProductB1(AbstractProductB):
    def do_something(self):
        print("Product B1")

class ProductB2(AbstractProductB):
    def do_something(self):
        print("Product B2")

# 客户端代码
def client_code(factory):
    product_a = factory.create_product_a()
    product_b = factory.create_product_b()

    product_a.do_something()
    product_b.do_something()

# 使用具体工厂1
factory1 = ConcreteFactory1()
client_code(factory1)

# 使用具体工厂2
factory2 = ConcreteFactory2()
client_code(factory2)

简单工厂模式(Simple Factory Pattern)

简单工厂模式又称为静态工厂模式,它由一个工厂类来负责创建所有的产品对象。客户端只需要通过工厂类来创建产品对象,而不需要直接实例化具体产品类。简单工厂模式的核心是一个工厂类,它包含一个创建产品的方法,根据客户端传入的参数来决定创建哪种产品。

# 定义产品接口
class Product:
    def show(self):
        pass

# 定义具体类A,实现接口
class ConcreteProductA(Product):
    def show(self):
        print("Concrete Product A")

# 定义具体类B,实现接口
class ConcreteProductB(Product):
    def show(self):
        print("Concrete Product B")

# 定义静态工厂类
class StaticFactory:
    @staticmethod
    def create_product(product_type):
        if product_type == "A":
            return ConcreteProductA()
        elif product_type == "B":
            return ConcreteProductB()
        else:
            raise ValueError("Invalid product type")

# 客户端代码
if __name__ == "__main__":
    product_a = StaticFactory.create_product("A")  # 使用静态工厂类创建具体A
    product_a.show()  # 调用具体A的方法,输出 "Concrete Product A"

    product_b = StaticFactory.create_product("B")  # 使用静态工厂类创建具体B
    product_b.show()  # 调用具体B的方法,输出 "Concrete Product B"

工厂方法模式(Factory Method Pattern)

工厂方法模式将具体产品的创建过程延迟到子类中进行,每个具体产品都对应一个具体工厂类。客户端通过调用工厂方法来创建产品对象,工厂方法由子类实现,以创建对应的具体产品对象。

// 抽象类
public abstract class Product {
    public abstract void use();
}

// 具体类A
public class ConcreteProductA extends Product {
    @Override
    public void use() {
        System.out.println("使用具体类A");
    }
}

// 具体类B
public class ConcreteProductB extends Product {
    @Override
    public void use() {
        System.out.println("使用具体类B");
    }
}

// 抽象工厂类
public abstract class Factory {
    public abstract Product createProduct();
}

// 工厂类A
public class ConcreteFactoryA extends Factory {
    @Override
    public Product createProduct() {
        return new ConcreteProductA();
    }
}

// 工厂类B
public class ConcreteFactoryB extends Factory {
    @Override
    public Product createProduct() {
        return new ConcreteProductB();
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        Factory factoryA = new ConcreteFactoryA();
        Product productA = factoryA.createProduct();
        productA.use();
        
        Factory factoryB = new ConcreteFactoryB();
        Product productB = factoryB.createProduct();
        productB.use();
    }
}

抽象工厂模式(Abstract Factory Pattern)

抽象工厂模式提供了一种创建一系列相关或相互依赖对象的接口,而无需指定其具体类。抽象工厂模式包含一个抽象工厂接口,定义了用于创建产品对象的方法,具体工厂类实现了抽象工厂接口,并负责创建一系列相关产品。每个具体工厂类都对应于一个产品族,可以创建该产品族的多个产品。文章来源地址https://www.toymoban.com/news/detail-683420.html

// 定义抽象A
interface AbstractProductA {
    void operationA();
}

// 定义具体A1
class ConcreteProductA1 implements AbstractProductA {
    public void operationA() {
        System.out.println("Product A1");
    }
}

// 定义具体A2
class ConcreteProductA2 implements AbstractProductA {
    public void operationA() {
        System.out.println("Product A2");
    }
}

// 定义抽象B
interface AbstractProductB {
    void operationB();
}

// 定义具体B1
class ConcreteProductB1 implements AbstractProductB {
    public void operationB() {
        System.out.println("Product B1");
    }
}

// 定义具体B2
class ConcreteProductB2 implements AbstractProductB {
    public void operationB() {
        System.out.println("Product B2");
    }
}

// 定义抽象工厂
interface AbstractFactory {
    AbstractProductA createProductA();
    AbstractProductB createProductB();
}

// 定义具体工厂1
class ConcreteFactory1 implements AbstractFactory {
    public AbstractProductA createProductA() {
        return new ConcreteProductA1();
    }

    public AbstractProductB createProductB() {
        return new ConcreteProductB1();
    }
}

// 定义具体工厂2
class ConcreteFactory2 implements AbstractFactory {
    public AbstractProductA createProductA() {
        return new ConcreteProductA2();
    }

    public AbstractProductB createProductB() {
        return new ConcreteProductB2();
    }
}

// 调用方
public class Client {
    public static void main(String[] args) {
        // 创建工厂1
        AbstractFactory factory1 = new ConcreteFactory1();
        // 使用工厂1创建A和B
        AbstractProductA productA1 = factory1.createProductA();
        AbstractProductB productB1 = factory1.createProductB();
        productA1.operationA();
        productB1.operationB();

        // 创建工厂2
        AbstractFactory factory2 = new ConcreteFactory2();
        // 使用工厂2创建A和B
        AbstractProductA productA2 = factory2.createProductA();
        AbstractProductB productB2 = factory2.createProductB();
        productA2.operationA();
        productB2.operationB();
    }
}

对比

  • 简单工厂模式适用于对象种类较少且不会频繁变化的情况,工厂方法模式适用于对象种类较多且可能会有新产品增加的情况,抽象工厂模式适用于创建一组相关或相互依赖的产品且可能会有新的产品组合增加的情况。根据具体的需求和场景,选择适合的工厂模式可以提高代码的灵活性和可维护性。
  • 简单工厂模式是通过一个工厂类来创建所有的产品对象,根据不同的参数返回不同的具体产品对象。在多线程环境下,如果多个线程同时调用工厂的创建方法,可能会导致线程安全问题。解决这个问题的一种方式是在工厂类的创建方法上加锁,保证同一时间只有一个线程能够调用该方法。
  • 工厂方法模式将产品的创建延迟到子类中,每个产品有一个对应的工厂类来创建。在多线程环境下,每个线程独立使用各自的工厂类创建产品对象,不存在线程安全问题。不同的线程可以并发调用不同的工厂类创建产品,互不干扰。
  • 抽象工厂模式通过提供一个接口来创建一系列相关或依赖对象的家族,而不需要指定具体的类。在多线程环境下,如果多个线程同时调用不同的具体工厂类创建产品对象,也不存在线程安全问题。不同的线程可以并发调用不同的具体工厂类创建产品,互不干扰。

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

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

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

相关文章

  • C++面试:单例模式、工厂模式等简单的设计模式 & 创建型、结构型、行为型设计模式的应用技巧

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

    2024年02月01日
    浏览(49)
  • 实际开发中常用的设计模式--------单例模式(知识跟业务场景结合)-----小白也能看懂(通俗易懂版本)

    1.定义 单例模式是一种创建型设计模式,它通过使用私有构造函数和静态方法来确保一个类只有一个实例,并且提供全局访问点来获取该实例。 通过使用单例模式,我们可以方便地管理全局唯一的对象实例,并且避免了多次创建相同类型的对象所带来的资源浪费问题 2.业务场

    2024年02月12日
    浏览(31)
  • 【设计模式】使用 go 语言实现简单工厂模式

    最近在看《大话设计模式》,这本书通过对话形式讲解设计模式的使用场景,有兴趣的可以去看一下。 第一篇讲的是 简单工厂模式 ,要求输入两个数和运算符号,得到运行结果。 这个需求不难,难就难在类要怎么设计,才能达到可复用、维护性强、可拓展和灵活性高。 运

    2024年02月05日
    浏览(30)
  • 设计模式-简单工厂模式(静态工厂模式)java实现

    简单工厂模式根据所 提供的参数 数据返回几个可能类中的一个类的实例。通常返回的类都有一个公共的父类和公共的方法。   意图 提供一个类,负责根据一定的条件创建某一具体类的实例。同时使用工厂模式也是为了隐藏创建对象的过程 角色及其职责 (1)工厂(Creator)角色

    2024年02月13日
    浏览(34)
  • Java基础:简单工厂模式、工厂方法模式和抽象工厂模式综合概述

    简单工厂模式、工厂方法模式和抽象工厂模式是面向对象设计中用来实现对象创建灵活性的三种不同形式的工厂模式。它们各自有其特点、适用场景及优缺点。以下是它们之间的区别以及对应的适用场景,以及示例说明: 简单工厂模式 定义 : 简单工厂模式提供一个静态方法

    2024年04月25日
    浏览(22)
  • Java与设计模式(1):简单工厂模式

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

    2024年02月11日
    浏览(29)
  • Java 单例模式简单介绍

    何为单例模式 所谓类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类 只能存在一个对象实例 ,并且该类只提供一个取得其对象实例的方法。 实现思路 如果我们要让类在一个虚拟机中只能产生一个对象,我们首先必须将 类的构造器的访问权限 设置

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

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

    2024年01月15日
    浏览(42)
  • Java设计模式-简单工厂(Simple Factory)模式

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

    2024年02月16日
    浏览(27)
  • Go和Java实现简单工厂模式

    本文通过计算器案例来说明简单工厂模式的使用,使用Go语言和Java语言实现。 简单工厂模式对对象创建管理方式最为简单,只需要创建一个简单的工厂类然后在里面创建对象,该模式通过向工 厂传递类型来指定要创建的对象。 由于 Go 本身是没有构造函数的,一般而言我们采

    2024年02月15日
    浏览(23)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包