设计模式(工厂模式,模板方法模式,单例模式)

avatar
作者
猴君
阅读量:1

单例模式:

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

单例模式举例:

  1. 配置信息类:用于存储应用程序的全局配置信息,例如数据库连接信息、日志配置等。

  2. 日志类:用于记录应用程序运行时的日志信息,确保在整个应用程序中只有一个日志实例

  3. 线程池类:在多线程环境下,使用单例模式可以确保只有一个线程池实例,提高资源利用率和性能。

单例模式饿汉式:

代码:

public class Singleton {     /*       防止外界随意使用构造方法new对象,我们需要将构造私有化      */     private Singleton(){      }      /*        为了赶紧new对象,我们new对象的时候变成静态的,让其随着类的加载而加载        为了不让外界随便使用类名调用此静态对象,我们将其变成private      */     private static Singleton singleton = new Singleton();      /*        为了将内部new出来的对象给外界        我们可以定义 一个方法,将内部的对象返回给外界      */     public static Singleton getSingleton(){         return singleton;     } }

将new出来的对象设置为静态属性,这样随着类的加载而加载

单例模式懒汉式:

public class Singleton1 {     /*       防止外界随意使用构造方法new对象,我们需要将构造私有化     */     private Singleton1() {      }      /*        懒汉式,不着急new对象      */     private static Singleton1 singleton1 = null;      /*        为了将内部new出来的对给外界        定义一个方法,将内部new出来的对返回      */     public static Singleton1 getSingleton1() {         //如果singleton1不是null就没必要抢锁了,直接返回,是null再抢锁         if (singleton1==null){             synchronized (Singleton1.class){                 if (singleton1 == null) {                     singleton1 = new Singleton1();                 }             }         }         return singleton1;     } }

懒汉式就不着急new对象了,留了一个公共的接口,你想new的时候就new即可

懒汉式的线程不安全问题:

这也是懒汉式的一个缺点:如果没有加锁的代码:

public static Singleton1 getSingleton1() {                 if (singleton1 == null) {                     singleton1 = new Singleton1();                 }                      return singleton1;     }

这很容易引发线程不安全问题,我们设想有两个线程,第一个线程需要这个singleton1这个对象,进入了if判断,不过这个时候CPU将线程切换给了第二个线程,那这个时候,第二个线程也进入了if判断,然后CPU再切换会第一个线程,线程一创建了对象,但是我们知道线程二也进入了if判断,它也能创建对象,这就导致了线程不安全问题

饿汉式和懒汉式区别:

1:创建的时间不一样:饿汉式是在类加载过程中就创建了实例,而饿汉式是被调用的时候才创建实例

2:线程安全问题:饿汉式不存在什么线程安全,类加载的时候我就创建了,而且不能改,不可能又线程安全问题,反观饿汉式就有线程安全问题

在Spring中的单例模式的体现:

 在 Spring 源码中,最常见的使用单例设计模式的场景就是在创建 Bean 实例时使用单例模式。Spring 容器默认情况下会将所有的 Bean 对象作为单例对象进行管理,这样可以节省资源,提高性能。

public class DefaultSingletonBeanRegistry implements SingletonBeanRegistry {          private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);          @Override     public Object getSingleton(String beanName) {         return this.singletonObjects.get(beanName);     }          @Override     public void registerSingleton(String beanName, Object singletonObject) {         synchronized (this.singletonObjects) {             Object oldObject = this.singletonObjects.get(beanName);             if (oldObject != null) {                 throw new IllegalStateException("Could not register object [" + singletonObject + "] under bean name '" + beanName +                         "': there is already object [" + oldObject + "] bound");             }             this.singletonObjects.put(beanName, singletonObject);         }     }          // 其他方法... }

这个是我在鱼皮公众号上看到的,我第一次看到这段话的时候,也是有一个疑问

创建 Bean 实例是饿汉式还是懒汉式?

然后我问了GPT:

Spring容器在启动时会预先实例化所有单例Bean对象,这样可以避免懒汉式中可能存在的线程安全问题,确保在需要使用Bean时能够立即获取到对象实例。这种预先实例化的方式类似于饿汉式,但并不完全等同于饿汉式的实现方式。


模板方法模式:

定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。明确了一部分功能,而另一部分功能不明确。需要延伸到子类中实现

