首页 > 其他分享 >工作中常用的6种设计模式

工作中常用的6种设计模式

时间:2024-03-06 12:45:18浏览次数:22  
标签:... 常用 return Spring Object 工作 设计模式 public

谈起设计模式,你一定会问?这玩意到底有啥用?我好像没用过也不影响做一个码农。也可能项目中实际用了,但是你不自知。虽然Java设计模式有23种,但是工作中常用的可能并没有那麽多。就像新华字典有多少字,你没必要都学一样。本章我们只谈常用的几种设计模式,通过设计模式的理念、规约、到应用,理解实战中如何正确使用设计模式,不论对面试还是实际工作中都有益处。
文章提纲

设计理念
最为Java开发者,程序员基本修养名言绝句:

该露露,该藏藏
该封装的要封装
万事万物兼对象
程序代码要健壮
我们简单归纳为2个核心词:高内聚、低耦合。
很小的时候看过动画片,封神演义中哪吒:三头八臂显威力,千征百战斗魔法。


我们根据这首歌词抽象一下,哪吒:三头八臂是静态特征,千征百战是动态技能。把这些特征归纳映射一下:类 = 属性 + 方法如下图:

以上是高内聚的概念,什么是低耦合?

如果可能,我写一本神话《封神演戏》,说哪吒有:三头九臂。你肯定和我吵吵,要给它再配一把兵器。虽然还没想好是啥,但是有个总则:绝对不影响先前这八臂的演技。这就是低耦合!!!所谓程序健壮、拓展性强,也是这个道理。我们真诚地希望:

上述例子不是特别恰当,但是对于设计模式,我们终级的理念是:封装变化的内容,保留不变的宗旨。

设计原则
设计原则可以归纳为2大类:

开闭原则(李氏替换,组合复用,依赖倒置)
规定:软件中的对象(类、模块、函数等等)应该对于扩展是开放的,但是对于修改是封闭的。换句话说,一个实体是允许在不改变它的源代码的前提下变更它的行为。

单一职责(接口隔离,迪米特法则)
规定:一个类只应该有一个职责,只有一个改变它的原因

Spring中的设计模式
在Spring框架中,各种设计模式被广泛应用以支持其强大的功能和灵活性。下面我将结合Spring的源码,鉴赏下Spring中常见的几种设计模式。

  1. 单例模式
      Spring框架中的Bean默认就是单例的。Spring IoC容器负责创建对象实例,并确保在整个应用中,针对同一个Bean的ID,只实例化一次对象。DefaultSingletonBeanRegistry类是Spring管理单例Bean的核心类。
// DefaultSingletonBeanRegistry类中的部分源码
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
    // ...
    private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
    // ...
    @Override
    public Object getSingleton(String beanName) {
        return getSingleton(beanName, true);
    }
    
    protected Object getSingleton(String beanName, boolean allowEarlyReference) {
        // ... 省略部分代码
        Object singletonObject = this.singletonObjects.get(beanName);
        if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
            synchronized (this.singletonObjects) {
                singletonObject = this.earlySingletonObjects.get(beanName);
                if (singletonObject == null && allowEarlyReference) {
                    ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                    if (singletonFactory != null) {
                        singletonObject = singletonFactory.getObject();
                        this.earlySingletonObjects.put(beanName, singletonObject);
                        this.singletonFactories.remove(beanName);
                    }
                }
            }
        }
        return (singletonObject != NULL_OBJECT ? singletonObject : null);
    }
    // ...
}
  1. 工厂模式
    Spring使用工厂模式通过BeanFactory、ApplicationContext等接口创建和管理Bean对象。DefaultListableBeanFactory是Spring中Bean工厂的实现类。
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
        implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
    // ...
    @Override
    public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
        return doGetBean(name, requiredType, null, false);
    }

    @Override
    public <T> T getBean(Class<T> requiredType) throws BeansException {
        return doGetBean(null, requiredType, null, false);
    }
    
    // ... 省略部分代码
}
  1. 代理模式
    Spring AOP(面向切面编程)的实现就是基于代理模式。Spring创建目标对象的代理对象,并在代理对象中织入切面逻辑。JdkDynamicAopProxy和CglibAopProxy是Spring AOP中创建代理的两个核心类。
