java设计模式

设计模式的原则

开闭原则

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

里氏代换原则

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

依赖倒转原则

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

接口隔离原则

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

工厂模式

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

@Service
@Slf4j
public class TypeFactory {

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

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

工具类 ApplicationContextHelper

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

@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

/**
 * @Auther: lr
 * @Date: 2024/8/7 15:29
 * @Description: 接口
 */
public interface TypeInterface {

    void cal();
}

理财产品 BondService

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

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类型调用对应的方法

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实例对象。

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

饿汉式

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

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

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

代理模式

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值