 这个我觉得就非常好理解:

我们平常都在写的接口或者抽象类都是这种思想

比如我们要去餐馆吃饭,我们每次餐馆都要点菜买单

不过我们去不同的餐馆点的菜都不一样

就可以把餐馆抽象成一个类,不同的餐馆都是实现类

上一段代码:

public abstract class Hotel {     public void eat(){         System.out.println("点菜");         eatCai();         System.out.println("买单");     }     public abstract void eatCai(); }  public class QuanJuDe extends Hotel{     @Override     public void eatCai() {         System.out.println("薄饼");         System.out.println("放鸭肉");         System.out.println("酱");         System.out.println("葱丝");         System.out.println("黄瓜丝");         System.out.println("卷着吃");     } } public class ZhangLiang extends Hotel{     @Override     public void eatCai() {         System.out.println("调麻酱");         System.out.println("放辣椒油");         System.out.println("倒到大碗中吃");     } }  public class Test01 {     public static void main(String[] args) {         QuanJuDe quanJuDe = new QuanJuDe();         quanJuDe.eat();          System.out.println("================");          ZhangLiang zhangLiang = new ZhangLiang();         zhangLiang.eat();     } }

 


工厂模式:

工厂模式是一种创建型设计模式,其主要目的是封装对象的实例化过程,将对象的创建和使用分离。通过工厂模式,可以实现更灵活、可扩展的对象创建方式,同时降低代码的耦合度。

工厂模式分为下面三种:简单工厂模式,工厂方法模式,抽象工厂模式


还没有工厂的时候:我们如果需要车,我们得自己去造车 自己去 new 对象
public class BMW320 { 	public BMW320(){ 		System.out.println("制造-->BMW320"); 	} }   public class BMW523 { 	public BMW523(){ 		System.out.println("制造-->BMW523"); 	} }   public class Customer { 	public static void main(String[] args) { 		BMW320 bmw320 = new BMW320(); 		BMW523 bmw523 = new BMW523(); 	} }
简单工厂模式:简单工厂的时候,我们已经有了简单的工厂,我们不用自己去造车了

我们可以告诉工厂,我们需要这个这个车,工厂造好给我们即可

有一个工厂类,我们去调用工厂类的造车方法造车

产品类:

// 产品接口 interface Product {     void doSomething(); }  // 具体产品类 A class ConcreteProductA implements Product {     @Override     public void doSomething() {         System.out.println("Product A is doing something.");     } }  // 具体产品类 B class ConcreteProductB implements Product {     @Override     public void doSomething() {         System.out.println("Product B is doing something.");     } }

工厂类: 

// 简单工厂类 class SimpleFactory {     public static Product createProduct(String type) {         if ("A".equals(type)) {             return new ConcreteProductA();         } else if ("B".equals(type)) {             return new ConcreteProductB();         }         return null;     } }

客户端代码:

// 客户端代码 public class Main {     public static void main(String[] args) {         Product productA = SimpleFactory.createProduct("A");         productA.doSomething();          Product productB = SimpleFactory.createProduct("B");         productB.doSomething();     } }
工厂方法模式:到了这个时候,随着车型的增多,一个工厂已经不能生成这么多车型了

就需要工厂分类:每个工厂生成一种型号的车

有一个工厂抽象类,生成各种型号的车的工厂去继承里面的造车方法

再有一个车的抽象类,不同的车去继承里面的方法
 

 

// 产品接口 interface Product {     void doSomething(); }  // 具体产品类 A class ConcreteProductA implements Product {     @Override     public void doSomething() {         System.out.println("Product A is doing something.");     } }  // 具体产品类 B class ConcreteProductB implements Product {     @Override     public void doSomething() {         System.out.println("Product B is doing something.");     } }  // 工厂接口 interface Factory {     Product createProduct(); }  // 具体工厂类 A,负责创建产品 A class ConcreteFactoryA implements Factory {     @Override     public Product createProduct() {         return new ConcreteProductA();     } }  // 具体工厂类 B,负责创建产品 B class ConcreteFactoryB implements Factory {     @Override     public Product createProduct() {         return new ConcreteProductB();     } }  // 客户端代码 public class Main {     public static void main(String[] args) {         Factory factoryA = new ConcreteFactoryA();         Product productA = factoryA.createProduct();         productA.doSomething();          Factory factoryB = new ConcreteFactoryB();         Product productB = factoryB.createProduct();         productB.doSomething();     } }
抽象工厂模式:这个时候的需求就已经很复杂了,

每个车需要的零件都不同,比如车1和车2分别是两个不同的型号,车1需要空调a和发动机b,车2需要空调b和发动机b

这个时候就设计到了一个产品族,就是空调,发动机或者其它产品合在一起就是一个产品族

有点像我们日常生活中开店,比如我们开冷冻产品店,那我们不可能一个人去准备所有的冷冻产品,我肯定是去找对应的供货商,比如火锅料的供货商,鱿鱼的供货商,饮料的供货商,然后整合到我这个冷冻店再去销售

所以翻译成Java语言就是,空调是一个抽象类,发动机是一个抽象类,多个抽象类,一个工厂抽象类,不同型号的车是一个类都去继承这个工厂,你需要什么零件就去这个工厂里面配这个零件。

// 产品族接口 interface AbstractProductA {     void doSomething(); }  interface AbstractProductB {     void doSomething(); }  // 具体产品类 A1 class ConcreteProductA1 implements AbstractProductA {     @Override     public void doSomething() {         System.out.println("Product A1 is doing something.");     } }  // 具体产品类 B1 class ConcreteProductB1 implements AbstractProductB {     @Override     public void doSomething() {         System.out.println("Product B1 is doing something.");     } }  // 具体产品类 A2 class ConcreteProductA2 implements AbstractProductA {     @Override     public void doSomething() {         System.out.println("Product A2 is doing something.");     } }  // 具体产品类 B2 class ConcreteProductB2 implements AbstractProductB {     @Override     public void doSomething() {         System.out.println("Product B2 is doing something.");     } }  // 抽象工厂接口 interface AbstractFactory {     AbstractProductA createProductA();     AbstractProductB createProductB(); }  // 具体工厂类 1 class ConcreteFactory1 implements AbstractFactory {     @Override     public AbstractProductA createProductA() {         return new ConcreteProductA1();     }      @Override     public AbstractProductB createProductB() {         return new ConcreteProductB1();     } }  // 具体工厂类 2 class ConcreteFactory2 implements AbstractFactory {     @Override     public AbstractProductA createProductA() {         return new ConcreteProductA2();     }      @Override     public AbstractProductB createProductB() {         return new ConcreteProductB2();     } }  // 客户端代码 public class Main {     public static void main(String[] args) {         AbstractFactory factory1 = new ConcreteFactory1();         AbstractProductA productA1 = factory1.createProductA();         AbstractProductB productB1 = factory1.createProductB();         productA1.doSomething();         productB1.doSomething();          AbstractFactory factory2 = new ConcreteFactory2();         AbstractProductA productA2 = factory2.createProductA();         AbstractProductB productB2 = factory2.createProductB();         productA2.doSomething();         productB2.doSomething();     } }

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!