// JdkDynamicAopProxy类中的部分源码
public class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {
    // ...
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // ... 省略部分代码
        // 获取AdvisedSupport对象,包含了切面等AOP相关信息
        final AdvisedSupport advised = this.advised;
        // ... 省略部分代码
        // 获取拦截器链(切面链)
        List<Object> chain = advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
        // ... 省略部分代码
        // 执行链式调用
        return invokeJoinpointUsingReflection(target, method, args, targetClass, chain);
    }
    // ...
}
  1. 观察者模式(监听模式)
    在Spring中,事件处理机制就是基于观察者模式实现的。当事件发生时,所有注册的观察者都会收到通知并作出响应。ApplicationEventMulticaster接口和SimpleApplicationEventMulticaster类是Spring事件处理机制的核心。
// SimpleApplicationEventMulticaster类中的部分源码
public class SimpleApplicationEventMulticaster extends AbstractApplicationEventMulticaster {
    // ...
    @Override
    public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
        ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
        for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {```java
            // 调用监听器的方法处理事件
            invokeListener(listener, event);
        }
    }

    private void invokeListener(ApplicationListener<?> listener, ApplicationEvent event) {
        ErrorHandler errorHandler = getErrorHandler();
        if (errorHandler != null) {
            try {
                doInvokeListener(listener, event);
            } catch (Throwable err) {
                errorHandler.handleError(err);
            }
        } else {
            doInvokeListener(listener, event);
        }
    }

    private void doInvokeListener(ApplicationListener<?> listener, ApplicationEvent event) {
        try {
            // 调用监听器的onApplicationEvent方法
            listener.onApplicationEvent(event);
        } catch (ClassCastException ex) {
            // ... 省略部分代码,处理类型不匹配异常
        }
    }
    // ...
}
  1. 责任链模式
    在Spring中,HandlerInterceptor和HandlerInterceptorAdapter等类在处理请求拦截时,采用的就是责任链模式。一个请求会按照定义的拦截器顺序,逐个被处理,直到找到对应的处理器或者遍历完所有的拦截器。
// HandlerInterceptor接口定义
public interface HandlerInterceptor {
    boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception;

    void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception;

    void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception;
}

// 实现HandlerInterceptor接口的自定义拦截器
public class CustomInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        // 在这里执行前置处理逻辑
        return true; // 返回true表示继续向下执行,返回false表示中断请求
    }

    // ... 其他方法实现
}
  1. 模版模式
    Spring中的JdbcTemplate、HibernateTemplate等类就是模版模式的典型应用。它们定义了一个操作数据库或Hibernate的骨架方法,允许子类在不改变算法结构的情况下重定义某些步骤的具体内容。
// JdbcTemplate部分源码
public class JdbcTemplate extends JdbcAccessor implements JdbcOperations, BeanFactoryAware {
    // ...
    public <T> T query(String sql, RowMapper<T> rowMapper) {
        return query(sql, new Object[0], rowMapper);
    }

    public <T> T query(String sql, Object[] args, RowMapper<T> rowMapper) {
        return query(sql, args, rowMapper, true);
    }

    // ... 省略部分代码,这里是模版方法的实现
    // 真正的SQL执行和结果集处理逻辑在这里,但是允许子类通过RowMapper来定制结果集的处理方式
    // ...
}

// 自定义RowMapper实现
public class CustomRowMapper implements RowMapper<MyObject> {
    @Override
    public MyObject mapRow(ResultSet rs, int rowNum) throws SQLException {
        // 在这里定制如何从ResultSet中映射到MyObject对象
        return new MyObject(/* 映射逻辑 */);
    }
}

这些设计模式在Spring框架中被广泛应用,能够灵活地应对各种复杂场景,提供强大且可扩展的功能。

标签:...,常用,return,Spring,Object,工作,设计模式,public
From: https://www.cnblogs.com/kisshappyboy/p/18056276

相关文章

  • 工作两年涨薪40%,揭秘我的学习之路!
    毕业出来工作差不多两年了,就呆过一家公司,主要做功能测试,会自己驱动做些自动化相关的工作,但不想就此止步,所以换了工作,最近刚获得了新Offer,涨薪幅度40%+,年薪大概25w。自己还挺满意的,不论薪资还是福利方面,希望未来能持续进步,不断成长。关于之前的工作我是从大二开始接触并学习......
  • 找工作学习第八天
    echarts图表配置 定义一个变量引入echarts,使用echarts。init方法初始化一个标签,然后因为要获取dom中的标签元素,这就要写在mounted里面,定义一个option参数选项对象,下面x轴,y轴数据就可以写成option.x,option.y不用这样写成一大坨 order数据如下,如何将苹果三星小米获取......
  • Unity3D 常用得内置函数(Cg与GLSL)详解
    Cg和GLSL是Unity3D中常用的着色器语言,通过使用这两种语言,开发者可以实现各种精美的视觉效果。本文将详细介绍Unity3D中常用的一些内置函数,并给出相应的技术详解和代码实现。对啦!这里有个游戏开发交流小组里面聚集了一帮热爱学习游戏的零基础小白,也有一些正在从事游戏开发的技术大......
  • JS字符串、数组 常用方法
    字符串字符串增:1、+拼接2、concat()例:leta='hello'  letb=a.concat('word')  console.log(b) // "helloworld" 字符串删:1、slice(star,end)  从原始字符串中提取一个子字符串,并返回一个新的字符串,而不改变原字符串。start(必需):起始位置。如果是正数,则......
  • 【实用工具】IDEA常用快捷键
    ctrl+alt+insert:新建类/文件夹...shift+alt+上下 :单行上/下移动ctrl+d:复制行ctrl+x: 删除行Ctrl+Backspace:按单词删除Ctr+Shift+U:大小写转化alt+insert:快速生成set/get  equals/hashcode /overrideshift+f6:改类名/方法名refactorctrl......
  • 搜维尔科技:捕获、分析、优化,使用 Xsens Ergo 创建更安全的工作空间
    简化人体工程学分析,优先考虑员工福祉,并利用客观数据和见解提高生产力。捕获。分析。优化。使用XsensErgo创建更安全的工作空间1.质量数据使用高质量、客观且经过验证的运动数据进行详细的人体工程学分析2.随处使用在最具挑战性的工作环境中随时测量和分析3.快速、实时分......
  • Nestjs系列 Nestjs常用装饰器
    在此之前,项目中使用的各种@Inject@Controller等以@开头的都是装饰器,这里对使用中常用的装饰器进行进一步认识。模块之间常用装饰器模块装饰器@Module声明模块@Controller、@Injectable分别声明其中的controller和provider(service)其中@Injectable可以在任......
  • js 数组筛选方法使用整理_JavaScript常用数组元素搜索或过滤
    一、常用方案介绍:如果你想找到在符合特定条件的阵列中的所有项目,使用filter。如果你想检查是否至少有一个项目符合特定的条件,请使用find。如果你想检查一个数组包含一个特定的值,请使用includes。如果要在数组中查找特定项目的索引,请使用indexOf 二、js数组筛选方法......
  • React的7个常用Hooks及使用场景(含示例)
    React是一款非常流行的JavaScript库,它提供了许多Hooks,用于管理函数组件的状态和生命周期。下面是React的每个Hooks的使用场景和示例:No1、useStateuseState用于在函数组件中管理状态。它返回一个包含当前状态和一个更新状态的函数的数组。更新状态的函数可以接受一个新的值......
  • SpringBoot常用注解
    SpringBoot常用注解  @SpringBootApplication=@SpringBootConfiguration+@ComponentScan+@EnableAutoConfiguration@Configuration注解能够将一个类定义为SpringBoot应用程序中的配置类,等同于spring的XML配置文件,从而使该类中的Bean对象能够被SpringIoC容器进行自动管......