设计模式
贤子磊
love and code
展开
-
设计模式详解(二十二)——备忘录模式
一、场景问题某手游公司经营一款中国象棋游戏,在用户的反馈中发现一些用户由于屏幕操作失误经常出现下错棋的情况,但是系统并未提供撤销的功能,现需要设计一套撤销的功能可以回退棋子状态可以取消回退请设计一条切实可用的程序。二、传统解决方案一种解决思路就是每个棋子对象存储自己走过的快照信息,根据不同的时间恢复到指定的状态。这种方式简单可行,但是过多的信息混合到实体对象中,导致对象臃肿,违背单一职责原则。针对这种情况,我们可以进行指责分离,抽出一个单独的备忘录来优化。这就引出了本文的主题——备忘录模式。原创 2020-11-12 18:52:37 · 347 阅读 · 0 评论 -
设计模式详解(二十一)——访问者模式
一、场景问题某公司人事部门和财务部门都会处理员工的基础数据。财务部门:会访问员工的薪水情况人事部门:会访问员工的出勤情况员工分为正式员工和临时工二、传统解决方案定义抽象部门接口,财务部门和人事部门为其实现子类,分别在各自的类中处理逻辑,这种方式也能很方便解决问题,至于访问者模式,会导致代码抽象,晦涩难懂,不建议使用访问者模式。下文仅仅作为模式的案例展示。三、模式剖析1、模式定义访问者模式(Visitor Pattern):将作用于某种数据结构中的各元素的操作分离出来封装成独立的类,使原创 2020-11-10 19:22:12 · 264 阅读 · 0 评论 -
设计模式详解(二十)——迭代器模式
一、场景问题在激烈的市场竞争中,为了提高自己的硬实力,A公司和B公司决定合并。现在目前二者的员工信息都存放在不同的数据库中,且存储的方式不同,请设计出统一的读取所有员工(A、B公司之和)信息的接口。为了简化问题,假定A公司使用List集合存储员工信息B公司使用数组存储员工信息二、传统解决方案最直观的做法是分别查询出来二者的员工数据,采用其中一种格式转化为另一种格式的方式来遍历读取。这种方式处理起来最简单,也最容易理解,但是没有考虑以后的扩展性。如果新增一种采用另外的数据结构存储用户信息,需要原创 2020-11-10 18:55:11 · 306 阅读 · 0 评论 -
设计模式详解(十九)——中介者模式
一、场景问题设计一套买房与卖房的交互程序。二、传统解决方案最直观的做法是定义卖方和买方的实体,二者直接进行信息交互。但是随着买方和卖方的人数新增,实体之间的交互会变得错综复杂,直接交互的设计方案会导致系统的通信链路交错复杂,且实体之间耦合过多,维护困难。因此我们可以采用中间层(中介)的方式来简化交互流程。即每个客户都只与中介交互,由中介来负责传递消息,使得各个实体间解耦,较少交互上的不便性。(即现在的房地产中介公司,当然缺点就是增加了中介费)。三、模式剖析1、模式定义中介者模式(Mediato原创 2020-11-09 19:53:48 · 358 阅读 · 2 评论 -
设计模式详解(十八)——观察者模式
一、场景问题设计一套报纸发布/订阅的程序设计报亭:发布内容,并分发到各个订阅者读者:订阅报纸,也可取消订阅二、传统解决方案一种解决方式是报刊只负责生产报纸,发布内容。由各个订阅者自己去报亭拿自己的报纸。这种方式会导致各个订阅者需要不间断地轮询报亭取报纸,造成资源的浪费。所以这类问题一般会采用观察者模式来实现。三、模式剖析1、模式定义观察者模式(State Pattern):指多个对象间存在一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。这种模式有原创 2020-11-04 18:50:58 · 345 阅读 · 0 评论 -
设计模式详解(十七)——状态模式
一、场景问题某银行需要设计一套信用卡账户管理系统,其中账户大约分为三种状态正常状态账户余额大于等于0,即不存在欠款情况。此时用户可以存款,也可以取款。透支状态账户余额小于0,且欠款金额小于5000。用户可以存款,也可以取款。受限状态账户的欠款金额大于等于5000,用户无法继续取款,仅仅能够存款。请设计一套可用的信用卡账户存钱取款程序。二、传统解决方案1、解决思路每次存款取款校验状态判断是否可操作代码展示账户类public class Account {原创 2020-11-03 19:07:56 · 347 阅读 · 0 评论 -
设计模式详解(十六)——职责链模式
一、场景问题某公司决定设计一套线上的费用报销的审核机制,其中金额在1000以内只需要由项目经理审批即可金额在1000~5000则需要由部门经理审批金额大于5000则必须由总经理审批请设计一套程序实现上述逻辑二、传统解决方案1、解决思路根据不同的金额走不同的审批分支代码展示报销单实体public class FeeForm { /** * 报销单号 */ private Integer id; /** * 报销金额原创 2020-11-02 19:35:55 · 195 阅读 · 0 评论 -
设计模式详解(十五)——命令模式
一、场景问题大家每天上班来到公司第一件事一般就是电脑开机,然后等待一小会就可以开启常规摸鱼操作了。那么问题来了,电脑开机时我们作为用户仅仅按下了电源键,至于电脑内部是如何启动起来的我们并不关心。现在请用程序的方式描述出从按下电源键到电脑开机的整个过程。二、传统解决方案1、解决思路咋一看貌似没啥设计思路,索性就面向过程编程,主函数伪代码如下首先客户端按下电源键,发送开机命令给电脑电脑接收到命令调用调用主板执行开机命令电脑开机2、弊端客户端作为请求的发送者,并不关心请求真正的执行者和执行细原创 2020-10-30 19:08:12 · 173 阅读 · 0 评论 -
设计模式详解(十四)——策略模式
一、场景问题某电影院为了提高电影票的售卖量,决定根据不同的用户群体设置不同的票价折扣策略成年票:9折优惠学生票:半价优惠儿童票:票价大于等于10元情况下直降10元,否则8折优惠请设计票价的计算程序。二、解决方案1、传统解决方案1.1、解决思路根据不同的用户类型进行不同的票价计算,实现起来也比较简单代码实现public class PriceFactory { /** * 票价计算 * * @param originalPrice 原价原创 2020-10-27 19:20:08 · 302 阅读 · 0 评论 -
设计模式详解(十三)——模板方法模式
前言至此我们已经学完了创建型和结构型设计模式,相信大家对设计模式应该有了自己的认识。快马加鞭,我们就此开启行为型设计模式的学习。本文首先介绍较为常用的模板方法模式。一、场景问题使用程序模拟烹饪的整个过程,为了简化问题,目前只烹饪蔬菜和肉两种。烹饪蔬菜:准备菜,起锅烧油,翻炒,加调料,出锅…烹饪肉类:准备肉,焯水,起锅烧油,翻炒,加调料,出锅…二、解决方案1、传统解决方案1.1、解决思路定义抽象烹饪类,建立两个子类分别实现蔬菜与肉的烹饪。代码实现抽象烹饪类public ab原创 2020-10-26 18:10:27 · 190 阅读 · 0 评论 -
设计模式详解(十二)——享元模式
一、场景问题设计一套五子棋的程序。二、解决方案1、传统解决方案1.1、解决思路考虑到五子棋只包含黑白两种棋子,可以定义棋子类,属性包括棋子的颜色和位置。每次下棋时都新建个棋子对象,设置指定的颜色和位置。1.2、弊端虽然这样设计是最简单的,但是如果我们的棋盘巨大,或者棋子的基本属性很多(例如棋子的皮肤、形状等),就会导致棋子的对象创建成本较高,导致内存的浪费。2、享元模式方案明白了上面写法的弊端,我们考虑只创建两种棋子——黑白棋子。棋盘上的棋子展示全部共享与这两个棋子,从而减少内存的消耗。原创 2020-10-23 19:45:46 · 255 阅读 · 0 评论 -
设计模式详解(十一)——外观模式
前言今天我们来介绍外观模式,考虑外观模式较为简单且非常常见(平时开发中所处可见),就直接开门见山。一、模式定义外观模式(Facade Pattern):又叫作门面模式,是一种通过为多个复杂的子系统提供一个一致的接口,而使这些子系统更加容易被访问的模式。该模式对外有一个统一接口,外部应用程序不用关心内部子系统的具体细节,这样会大大降低应用程序的复杂度,提高了程序的可维护性。咋一看定义好像还挺复杂哈,仔细一想,这不就是封装嘛。平时在开发中,我们经常把一些复杂逻辑封装成方法或接口来供别人调用,这就是外原创 2020-10-22 18:45:32 · 206 阅读 · 0 评论 -
设计模式详解(十)——组合模式
一、场景问题设计出省、市、区机构的区域程序代码。省市区结构如下安徽省--合肥市----肥东县--芜湖市----三山区浙江省--杭州市----滨江区--温州市----永嘉县江苏省--镇江市----京口区二、解决方案1、传统解决方案1.1、实现思路定义省市区/县三个类,省包含市,市包含区/县。代码展示区/县public class District { /** * 名称 */ private String name;原创 2020-10-14 20:04:08 · 363 阅读 · 0 评论 -
设计模式详解(九)——代理模式
一、场景问题某教务系统想要在用户业务操作前添加权限验证,以及操作过程的日志记录。请设计出一套合理的程序解决方案。二、解决方案1、传统解决方案1.1、实现思路在业务操作的前面添加权限校验,校验通过才能执行业务操作,在业务操作过程中添加相应的日志记录代码。代码展示权限校验器public class AccessValidator { /** * 权限校验 * @param role 角色 * @author xianzilei **/原创 2020-10-13 20:21:38 · 252 阅读 · 0 评论 -
设计模式详解(八)——装饰者模式
一、场景问题某咖啡店新开业,请设计一套咖啡的订单项目。咖啡的种类分为:黑咖啡、浓咖啡调料:摩卡、豆浆二、解决方案1、传统解决方案1.1、实现思路常规思路是定义一个咖啡的抽象类或接口,根据咖啡的种类和调料设计出不同的类咖啡种类黑咖啡(无添加)浓咖啡(无添加)黑咖啡(添加摩卡)浓咖啡(添加摩卡)黑咖啡(添加豆浆)浓咖啡(添加豆浆)黑咖啡(添加摩卡和豆浆)浓咖啡(添加摩卡和豆浆)1.2、传统方式实现的优缺点优点:实现简单,代原创 2020-10-09 19:47:53 · 357 阅读 · 0 评论 -
设计模式详解(七)——桥接模式
一、场景问题某系统需要实现消息推送的需求。其中消息的类型包含普通、紧急、严重三种类型,消息的发送渠道又可以分为邮件、短信等方式。请设计出一套合理的消息推送的程序。二、解决方案1、传统解决方案1.1、设计思路消息类型分为三种,消息的发送渠道又分为两种,两个不同维度可以分为2*3=6种类型。消息类型普通邮件消息普通短信消息紧急邮件消息紧急短信消息严重邮件消息严重短信消息1.2、代码实现顶层消息接口public interface Mess原创 2020-10-07 16:50:36 · 182 阅读 · 0 评论 -
设计模式详解(六)——适配器模式
这里写自定义目录标题欢迎使用Markdown编辑器**一、场景问题****二、解决方案****1、传统解决方案****2、适配器模式方案****2.1、代码实现****2.2、方案解析****三、模式剖析****1、模式定义****2、模式结构****3、模式结构图****4、优缺点****5、使用场景**四、模式扩展1、双向适配器生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章U原创 2020-10-06 19:30:21 · 297 阅读 · 0 评论 -
设计模式详解(五)——建造者模式
一、场景问题大家很多人应该都玩过LOL(英雄联盟)这款游戏,博主从S4赛季一直玩到现在,可以说这块游戏陪伴了我整个大学生涯。正好现在S10入围赛已经快接近尾声,即将到精彩的小组赛了。当前这篇文章不是讨论游戏哈。大家在刚接触这款游戏时,系统推荐的游戏角色最多的应该都是流浪法师、寒冰射手、德玛西亚之力这三个新手英雄。所以业务场景就是设计程序构造这三种角色(法师、射手和战士)。二、解决方案1、传统解决思路为了方便讲解,我们使用简单工厂模式来实现。1.1、代码展示游戏角色实体类public cla原创 2020-09-30 17:07:49 · 606 阅读 · 0 评论 -
设计模式详解(四)——原型模式
一、场景问题在电商系统中,订单服务通常是业务核心模块之一。在提交订单的过程中,往往会出现某个订单数额较大的订单,例如一些企业订单订购公司员工节假日礼品,往往会订购成千上万件,如果不做拆分,就会导致订单票据较长。此时就会有拆分订单的操作,假设最大商品数为500,订单类型为个人订单和企业订单,请设计拆分订单的程序方案(此案例来源于《研磨设计模式》一书)。二、解决方案1、常规解决思路1.1、代码展示订单抽象层(这里定义为抽象类)public abstract class AbstractOrder原创 2020-09-24 20:19:38 · 534 阅读 · 2 评论 -
设计模式详解(三)——单例模式
一、场景问题设计单体应用中的序列生成器。二、解决方案考虑到序列生成器的使用频繁性,我们可以使用单例模式,即始终只存在一个序列生成器实例,每次都调用实例来获取最新的序列,不仅减少类的资源占用,同时也保证了序列的唯一性。1、序列生成器类public class UidGenerator { /** * 唯一序列 */ private AtomicInteger uniqueSequence = new AtomicInteger(0); /**原创 2020-09-22 20:36:08 · 417 阅读 · 0 评论 -
设计模式详解(二)——抽象工厂模式
前言前面介绍了简单工厂模式和工厂方法模式。但是这两种模式对应的工厂结构过于单一(一个工厂只能生产一种产品),不适应与一些复杂的工厂等级结构,强行使用会导致工厂类的职责过于繁重,违反单一职责原则。因此我们推出抽象工厂模式。一、场景问题A、B工厂分别生产联想和戴尔品牌的笔记本,其组件包括主板、屏幕、CPU、电源等,为了简化问题,我们定义笔记本的组件包含三种:主板、屏幕、电源,请设计程序模拟客户下单某一品牌的电脑。二、解决方案根据前面学习的工厂模式,我们很容易就可以设计出实现方案,这里我们假设使用工厂方原创 2020-09-22 18:41:48 · 364 阅读 · 0 评论 -
设计模式详解(一)——工厂方法模式
前言前面我们介绍了简单工厂模式,它将创建对象的细节隐藏起来,客户端仅仅通过参数来决定生产哪种具体的产品。但是该模式有个较大的缺点,当我们增加新产品的时候就需要修改工厂类的逻辑,导致原来的商品创建逻辑可能受到影响,即违背了开闭原则。因此我们提出了工厂方法模式。一、场景问题在实际工作中,我们经常需要导出一些数据,这些数据可能是Excel模式、文本格式、XML格式或数据库脚本格式等等,总之一系列的数据文件格式,未来也有各种各样的导出格式需求.二、解决方案1、传统解决方案即简单工厂模式,缺点上面也说明了原创 2020-09-18 17:44:54 · 471 阅读 · 0 评论 -
设计模式详解(零)——简单工厂模式
前言简单工厂模式不是一个标准的设计模式,也并不属于23种设计模式中的任何一种,但是它是抽象工厂模式和工厂方法模式的基础,且在日常工作中非常常见,姑且作为学习其他设计模式的热身吧。文章讲解思路:设计模式本质就是一个解决方案。因此在后续的设计模式系列文章中,博主会首先给大家引出一个场景问题,并使用传统的面向过程编程方式解决,通过分析传统方案的弊端,并使用指定的设计模式进行优化改进,从而加深大家对设计模式及其设计理念的理解。同时也适当对设计模式进行扩展,剖析开源框架中的设计模式应用。(Java)一、场景问题原创 2020-09-16 19:55:22 · 335 阅读 · 0 评论 -
设计模式详解(开篇)——设计模式初识
一、什么是设计模式1、概念设计模式:是指在软件开发中,经过验证的,用于解决在特定环境下、重复出现的、特定问题的解决方案。我们从以上标粗的词语中理解一下设计模式的概念软件开发宏观来说,设计模式遍布各行各业,包括IT、机械、建筑、医疗等行业。由于博主是程序员,所以本文介绍的设计模式主要指的是软件开发过程中的设计模式。解决方案首先申明一下,设计模式是一个解决方案,通俗地来说,就是解决问题的方法。当时反过来说解决方案就是一个设计模式是不正确的,因为解决方案需要满足特定的条件才能算设计模式,原创 2020-09-15 20:08:47 · 236 阅读 · 0 评论