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就是其中一个。感兴趣可看详细文章 动态代理

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

相关推荐
九圣残炎7 分钟前
【从零开始的LeetCode-算法】1456. 定长子串中元音的最大数目
java·算法·leetcode
wclass-zhengge9 分钟前
Netty篇(入门编程)
java·linux·服务器
Re.不晚36 分钟前
Java入门15——抽象类
java·开发语言·学习·算法·intellij-idea
雷神乐乐42 分钟前
Maven学习——创建Maven的Java和Web工程,并运行在Tomcat上
java·maven
码农派大星。1 小时前
Spring Boot 配置文件
java·spring boot·后端
顾北川_野1 小时前
Android 手机设备的OEM-unlock解锁 和 adb push文件
android·java
江深竹静,一苇以航1 小时前
springboot3项目整合Mybatis-plus启动项目报错:Invalid bean definition with name ‘xxxMapper‘
java·spring boot
confiself1 小时前
大模型系列——LLAMA-O1 复刻代码解读
java·开发语言
Wlq04151 小时前
J2EE平台
java·java-ee
XiaoLeisj1 小时前
【JavaEE初阶 — 多线程】Thread类的方法&线程生命周期
java·开发语言·java-ee