设计模式
文章平均质量分 88
Lvshen的技术小屋
技术宅
展开
-
我用自定义注解优雅的实现了业务的复杂校验
当我们的业务逻辑校验很复杂时,我们可以使用上面的校验注解将校验逻辑与业务逻辑分开,这样有利于业务与非业务解耦,也满足设计原则的单一职责原则。除了方便阅读,还有的好处就是,当我们不需要校验时,我们可以将业务方法上的校验注解注释掉,这样我们就不必在业务代码中去修改了,从而减少了因修改业务代码导致bug的风险。上面的代码相信大家都写过,我们不需要在方法中去写参数的校验,我们在字段上使用注解,就是实现了参数的必填校验,范围校验。类就是真正写校验功能的类,会把业务参数传到这个校验类中。原创 2022-08-20 10:39:57 · 568 阅读 · 0 评论 -
我用规则引擎实现了消除if语句
规则引擎就是提供一种可选的计算模型。与通常的命令式模型(由带有条件和循环的命令依次组成)不同,规则引擎基于生产规则系统。原创 2022-08-20 10:34:38 · 231 阅读 · 0 评论 -
我用注解优雅的实现了数据的脱敏
1使用场景你平时肯定做过这样的需求。要求展示用户的手机号,但是不能完全展示,需要在中间给手机号打码,如下图:我们将关键数据做了适当隐藏,这样就叫数据脱敏。2数据脱敏数据脱敏又称数据去隐私化或数据变形,是在给定的规则、策略下对敏感数据进行变换、修改的技术机制,能够在很大程度上解决敏感数据在非可信环境中使用的问题。根据数据保护规范和脱敏策略.对业务数据中的敏感信息实施自动变形.实现对敏感信息的隐藏。我们来看看具体需求,现在要求对以下数据的电话号码和身份证号码适当隐藏处理:要求脱敏原创 2021-04-26 16:07:50 · 937 阅读 · 0 评论 -
连续写了一个月的设计模式,现在我把它汇总成PDF了
嗨,经历一个月我的设计模式系列终于告一段落啦。如上图这是我在微信公众号【Lvshen_9】上发表的设计模式系列文章,我写设计模式的目的也是在于自己学习,还有和大家一起交流,一起进步。之前就只知道一些单例、代理、观察者等代理模式。写完了确实对设计模式有了更深的认识。除了在公众号上面发表,我还在头条上【Lvshen的技术小屋】也发表了。下面来看看我整合的PDF:里面的图都是自己画的,代码我都上传到Github了。对图和代码有兴趣的可以私聊。部分目录:我写这个系列的文章原创 2020-11-27 08:50:17 · 104 阅读 · 0 评论 -
设计模式23之桥接模式(终章)
背景在现实生活中,一个物体往往具有多个方面的属性。如果我们将人进行归类。我们可以按性别分类,也可以按肤色分类,也可以按所处的地区分类,还可以按自己的母语分类。在代码中我们如何让表示这个人呢。如果以继承的方式表示,就会出现很多子类,这样扩展就会很麻烦。我们可以使用桥接模式来解决这些问题。什么是桥接模式“Decouple an abstraction from its implementation so that the two can vary independently.(将抽象和实现原创 2020-11-26 08:22:43 · 103 阅读 · 0 评论 -
设计模式22之享元模式
背景在我们编码开发过程中可能会遇到需要创建大量相同或相似对象实例问题。如果我们把这些对象都创建出来,会耗费系统资源。但是我们可以将这些公共的部分抽取出来,就会节省大量的系统资源。因此享元模式就这样出来了。什么是享元模式“Use sharing to support large numbers of fine-grained objects efficiently.(使用共享对象可有效地支持大量的细粒度的对象。)”享元模式的核心思想就是共享,相同的对象只保留一份。但是为了实现共享,不同的状原创 2020-11-25 15:41:24 · 101 阅读 · 1 评论 -
设计模式21之解释器模式
背景在软件开发中,可能会出现某些相似的功能多次出现,这些功能有一定的相似性与规律性。这是我们就可以将其归纳成一种简单的语言。这就是解释器模式的来源。上面的讲述是不是云里雾里的,那我们来举个例子。我们要开发一个功能,要求输入公式,输入参数,返回正确结果。例如我们输入参数:a=2;b=4;c=10我们再输入表达式:a+b-c输出结果:-4。我们再来输入一个表达式:a*b/c输出结果:0.8。如果要你开发这个功能,你会怎么做?如果使用解释器模式,会有很好...原创 2020-11-24 08:41:54 · 104 阅读 · 0 评论 -
设计模式20之状态模式
背景在开发过程中,对象会有根据不同的情况做出不同的行为,而影响行为的属性称之为状态属性,这个对象也就是状态对象。我们在编码时,可能会使用if-else来做状态判断。例如我有一个活动类Activity,这个类里面有一个活动开始字段,活动结束字段,还有一个状态字段,现在我们要来判断活动的状态:未开始、进行中、已结束。示例代码如下:当状态很多,那么程序会变得很复杂。如果有新的状态增加,就要添加新的if语句,违背设计原则中的开闭原则。所以我们采用状态模式来解决这个问题,我们将对象状态的判断逻辑抽原创 2020-11-23 09:43:51 · 183 阅读 · 0 评论 -
设计模式19之访问者模式
背景现实生活中有这样的场景,一个集合对象中存在多种不同的元素,并且每种元素也存在多种不同的访问者和访问方式。如超市中有多种不同的商品,存在多个顾客在买衣服。不同顾客对不同的商品评价也不一样。当遇到被处理的数据元素相对稳定并且访问方式多种多样的数据结构,我们就可以使用访问者模式。通过访问者模式,我们可以将访问方法从数据结构中分离出来,这样我们可以扩展新的访问方法,不用修改原程序代码就能实现灵活的扩展。什么是访问者模式上面的文字你可能云里雾里,现在你只要知道使用访问者模式的作用是将数据结构中的元原创 2020-11-16 08:31:19 · 106 阅读 · 0 评论 -
设计模式18之备忘录模式
背景我们直接开篇点题,备忘录模式解决什么问题呢?主要用于实现撤销功能。很多软件都有撤销功能,只需要按Ctrl + Z即可实现撤回。数据库也有回滚操作。游戏中有存档功能。竞速类游戏有时间回溯功能。备忘录模式记录一个对象的内部状态,如果我们需要撤销当前操作。就能使数据回复到原来的状态。什么是备忘录模式“Without violating encapsulation,capture and externalize an object's internal state so that the ob原创 2020-11-12 08:37:18 · 170 阅读 · 0 评论 -
设计模式17之外观模式
背景现实生活中有这样一个例子,如你贷款买房,需要同多个机构联系。你可能需要转户口,需要去市政府去办理;需要公积金社保流水,就要去人社局打印盖章;需要薪资流水,就要去银行打印。但是,如果有一个综合部门来处理这些手续,你就不用到处跑了。外观模式-背景在系统开发中也是一样,如果子系统越来越多,那么访问系统的的复杂度也会变高。如果子系统发生变化,那么客户访问的逻辑也会变化,这样违背了设计中的"开闭原则"。为此我们需要外观模式,来降低系统的耦合度。外观模式-背景2什么是外观模式“Pr原创 2020-11-11 08:18:45 · 102 阅读 · 0 评论 -
设计模式16之观察者模式
背景观察者模式你肯定知道并且用过,如果你没听过观察者模式这几个词,那发布-订阅模型你肯定知道。我们在使用Kafka等消息中间件时,就用到了发布-订阅模式进行数据的生产消费。你可以将发布-订阅模式理解为观察者模式。如下代码:kafka发布消息:ListenableFuturefuture=kafkaTemplate.send(topic,jsonString);消费者订阅消息:@KafkaListener(topics="${spring.kafka.topic}"...原创 2020-11-06 08:18:04 · 167 阅读 · 0 评论 -
设计模式15之组合模式
背景首先我们来理解下"部分-整体",在现实生活中的这种关系"部分-整体"也很常见。比如:学院与学校,分公司与总公司,书与书柜等等。在软件开发中我们常常有对简单对象与复合对象的处理,可以使用组合模式一致地处理单个对象与复合对象,客户端无需关系要调用的是单个对象还是复合对象。这种通用性很好的减少了客户端的代码。上面的介绍是不是比较抽象?别急,请继续往下看。什么是组合模式“Compose objects into tree structures to represent part-whole原创 2020-11-04 08:57:35 · 127 阅读 · 0 评论 -
设计模式14之迭代器模式
背景首先我们来看一段代码:List<Member>memberList=listMember();Iterator<Member>iterator=memberList.iterator();while(iterator.hasNext()){Membernext=iterator.next();...}上面的代码是使用迭代器遍历List。我们来看看下面的遍历方法:for(Membermember:memb...原创 2020-11-02 08:33:00 · 233 阅读 · 0 评论 -
设计模式13之适配器模式
背景现实生活中,如果我要给苹果手机充电,但是我只有一根安卓充电线,这里我还有一根安卓转苹果的转接线。所以我可以给苹果手机充电,使用安卓线加上转接线就能实现。那么这里的转接线就充当了适配器的作用。我们在开发中也会碰到类似的情景,具有某种业务功能的方法已经存在,但是它与当前系统的接口规范不符。如果重新开发方法,成本会很高。这时我们就可以使用适配器模式来解决这个问题。示意图如图左,A、B两个组件想结合在一起,需要图右中的C。这个C就是适配器。什么是适配器模式“Convert th原创 2020-10-29 08:18:51 · 107 阅读 · 0 评论 -
设计模式12之策略模式
背景策略模式是一种比较简单的设计模式,生活中做成一件事有几种不同的策略选择供你达成。比如你上班可以选择坐公交上班,可以选择坐地铁上班,也可以选择自驾上班,甚至还可以步行上班。如果需要用代码表示上面的内容,你可以使用多重条件语句实现。if("1".equals(status)){return"公交";}elseif("2".equals(status)){return"地铁";}elseif("3".equals(status)){return"自...原创 2020-10-26 08:29:51 · 190 阅读 · 0 评论 -
设计模式11之装饰模式
背景我们在开发过程中,如果我们想使用存在的轮子,但是轮子的有些功能不能满足我们。我们需要对轮子新增想要的功能。好的设计方式是不改变轮子的结构,动态的扩展功能。装饰模式就是这样的一种设计方式。什么是装饰模式“装饰模式(Decorator Pattern)是一种比较常见的模式,其定义如下:Attach additional responsibilities to an object dynamically keeping the same interface.Decorators provide原创 2020-10-23 10:41:11 · 136 阅读 · 0 评论 -
设计模式10之责任链模式
背景我们有这样一个场景,假如你出差需要报销。你的报销单审批人依次是:项目经理、科室主任、部门负责人、财务负责人。当然你不需要知道每个审批人的姓名、电话号码、办公地址等信息。你不需要自己一个一个的去找这些审批人审批。常用的解决方式是你发起一个审批需求,你的项目经理审批后提交给科室主任,科室主任审批后提交给部门负责人,部门负责人审批后提交给财务负责人审批。这样你只需要发起一个请求,后面的审批就不需要你操心了。什么是责任链模式“Avoid coupling the sender of a req原创 2020-10-21 08:29:46 · 204 阅读 · 2 评论 -
设计模式9之命令模式
在开发中,方法的请求与方法的执行往往存在紧密耦合关系,不利于系统的维护。命令模式就是为了解决这个问题而出现的。什么是命令模式“命令模式是一个高内聚的模式,其定义为:Encapsulate a request as an object,thereby letting you parameterize clients with different requests,queue or log requests,and support undoable operations.(将一个请求封装成一个对象,从原创 2020-10-19 08:36:11 · 195 阅读 · 1 评论 -
公司系统if-else语句太多了,我用设计模式消除了if-else
我在之前的文章中使用枚举消除了if-else语句,有兴趣的可以看看我的这篇文章:“如何用枚举消除if/else?-枚举高阶用法”这次我采用其他方式消除if-else。背景你在平时开发中肯定有使用if-else语句的时候,然而大量的if-else语句不利于代码阅读,影响代码复杂度。反正我在消除Sonar异味的时候头疼过。之前公司系统的代码中也存在if-else过多问题,导致代码不优雅,这里为了讲解,我将业务逻辑简化。假如我有一个计算实际价格的方法,要求输入用户的级别和商品的实际价格原创 2020-10-16 08:47:31 · 1658 阅读 · 0 评论 -
设计模式8之中介者模式
背景有这样一个场景,如果你有很多朋友,朋友与朋友之间也是朋友。如果你的QQ号码变化,你的所有朋友都需要知道,你会告诉你的朋友你的QQ号码变了,朋友再告诉他的朋友。这样所有的朋友都需要相互通知你的QQ号码变了,这样牵一发动全身,耦合性非常大。网状结构为了降低之间的耦合性,可以将网状结构改成星形模式。这里就需要一个中介者,负责告知所有的朋友。星形结构这种形式后面就发展成了中介者模式。什么是中介者模式“Define an object that encapsulates ho原创 2020-10-15 08:41:31 · 195 阅读 · 1 评论 -
设计模式7之原型模式
如果你在开发中遇到需要创建大量的对象,你可以使用传统的构造函数创建对象。但是对于开发来说这样做太麻烦了,有没有高效的生成对象的方式呢?当然是有的,原型模式就能解决上面的问题。什么是原型模式“Specify the kinds of objects to create using a prototypical instance,and create new objects by copying this prototype.(用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。)”原创 2020-10-13 08:44:22 · 196 阅读 · 0 评论 -
设计模式6之代理模式
关于代理模式,很好理解。比如你买演唱会的票,自己很难买到,只能去找黄牛,那么黄牛就是代理(非官方)卖火车票的。在开发中,代理模式很常见。一个类的对象不直接生成,通过代理类去帮你生成对象。那么通过代理生成的对像的功能可能会有增强。一般我们想让一个对象的功能增强,就可以使用代理模式。什么是代理模式“Provide a surrogate or placeholder for another object to control access to it.(为其他对象提供一种代理以控制对这个对象的访问原创 2020-10-12 08:37:23 · 132 阅读 · 0 评论 -
设计模式5之建造者模式
一个复杂的对象往往由多个子部件按一定的步骤组成。例如,汽车由发动机、轮胎、方向盘等部件组成的。组成对象的各个部件可以灵活选择,而创建步骤大同小异。我们可以用建造者模式很好的描述该类产品的创建。什么是建造者模式呢“Separate the construction of a complex object from its representation so that the same construction process can create different representation原创 2020-10-11 09:42:25 · 128 阅读 · 0 评论 -
设计模式4之模板方法模式
背景在开发中,你肯定有遇到过这样一种场景:你知道某个方法的关键步骤以及执行顺序,但是里面有的具体步骤并清楚。你会怎么做?比如你早上起床到公司,我们分解步骤:“ 起床洗漱 吃早餐 乘坐交通工具 到公司 ”我们已经确定这个步骤了,但是不同的人里面的细节可能会不一样。比如小明早餐吃的面包,小张吃的面条。小美坐的地铁,小花做的公交。再举个例子,我们平时写简历会用到简历模板,不同的人写的内容不一样,模板一样。模板方法模式是这样定义的:“定义一个操作原创 2020-10-10 08:32:06 · 103 阅读 · 0 评论 -
设计模式3之抽象工厂模式
抽象工厂模式定义工厂方法模式中工厂只负责同类产品的生产。比如电视机工厂不应该生产汽车。然而现实生活中有很多综合型的工厂,比如有些电视工厂不仅生产电视机,还会生产与之配套的机顶盒。那么抽象工厂模式随之诞生,这种模式将考虑多种类型产品的生产。我们总结下:“ 工厂方法模式只考虑成产同一等级级的产品 抽象方法模式考虑生产多等级的产品,可以说是工厂方法模式的升级版 ”如上图,小米音响和苹果音响为同一个产品。而小米手机和小米音响为同一产品族。使用场景那么什么情况原创 2020-09-29 09:28:29 · 211 阅读 · 0 评论 -
设计模式2之工厂方法模式
什么是工厂方法模式我们有一个产品类,还有一个工厂接口,一个实现工厂接口的工厂类。产品对象的创建是依靠工厂类来创建。核心就是创建与使用分离。“Define an interface for creating an object,but let subclasses decide which class to instantiate.Factory Method lets a class defer instantiation to subclasses”工厂方法模式主要有下面的优点:“原创 2020-09-25 16:16:00 · 108 阅读 · 0 评论 -
设计模式1之单列模式
单列模式在生活中的应用“Ensure a class has only one instance, and provide a global point of access to it”单列模式相信大家都很熟悉,一个类只能创建一个实列。这样做的原因是避免内存浪费,还有某些场景下保持数据一致性问题。在操作系统中很多场景都被设计成单列。比如网站的计数器,多线程中的线程池,打印机的后台服务,应用程序中的对话框等等。在我们平时的开发中,也有很多时候用到了单列模式。比如:J2EE 标准中的Ser.原创 2020-09-18 16:41:12 · 180 阅读 · 0 评论