java设计模式

设计模式的原则

开闭原则

扩展开放,修改关闭。项目后期维护升级时尽量保证在不修改之前代码的前提下,扩展新功能。

里氏代换原则

这个是对扩展开放的一个具体实现方式-继承。

依赖倒转原则

这个是对扩展开放的一个基础-接口编程。

接口隔离原则

接口隔离,降低类之间的耦合性。

工厂模式

当项目中某个功能的不同产品的业务处理逻辑大部分一致,为了减少重复代码,可使用工厂模式,使得调用者不用操心里面具体的实现逻辑,直接调用具体的产品名称即可。

java 复制代码
@Service
@Slf4j
public class TypeFactory {

    public void cal(String type){
        //根据不同的产品类型处理不同业务逻辑 TODO
        
    }
}

当不同产品有自己的service类文件时,也可通过工厂找到对应的service后调用其方法

工具类 ApplicationContextHelper

java 复制代码
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

/**
 * @Auther: lr
 * @Date: 2024/8/9 10:33
 * @Description: 根据bean名称获取对应的类
 */
@Component
public class ApplicationContextHelper implements ApplicationContextAware {
    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    public static Object getBean(String className) throws BeansException, IllegalArgumentException {
        if (className == null || className.length() <= 0) {
            throw new IllegalArgumentException("className is null!");
        }

        String beanName = null;
        if (className.length() > 1) {
            beanName = className.substring(0, 1).toLowerCase() + className.substring(1);
        } else {
            beanName = className.toLowerCase();
        }
        return applicationContext != null ? applicationContext.getBean(beanName) : null;
    }
}

工厂类 TypeFactory

java 复制代码
@Service
@Slf4j
public class TypeFactory {

    public TypeInterface getType(String type){
        String beanName = type + "Service";
        try {
            Object instance = ApplicationContextHelper.getBean(beanName);
            return (TypeInterface)instance;
        } catch (Exception e) {
            log.error("{}未找到对应类",type,e);
            throw e;
        }
    }
}

接口 TypeInterface

java 复制代码
/**
 * @Auther: lr
 * @Date: 2024/8/7 15:29
 * @Description: 接口
 */
public interface TypeInterface {

    void cal();
}

理财产品 BondService

java 复制代码
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

/**
 * @Auther: lr
 * @Date: 2024/8/7 15:08
 * @Description: 理财产品的service
 */
@Service
@Slf4j
public class BondService implements TypeInterface{

    public void cal(){
        log.info("理财产品计算....");
    }
}

定期贷款 FixedDepositService

java 复制代码
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

/**
 * @Auther: lr
 * @Date: 2024/8/7 15:09
 * @Description: 定期贷款的service
 */
@Service
@Slf4j
public class FixedDepositService implements TypeInterface{

    public void cal(){
        log.info("定期贷款计算....");
    }
}

controller 根据type类型调用对应的方法

java 复制代码
import com.example.demo.service.TypeFactory;
import com.example.demo.service.TypeInterface;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
 * @Auther: lr
 * @Date: 2024/8/7 15:20
 * @Description:
 */
@RestController
@Slf4j
@RequestMapping("/testFactory")
public class TestFactoryController {

    @Autowired
    private TypeFactory typeFactory;

    @RequestMapping("/getCal")
    public String getCal(@RequestParam("type") String type){
        TypeInterface typeInterface = typeFactory.getType(type);
        typeInterface.cal();
        return "success";
    }
}

测试

调用接口 /testFactory/getCal?type=Bond 可以看到后台日志打印

单例模式

懒汉式

人很懒,等到饿了才去找食物。类加载时不会初始化,只有用的时候才会new实例对象。

java 复制代码
public class SingleBean {
    //未进行初始化
    private static SingleBean instance;
    private SingleBean (){}
    //调用时才会new对象
    public static synchronized SingleBean getInstance() {
        if (instance == null) {
            instance = new SingleBean();
        }
        return instance;
    }
}

饿汉式

人勤快,屯食物待饿了就吃。类加载时初始化实例对象,后续直接用。

java 复制代码
public class SingleBean {
    //初始化
    private static SingleBean instance=new SingleBean();
    private SingleBean (){}
    public static SingleBean getInstance() {
        return instance;
    }
}
  • 懒汉式由于在方法内new对象,若多线程同时进来,发现找不到对象,都去new对象,会造成数据覆盖现象。而饿汉式在类加载时就已经初始化实例对象。所以与懒汉式相比,饿汉式是线程安全的;
  • 懒汉式由于出现多线程调用情况,会在方法上加锁(synchronized),保证同一时间只有一个进程调用,此时执行效率会降低。所以饿汉式的执行效率比懒汉式快;
  • 由于饿汉式在类初始化时加载,内存占用会浪费空间。所以饿汉式的内存情况比懒汉式占用量大且耗内存;

这篇文章的解决方法二 使用的则是懒汉式方式,可试着用饿汉式解决。一般会使用饿汉式解决

代理模式

代理模式很常见,spring的aop就是其中一个。感兴趣可看详细文章 动态代理

开发过程中切切实实的场景还真没见过。若有前辈了解,还请告知一二!

相关推荐
侠客行03179 小时前
Mybatis连接池实现及池化模式
java·mybatis·源码阅读
蛇皮划水怪9 小时前
深入浅出LangChain4J
java·langchain·llm
老毛肚10 小时前
MyBatis体系结构与工作原理 上篇
java·mybatis
风流倜傥唐伯虎11 小时前
Spring Boot Jar包生产级启停脚本
java·运维·spring boot
Yvonne爱编码11 小时前
JAVA数据结构 DAY6-栈和队列
java·开发语言·数据结构·python
Re.不晚11 小时前
JAVA进阶之路——无奖问答挑战1
java·开发语言
你这个代码我看不懂11 小时前
@ConditionalOnProperty不直接使用松绑定规则
java·开发语言
fuquxiaoguang11 小时前
深入浅出:使用MDC构建SpringBoot全链路请求追踪系统
java·spring boot·后端·调用链分析
琹箐11 小时前
最大堆和最小堆 实现思路
java·开发语言·算法
__WanG12 小时前
JavaTuples 库分析
java