
重构与设计模式
文章平均质量分 71
代码重构是代码开发过程中核心内容,所有的开发没有办法一气呵成,设计模式是总结出来成型的一套重构技法
生活需要深度
这个作者很懒,什么都没留下…
展开
-
代码整洁之道(下篇)
信息过多:类中方法越少越好,函数知道的变量越少越好,类拥有的实体变量越少越好。隐藏数据、工具函数、常量和临时变量等,不要创建拥有大量方法/实体变量的类,不要为子类创建大量受保护变量和函数。new Math().max(a, b)比Math.max(double a, double b)愚蠢,因为max用到的全部数据来自于两个参数而非“所属”对象。// 输出:1-红色。不恰当的静态方法:倾向于选用非静态方法,如果有疑问,用非静态函数,如果的确需要静态函数,确保没机会打算让它有多态行为。期望函数忽略大小写。原创 2022-10-12 16:32:09 · 279 阅读 · 0 评论 -
代码整洁之道(上篇)
只做一件事:应该做一件事,只做一件事,做好一件事。(2)内聚:一般来说,创造极大化内聚类是不可取也不可能的,另一方面,我们希望内聚性保持较高未知,内聚性高,意味着类中的方法和变量互相依赖、互相组合成一个逻辑整体。(1)单一权责原则:系统应该由许多短小的类而不是少数巨大的类组成,每个小类封装了一个权责,只有一个修改的理由,并与其他少数类一起协同达成期望的系统行为。本文旨在讨论营地意识,此篇为理论篇,分别从命名、函数、注释、格式、对象和数据结构、错误处理、边界、单元测试、类、系统等多个方面进行阐述。原创 2022-10-12 16:31:10 · 730 阅读 · 0 评论 -
重构,改善既有代码的设计(实战篇)
1.观察amountFor函数,使用了Rental类的信息却没有使用来自Customer类的信息,函数是应该放在它所使用的数据的对象内的,所以amountFor应该要放到Rental类而非Customer类,调整代码以使用新类。好的代码应该清楚表达自己的功能,变量名称是代码清晰的关键,唯有写出人类容易理解的代码,才是好的程序员。测试需足够自动化,若新/参考字符串一致,那么OK,如果不一致,则显示问题字符串行号,测试能够自我校验,否则大把时间的对比无疑会降低开发速度。原创 2022-10-12 16:27:50 · 422 阅读 · 0 评论 -
重构,改善既有代码的设计(理论篇)
使用Move Method(当两类之间太多耦合,将某个类中的方法移动至另一类中)和Move Field(在目标类中新建一个字段,修改源字段的所有用户,令它们改用新字段)将需要修改的代码放在同一类中,若没有,就创造一个,将一系列行为放进同一类中。2. 但如果子类不想继承,新建子类的兄弟类,使用Push Down Method(方法下移:超类中的某函数只与部分子类相关,将这个函数移到相关子类中去)和Push Down Field(字段下移:超类中的某字段只与部分子类相关,将这个字段移到相关子类中去)。原创 2022-10-12 16:26:24 · 295 阅读 · 0 评论 -
重构 改善既有代码的设计 3
但是,在建立这些具有共通性的类之前,你往往无法发现这样的共通性,因此经常会在具有共通性的类出现之后,再开始建立其间的继承关系。异常只应该被用于异常的、罕见的行为,也就是哪些产生意料之外的错误的行为,而不应该成为条件检查的替代品。这样的函数被称为模板函数。你手上有个条件表达式,它根据对象类型的不同而选择不同的行为,将这个条件表达式的每个分支放进一个子类中的覆写函数中,然后将原始函数声明为抽象函数。继承是个好东西,它可以明显减少子类中的代码量,函数的重要性可能并不和它的大小成正比,在继承体系中尤然。原创 2022-10-12 16:24:33 · 117 阅读 · 0 评论 -
重构 改善既有代码设计 2
你有一个大型函数,其中对局部变量的使用使你无法采用提取函数,将这个函数放进一个单独对象中,如此一来局部变量就成了对象内的字段,然后你可以在同一个对象中将这个大型函数分解为多个小型函数。同时,针对原函数的每个临时变量和每个参数,在新类中建立一个对应的字段保存之。你的程序中,有个函数与其所在类之外的另一个类进行更多的交流,在该函数最常引用的类中建立一个有着类似行为的新函数。因为数据存在基本数据、实时数据、分钟累计数据,这种结构的代码项目中比比皆是,写的那叫一个烂,这个上传程序折磨的我苦不堪言,往事不堪回首。原创 2022-10-12 16:20:22 · 142 阅读 · 0 评论 -
重构 改善既有代码的设计 1
完成同一件事,设计不良的程序往往需要更多的代码,这常常是因为代码在不同的地方使用完全相同的语句做同样的事情。对象技术的新手通常不愿意在小任务上运用小对象,像结合数值和币种的money类、电话号码、邮政编码等的特殊字符串,看似简单,此时可以运用以对象取代数据值,将原本单独存在的数据值替换为对象,从而走出传统的洞窟,进入炙手可热的对象世界。本质上说,重构就是在代码写好之后改进它的设计。重构 既有代码的设计,一本经典神书,两年前入手,一年前看了一半,感觉一般般,今天起,再次拜读,希望会有不一样的收获!原创 2022-10-12 16:15:37 · 130 阅读 · 0 评论 -
重构,改善既有代码的设计
我们都有这样的经验,看到别人的代码时感觉就像屎一样,有一种强烈的想重写的冲动,但一定要压制住这种冲动,完全重写,可能比原来好一点,但浪费时间不说,还有可能引入原来不存在的bug,而且,你不一定比原来设计的好,也许原来的设计考虑到了一些你没考虑到的情况。所以,我们要做的重构,从小范围的重构开始。比如一个复杂的条件表达式,我们可能需要很久才能明白这个表达式的作用,这时候,抽象出来,起一个易于理解的名字,函数名字很重要,下次再见到的时候,自然知道当初的想法了,好的代码胜过注释,毕竟注释有可能更新的不是很及时。原创 2022-10-09 22:10:07 · 153 阅读 · 0 评论 -
解析器模式 -
解析器模式提供了评估语言的语法或表达式的方式。这种模式实现了一个表达式接口,该接口解释一个特定的上下文,这种模式被用在SQL解析、符号处理引擎等。1. 介绍意图:给定一个怨言,定义它的文法表示,并定义一个解析器,这个解析器使用该标识来解析语言中的句子。主要解决:对于一些固定文法构建一个解析句子的解析器。何时使用:如果一种特定类型的额问题发生的评率足够高,那么可能就值得将该问题的各个实例表述为一个简单语言中的句子。这样就可以构建一个解析器,该解析器通过解析这些句子来解决问题。如何解决:构建原创 2022-02-13 09:10:07 · 378 阅读 · 0 评论 -
访问器 -
在访问者模式中,我们使用一个访问这类,它改变了元素类的执行算法。通过这种方式,元素的执行算法可以随着访问者改变而改变。这种类型的设计模式俗语行为型模式。根据模式,元素对象以接受访问者对象,这样访问者对象可以处理元素对象上的操作。1. 介绍意图:主要将数据结构与数据操作分离。主要解决:稳定的数据结构和易变的操作耦合问题。何时使用:需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免让这些操作“污染”这些对象的类,使用访问者模式将这些类封装到类中。如何解决:在被访问的类里面加原创 2022-02-12 09:47:30 · 355 阅读 · 0 评论 -
命令模式 -
命令模式(commandPattern)是一种数据驱动的设计模式。请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令合适的对象,并把该命令传给相应的对象,该对象执行命令。1. 介绍意图:将一个请求封装成一个对象,从而使您可以用不同的请求对客户进行参数。主要解决:在软件系统中,行为请求者与行为实现着通常是一种紧耦合的关系,但某些场合,比如需要对行为进行记录、撤销或重做、事务等处理时,这种无法抵御变化的紧耦合的设计就太不合适。何时使用:再某些场合,比如要对行为“记录、撤销、原创 2022-02-12 09:46:16 · 1368 阅读 · 1 评论 -
职责链 -
职责链模式为请求创建了一个接受者兑现的链。这种模式给予请求的类型,对请求的发送者和接受者进行解耦。这种模式中,通常每个接受者都包含对另一个接受者的应用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接受者,以此类推。1. 介绍意图:避免请求发送者与接受者耦合在一起,让多个对象都有可能接受请求,将这些对象连成一条链传递请求,知道有对象处理它为止。主要解决:职责链上的处理者负责处理对象请求,客户只需要将请求发送给职责链上即可,无须关心请求的处理细节和请求的传递,所以职责链将请求的发送原创 2022-02-12 09:44:33 · 172 阅读 · 0 评论 -
迭代器 -
迭代器是编码中常用一种设计模式,这种模式用于顺序访问结合对象的元素,不需要知道集合对象的底层表示。1. 介绍意图:提供一种方法顺序访问一个聚合对象中各个元素,而又无须暴露该对象的内部表示。主要解决:不同的方式来遍历整合对象。何时使用:遍历啊一个聚合对象。如何解决:把再元素之间游走的责任交个迭代器,而不是聚合对象。关键代码:定义接口has next,next应用实例:C++内部线程迭代器结构。优点:1、它支持以不同的方式遍历一个聚合对象。 2、迭代器简化了聚合类。 3、在同一个原创 2022-02-12 09:43:19 · 96 阅读 · 0 评论 -
组合模式 -
组合模式(composite pattern),又叫部分整体模式,是用于把一组详细的对象作为一个单一的对象。组合模式一句树形结构来组合对象,用来表示部分以及整体的层次。这种模式创建了一个包含自己对象组的类,该类提供了修改相同对象的方式。1. 介绍意图:将对象组合成树形结构以表示“部分-整体”层次结构。组合模式使得用户对当个对象和组合对象的而是用具有一致性。主要解决:他们在我们树形结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以向处理简单元素一样来处理复杂元素,从而使得客户程序和复杂元素原创 2022-02-12 09:41:49 · 197 阅读 · 0 评论 -
备忘录 -
备忘录保存一个对象的某个状态,以便在适当的时候恢复对象。备忘录模式现在有内存序列化,内存编码等方式较好的替换。1. 介绍意图:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。主要解决:所谓备忘录模式就是在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样可以在以后将对象恢复到原先保存到额状态。何时使用:很多时候我们总是需要记录一个对象的内部状态,这样做的目的就是为了允许用户取消不确定或者错误的操作,能够恢复到他原先的状态该,是的他有“后悔原创 2022-02-12 09:39:57 · 405 阅读 · 0 评论 -
状态模式 -
状态模式中,类的行为是基于它的状态改变的。在状态模式中,我们创建表示各种状态的对象和一个行为随着状态的对象改变而改变的context对象。1. 介绍意图:允许对象再内部状态发生改变时改变它的行为,对象看起来好像修改了它的类。主要解决:对象的行为依赖于它的状态(属性),并且可以根据它的状态改变而改变它的相关行为。何时使用:代码中包含大量的与对象状态相关的条件语句。关键代码:通常命令模式的接口中只有一个方法,而状态模式的接口中有一个过着多个方法。而且状态模式的实现类的方法啊,一般返回值或者是原创 2022-02-12 09:37:32 · 106 阅读 · 0 评论 -
中介者模式 - 门面
中介者是用来降低多个对象和类之间的通信复杂性。这种模式提供了一种中介类,该类通常处理不同类之间的通信,并支持松耦合,使代码易于维护。用来解决系统内部网状复杂度问题。1. 介绍意图:用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显示地相互引用,从而使其耦合松散,而且可以独立地改变他们之间的交互。主要解决:对象与对象之间存在大量的关联关系,这样势必会导致系统的结构变得很复杂。同时所一个对象发生改变,我们也需要跟踪与之关联的对象,同事做出相应的处理。何时使用:多个类相互耦合,形成了网状原创 2022-02-12 09:33:15 · 332 阅读 · 0 评论 -
适配器 - 门面
适配器模式作为两个不兼容的接口之间的桥梁,它结合了两个独立接口的功能。这种模式涉及到一个单一的类,该类负责加入独立的活不兼容的接口工鞥。举个真是的例子,读卡器是作为内存卡和笔记本之间的适配器。您将内存卡插入读卡器,再将读卡器插入笔记本,这样就可以通过笔记本来读取内存卡。1. 介绍意图:将一个类的接口转换成客户希望的另外一个接口,适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。主要解决:在软件系统中,常常要将一个写“现存的对象”放到新的环境中,而新环境要求的接口是现对象不能满足原创 2022-02-12 09:16:47 · 350 阅读 · 0 评论 -
代理模式 - 门面模式
代理模式中一个类代表另外一个类的功能,以便对外界提供功能接口。1. 介绍意图:为其他对象提供一种代理以控制针对这个对象的访问。主要解决:再直接访问对象时带来的问题。比如说,要访问的对象再远程的机器上,可以这样理解,把高翠兰的外貌抽象出来,高翠兰本人和孙悟空都实现了这个接口,猪八戒访问高翠兰的时候看不出来这个是孙悟空,所以说孙悟空是高翠兰代理类。 3、买火车票不一定在火车站买,也可以去代售点。 4、一张支票或银行存单是账户中资金的代理。支票在市场交易中用来代替现金,并提供对签发人账号上资金的控制。原创 2022-02-12 08:52:41 · 452 阅读 · 0 评论 -
外观模式 - 门面
在组件构建过程中,某些接口之间的依赖常常会带来很多问题、甚至根本无法实现。采用添加一层间接(稳定)接口,来隔离本来互相紧密关联的接口是一种常见的解决方案。为子系统中的一组接口提供一个一致(稳定)的界面,façade模式定义了一个高层接口,这个接口使得这个子系统更加容易使用(复用)。更多时候是一种架构模式。外观模式(façade)隐藏系统的复杂性,并向客户提供了一个客户端可以访问的系统接口。这种模式设计到一个单一的类,该类提供了客户端请求的简化方法和对现有系统类方法的委托调用。1. 介绍意图:原创 2022-02-11 18:30:24 · 454 阅读 · 0 评论 -
创建者模式 - 对象创建
建造者模式(Builder Pattern)使用多个简单的对象一步一步构建成一个复杂的对象。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。一个 Builder 类会一步一步构造最终的对象。该 Builder 类是独立于其他对象的。1. 介绍意图:将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。主要解决:主要解决在软件系统中,有时候面临着"一个复杂对象"的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常原创 2022-02-11 17:50:43 · 242 阅读 · 0 评论 -
原型模式 - 对象创建
原型模式是用于创建重复的对象,同时又能保证性能。原型是实现了一个原型接口,该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时,则采用这种模式。例如,一个对象需要在一个高代价的数据库操作之后被创建。我们可以缓存该对象,在下一个请求时返回它的克隆,在需要的时候更新数据库,以此来减少数据库调用。1. 介绍意图:原型指定创建对象的种类,并通过拷贝这些原型创建新的对象。主要解决:在运行期建立和删除原型。何时使用:1、当一个系统应该独立于他的产品光剑,构成和表示时。2、当要实例化的类是在运行时刻原创 2022-02-11 17:48:45 · 316 阅读 · 0 评论 -
抽象工厂 - 对象创建
抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。介绍意图:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。主要解决:主要解决接口选择的问题。何时使用:系统的产品有多于一个的产品族,而系统只消费其中某一族的产转载 2022-02-11 17:45:35 · 155 阅读 · 0 评论 -
工厂方法模式 - 对象创建
通过“对象创建”模式绕开new,来避免对象创建(new)过程中所导致的紧耦合(依赖具体类),从而支持对象创建的稳定。它是接口抽象之后的第一步工作。工厂模式中再吃醋昂见对象时不会对客户端暴露创建逻辑,并且使通过使用一个共同的接口来指向新创新的对象。定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使得一个类的实例化延迟(目的:解耦,手段:虚函数)到子类1. 意图定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。主原创 2022-02-11 17:44:16 · 484 阅读 · 0 评论 -
桥接模式 - 单一职责
将抽象部分(业务功能)与实现部分(平台实现)分离,使它们都可以独立地变化。桥接是用于把抽象化与实现化解耦,是的二者可以独立变化。它通过提供抽象化和实现化之间的桥接结构,来实现二者的解耦。这种模式涉及到一个座位桥接的接口,使得实体类的功能独立于接口实现,这两种类型的类可被结构化改变而互不影响。由于某些类型的固有的实现逻辑,使得它们具有两个变化的维度,乃至多个纬度的变化。如何应对这种“多维度的变化”?如何利用面向对象技术来使得类型可以轻松地沿着两个乃至多个方向变化,而不引入额外的复杂度?原创 2022-02-11 17:33:15 · 1095 阅读 · 0 评论 -
装饰模式 Decorator Pattern - 单一职责
在软件组件的设计中,如果责任划分的不清晰,使用继承得到的结果往往是随着需求的变化,子类急剧膨胀,同时充斥着重复代码,这时候的关键是划清责任。装饰模式允许想一个现有的对象添加新的功能,同时又不改变其结构,它是作为现有的类一个包装。这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。1. 介绍意图:动态(组合)地给一个对象增加一些额外的职责。就增加功能而言,Decorator模式比生成子类(继承)更为灵活(消除重复代码 & 减少子类个数)。主要原创 2022-02-11 17:29:15 · 105 阅读 · 0 评论 -
观察者模式Observer/Event - 组件协作
对象间存在一对多关系时,则使用观察者模式(Observe Pattern)。比如,当一个对象被修改时,则会自动通知依赖他的对象。依赖关系分为编译时依赖和运行时依赖。核心是通知,是获取信息。C++不推荐多继承,但是推荐使用单继承其外都是接口或者抽象基类这种继承关系。1. 介绍意图:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。主要解决:一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作。何时使用:原创 2022-02-11 17:19:49 · 819 阅读 · 2 评论 -
策略模式 Strategy - 组件协作
定义一系列算法,把它们一个个封装起来,并且使它们可互相替换(变化)。该模式使得算法可独立于使用它的客户程序(稳定)而变化(扩展,子类化)。在策略模式中,一个类的行为或其算法可以在运行时更改。在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象的改变而改变的context对象,策略对象改变context对象的执行算法。1. 介绍意图:定义一系类的算法,把他们一个个封装起来,并且使他们可以相互替换。主要解决:在有多种算法类似的情况下面,使用if。。。else所带来的复杂和难以维护。原创 2022-02-11 17:07:47 · 497 阅读 · 0 评论 -
模板模式 Template method - 组件协作
现代软件专业分工时候的第一个结果是框架与应用程序的划分,组件协作模式通过晚期绑定。设计模式核心是在稳定点与变化点之间寻找平衡点,然后分离他们,从而管理变化。在模板模式中,一个抽象类公开定义了执行他的方法的方式/模板。他的子类按照需要从写方法实现,但调用将以抽象类中的定义的方式进行。定义一个操作中的算法的骨架 (稳定),而将一些步骤延迟(变化)到子类中。Template Method使得子类可以不改变(复用)一个算法的结构即可重定义(override 重写)该算法的某些特定步骤。1. 介绍意图:定原创 2022-02-11 17:05:08 · 369 阅读 · 0 评论 -
享元模式 - 对象性能
第一篇文章开始写原创 2021-11-23 16:09:45 · 551 阅读 · 0 评论 -
单例模式 - 对象性能
#include <stdio.h>#include <mutex>#include <vector>template < typename T > singleton{public: singleton(){}; ~singleton(){}; static T* GetInstance() { if (m_pInstance == nullptr) { std::lock_guard <std::...原创 2022-01-16 10:11:44 · 761 阅读 · 0 评论 -
设计模式 概述
课程核心能够把握松耦合设计思想、掌握面向对象设计原则、掌握重构技法改善设计、掌握GOF核心设计思想。设计模式:“每一个模式描述了一个在我们周围不断重复发生的问题, 以及该问题的解决方案的核心。这样,你就能一次又一次地使用该方案而不必做重复劳动”。向下:深入理解三大面向对象机制 • 封装,隐藏内部实现 • 继承,复用现有代码 • 多态,改写对象行为 向上:深刻把握面向对象机制所带来的抽象意义,理解如何使用 这些机制来表达现实世界,掌握什么是“好的面向对象设计”原创 2021-11-26 15:12:57 · 389 阅读 · 0 评论