设计模式之单例模式和工厂模式(代码+举例)

文章目录

  • 开闭原则
  • 工厂模式
    • [1. 简单工厂模式(耦合度低)](#1. 简单工厂模式(耦合度低))
    • [2. 静态工厂模式(同上)](#2. 静态工厂模式(同上))
    • [3. 工厂方法(无耦合)](#3. 工厂方法(无耦合))
    • [4. 抽象工厂模式](#4. 抽象工厂模式)
  • 单例模式
    • [1. 饿汉式](#1. 饿汉式)
    • [2. 懒汉式](#2. 懒汉式)
      • [1.1 线程不安全](#1.1 线程不安全)
      • [1.2 Double Check 线程安全方式](#1.2 Double Check 线程安全方式)

前言:如果你学过springboot,并知道自动配置,但你不知懂工厂模式,单例模式等,那么你是纯纯的八股小子(跟我一样),有点水平的面试官如果问了这两个问题你只会自动配置不会工厂模式,你大概率会被pass,学完设计模式,你就可以吊打面试官了
本文以 举例+代码 的方式,循序渐进的讲解设计模式

开闭原则

  • 对扩展开放,对修改关闭,尊虚开闭原则可以达到解耦的效果

工厂模式

  • 工厂说白了就是创建对象的,我创建对象不需要在业务层new了,直接调用工厂的方法获取对象
  • **解耦:**当我们想要添加新的实体类时,不需要改动工厂类和业务类,只添加实体类即可,这就是扩展了功能但没有修改源代码,因为你只是增加了一个新的类而已

1. 简单工厂模式(耦合度低)

顾客点咖啡案例 - 可以先看总结

工厂代码:

java 复制代码
public class CoffeeFactory {
    public Coffee createCoffee(String type){
        Coffee coffee = null;
        if ("American".equals(type)){
            coffee = new AmericanCoffee();
        } else if ("latter".equals(type)){
            coffee = new LatterCoffee();
        }
        return coffee;
    }
}

业务层代码:

java 复制代码
public class CoffeeStore {
    public Coffee orderCoffer(String type){
        CoffeeFactory coffeeFactory = new CoffeeFactory();
        Coffee coffee = coffeeFactory.createCoffee("latter");
        coffee.make();
        return coffee;
    }
}

顾客代码:

java 复制代码
public class Customer {
    public static void main(String[] args) {
        CoffeeStore coffeeStore = new CoffeeStore();
        Coffee coffee = coffeeStore.orderCoffer("latter");
    }
}

**总结:**可以看到业务层解耦了,不用new对象了,但是工厂还是有耦合,如果我想增加橙C美式咖啡,还是需要改动factory这个类,我们最终的目的是只添加实体类,而工厂类和业务层代码不用动。

2. 静态工厂模式(同上)

  • 静态工厂只是把工厂类中的createCoffee变成了静态方法,而业务层直接使用CoffeeFactory.createCoffee获取对象
  • **总结:**这种模式本质上和简单工厂模式没什么区别

3. 工厂方法(无耦合)

  • 代码改动:将Factory变成了抽象接口,具体的实现交给实现类,说白了你有几个类就增加几个FactroyCoffee。

业务层代码:

java 复制代码
public class CoffeeStore {
    private CoffeeFactory coffeeFactory;
    public void setCoffeeFactory(CoffeeFactory coffeeFactory) {
        this.coffeeFactory = coffeeFactory;
    }
    public Coffee orderCoffer(){
        Coffee coffee = coffeeFactory.createCoffee();
        coffee.make();
        return coffee;
    }
}

工厂方法代码:

java 复制代码
// CoffeeFactory
public interface CoffeeFactory {

    public Coffee createCoffee();
}
// 具体实现例如 LatterFactory(拿铁咖啡)
public class LatterFactory implements CoffeeFactory{
    @Override
    public Coffee createCoffee() {
        return new LatterCoffee();
    }
}
  • 总结:工厂方法实现了业务层的完全解耦,工厂层也没有耦合了,如果以后想要增加一个类,只需要创建实体类和工厂的实现类,然后实现CoffeeFactory接口,只增加了2个类,对源代码无修改
  • 缺点:增加一个品种需要创建两个类,增加了系统复杂度,类爆炸

4. 抽象工厂模式

代码就不演示了~~ 核心思想就是工厂方法模式+抽象类

只不过将多个相似功能的Factory抽象到一个父类里面,例如咖啡店除了做咖啡还做甜品,2种咖啡2种甜品要创建4个类+4工厂+1个接口,我们可以把咖啡和甜品放到一个工厂里面,例如美式咖啡+美式甜品使用一个工厂,意式咖啡+意式甜品使用一个工厂,这样就创建4个类+2个工厂+1个接口

单例模式

1. 饿汉式

  • 因为对象是随类加载(线程安全)而创建的,所以天生就是线程安全
java 复制代码
class EHSingleton {
    // 饿汉式单例模式实现
    private EHSingleton(){}
    private static final EHSingleton instance = new EHSingleton();
    public static EHSingleton getInstance(){
        return instance;
    }
}

2. 懒汉式

1.1 线程不安全

java 复制代码
class LHsingletion {
    // 懒汉式单例模式
    private LHsingletion(){}
    private static LHsingletion instance;
    public static LHsingletion getInstance(){
        if (instance == null){ // 可能发生线程安全问题
            instance = new LHsingletion();
        }
        return instance;
    }
}

1.2 Double Check 线程安全方式

java 复制代码
class DoubleCheckSingletion{
    private DoubleCheckSingletion(){}
    private static DoubleCheckSingletion instance;
    public static DoubleCheckSingletion getInstance(){
        if (instance == null){
            synchronized (DoubleCheckSingletion.class) {
                if (instance == null) {
                    instance = new DoubleCheckSingletion();
                }
            }
        }
        return instance;
    }
}
相关推荐
汤姆yu2 分钟前
基于springboot的运动服服饰销售购买商城系统
java·spring boot·后端
期待のcode5 分钟前
Springboot数据层开发—Springboot整合JdbcTemplate和Mybatis
spring boot·后端·mybatis
柯南二号6 分钟前
【后端】【Java】一文深入理解 Spring Boot RESTful 风格接口开发
java·spring boot·restful
Jul1en_7 分钟前
【Spring】实现验证码功能
java·后端·spring
〝七夜56910 分钟前
Jsp中动态include和静态include的区别
java·开发语言
努力进修15 分钟前
【JavaEE初阶】告别小白!Java IO 流读写 + 文件操作实战
java·开发语言·java-ee
爬山算法17 分钟前
Netty(7)如何实现基于Netty的TCP客户端和服务器?
java·服务器·tcp/ip
全栈独立开发者20 分钟前
软考架构师实战:Spring Boot 3.5 + DeepSeek 开发 AI 应用,上线 24 小时数据复盘(2C1G 服务器抗压实录)
java·spring boot·后端
CoderYanger21 分钟前
D.二分查找-基础-2529. 正整数和负整数的最大计数
java·开发语言·数据结构·算法·leetcode·职场和发展
小光学长22 分钟前
ssm农民养殖经验交流与分享平台bc046578(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
java·数据库·spring