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

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

相关推荐
Theodore_10223 小时前
4 设计模式原则之接口隔离原则
java·开发语言·设计模式·java-ee·接口隔离原则·javaee
冰帝海岸4 小时前
01-spring security认证笔记
java·笔记·spring
世间万物皆对象5 小时前
Spring Boot核心概念:日志管理
java·spring boot·单元测试
没书读了5 小时前
ssm框架-spring-spring声明式事务
java·数据库·spring
小二·5 小时前
java基础面试题笔记(基础篇)
java·笔记·python
开心工作室_kaic6 小时前
ssm161基于web的资源共享平台的共享与开发+jsp(论文+源码)_kaic
java·开发语言·前端
懒洋洋大魔王6 小时前
RocketMQ的使⽤
java·rocketmq·java-rocketmq
武子康6 小时前
Java-06 深入浅出 MyBatis - 一对一模型 SqlMapConfig 与 Mapper 详细讲解测试
java·开发语言·数据仓库·sql·mybatis·springboot·springcloud
转世成为计算机大神6 小时前
易考八股文之Java中的设计模式?
java·开发语言·设计模式
qq_327342737 小时前
Java实现离线身份证号码OCR识别
java·开发语言