![](https://img-blog.csdnimg.cn/20201014180756724.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
设计模式
文章平均质量分 89
heyuchang666
这个作者很懒,什么都没留下…
展开
-
23种设计模式(6)_结构型_适配器模式(Adapter Pattern)
适配器模式——把一个类的接口变换成客户端所期待的另一种接口,从而使原本接口不匹配而无法一起工作的两个类能够在一起工作。适配器模式有类的适配器模式和对象的适配器模式两种形式,下面我们分别讨论这两种形式的实现和给出对应的类图来帮助大家理清类之间的关系。优点:可以在不修改原有代码的基础上来复用现有类,很好地符合 “开闭原则”。可以重新定义Adaptee(被适配的类)的部分行为,因为在类适配器模式中,Adapter是Adaptee的子类。仅仅引入一个对象,并不需要额外的字段来引用Adaptee实例(这个即是优点也是原创 2015-12-27 18:22:14 · 892 阅读 · 0 评论 -
23种设计模式(1)_创建型_单例模式(Singleton Pattern)
私有的构造方法,指向自己实例的私有静态引用。以自己实例为返回值的静态的公有的方法.单例模式根据实例化对象时机的不同分为两种:一种是饿汉式单例,一种是懒汉式单例。饿汉式单例在单例类被加载时候,就实例化一个对象交给自己的引用;而懒汉式在调用取得实例方法的时候才会实例化对象。原创 2015-12-26 17:06:12 · 800 阅读 · 0 评论 -
23种设计模式(2)_创建型_工厂方法模式(Factory Method Pattern)
定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类。首先需要说一下工厂模式。工厂模式根据抽象程度的不同分为三种:简单工厂模式(也叫静态工厂模式)、本文所讲述的工厂方法模式、以及抽象工厂模式。工厂模式是编程中经常用到的一种模式。它的主要优点有:可以使代码结构清晰,有效地封装变化。在编程中,产品类的实例化有时候是比较复杂和多变的,通过工厂模式,将产品的实例化封装起来,使得调用者根本无需关心产品的实例化过程,只需依赖工厂即可得到自己想要的产品。对调用者屏蔽具体的产品类。如果原创 2015-12-26 17:22:46 · 627 阅读 · 0 评论 -
23种设计模式(4)_创建型_建造者模式(Builder Pattern)
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。首先,建造者模式的封装性很好。使用建造者模式可以有效的封装变化,在使用建造者模式的场景中,一般产品类和建造者类是比较稳定的,因此,将主要的业务逻辑封装在导演类中对整体而言可以取得比较好的稳定性。其次,建造者模式很容易进行扩展。如果有新的需求,通过实现一个新的建造者类就可以完成,基本上不用修改之前已经测试通过的代码,因此也就不会对原有功能引入风险。原创 2015-12-26 17:41:05 · 699 阅读 · 0 评论 -
23种设计模式(3)_创建型_抽象工厂模式(Abstract Factory Pattern)
当需要创建的对象是一系列相互关联或相互依赖的产品族时,便可以使用抽象工厂模式。说的更明白一点,就是一个继承体系中,如果存在着多个等级结构(即存在着多个抽象类),并且分属各个等级结构中的实现类之间存在着一定的关联或者约束,就可以使用抽象工厂模式。假如各个等级结构中的实现类之间不存在关联或约束,则使用多个独立的工厂来对产品进行创建,则更合适一点。原创 2015-12-26 17:34:16 · 583 阅读 · 0 评论 -
23种设计模式(5)_创建型_原型模式(Prototype Pattern)
用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。使用原型模式创建对象比直接new一个对象在性能上要好的多,因为Object类的clone方法是一个本地方法,它直接操作内存中的二进制流,特别是复制大对象时,性能的差别非常明显。使用原型模式的另一个好处是简化对象的创建,使得创建对象就像我们在编辑文档时的复制粘贴一样简单。因为以上优点,所以在需要重复地创建相似对象时可以考虑使用原型模式。比如需要在一个循环体内创建对象,假如对象创建过程比较复杂或者循环次数很多的话,使用原型模式不但可以简化创建过程,原创 2015-12-26 17:59:57 · 682 阅读 · 0 评论 -
设计模式中类的关系
在java以及其他的面向对象设计模式中,类与类之间主要有6种关系,他们分别是:依赖、关联、聚合、组合、继承、实现。他们的耦合度依次增强。 依赖关系的定义为:对于两个相对独立的对象,当一个对象负责构造另一个对象的实例,或者依赖另一个对象的服务时,这两个对象之间主要体现为依赖关系。定义比较晦涩难懂,但在java中的表现还是比较直观的:类A当中使用了类B,其中类B是作为类A的方法参数、方法中的局部变量、或者静态方法调用。类上面的图例中:People类依赖于Book类和Food类,Book类和Food类是作为类中方原创 2015-12-16 00:01:36 · 578 阅读 · 0 评论 -
换种思路去理解设计模式(中)
换种思路去理解设计模式(上)换种思路去理解设计模式(中)换种思路去理解设计模式(下)7 多个对象组成结构7.1 过程描述上一节介绍了如何创建一个对象。但大多数情况,一个对象是不够用的,这时候就需要把对象包装、封装、多对象组合。有时候还需要将一个组合作为一个整体使用,组合要提供对外的接口,也可能会用到系统原有的接口。下面针对每种情况详细原创 2015-12-18 12:17:22 · 738 阅读 · 0 评论 -
换种思路去理解设计模式(下)
对象行为与操作对象过程描述所谓对象行为和操作对象,需要三方面内容:l 操作过程:一般表现为一个方法。该方法接收一个对象或者组合类型的参数,然后对这个对象或者组合进行操作,例如修改属性、状态或者结构等。原创 2015-12-19 16:48:55 · 755 阅读 · 0 评论 -
换种思路去理解设计模式(上)
首先,设计模式解决的肯定是系统设计问题,而且会用到面向对象来解决的。所以,本书开头先说设计原则和面向对象。面向对象基础知识,大部分人应该都了解;至于设计原则,不了解的人必须要先了解。其次,我们将模拟一个简单的对象声明周期过程,从对象的创建、封装、组合、执行和操作,一步一步走来,会遇到许多情况和问题。针对问题,我们将通过思考,利用面向对象和设计原则,解决这个问题。而解决这个问题的方法,便是一种设计模式。最后,23种设计模式不是一盘散沙,是有关系的。就是对象的生命周期一步一步的将各个设计模式串联在了一起。对象原创 2015-12-17 22:53:32 · 778 阅读 · 0 评论 -
设计模式六大原则(3):依赖倒置原则
依赖倒置原则:A.高层次的模块不应该依赖于低层次的模块,他们都应该依赖于抽象。B.抽象不应该依赖于具体,具体应该依赖于抽象。定义:高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象。问题由来:类A直接依赖类B,假如要将类A改为依赖类C,则必须通过修改类A的代码来达成。这种场景下,类A一般是高层模块,负责复杂的业务逻辑;类B和类C是低层模块,负责基本的原子操作;假如修改类A,会给程序带来不必要的风险。原创 2015-12-27 14:13:35 · 507 阅读 · 0 评论 -
设计模式六大原则(4):接口隔离原则
接口隔离原则:使用多个专门的接口比使用单一的总接口要好。一个类对另外一个类的依赖性应当是建立在最小的接口上的。一个接口代表一个角色,不应当将不同的角色都交给一个接口。没有关系的接口合并在一起,形成一个臃肿的大接口,这是对角色和接口的污染。“不应该强迫客户依赖于它们不用的方法。接口属于客户,不属于它所在的类层次结构。”这个说得很明白了,再通俗点说,不要强迫客户使用它们不用的方法,如果强迫用户使用它们不使用的方法,那么这些客户就会面临由于这些不使用的方法的改变所带来的改变。原创 2015-12-27 14:44:39 · 581 阅读 · 0 评论 -
设计模式六大原则(5):迪米特法则
迪米特法则:迪米特法则(Law of Demeter)又叫作最少知识原则(Least Knowledge Principle 简写LKP),就是说一个对象应当对其他对象有尽可能少的了解,不和陌生人说话。英文简写为: LoD.定义:一个对象应该对其他对象保持最少的了解。迪米特法则的初衷是降低类之间的耦合,由于每个类都减少了不必要的依赖,因此的确可以降低耦合关系。但是凡事都有度,虽然可以避免与非直接的类通信,但是要通信,必然会通过一个“中介”来发生联系,例如本例中,总公司就是通过分公司这个“中介”来与分公司的员原创 2015-12-27 15:06:25 · 587 阅读 · 0 评论 -
设计模式六大原则(6):开闭原则
遵循开闭原则设计出的模块具有两个主要特征:对于扩展是开放的(Open for extension)。这意味着模块的行为是可以扩展的。当应用的需求改变时,我们可以对模块进行扩展,使其具有满足那些改变的新行为。也就是说,我们可以改变模块的功能。对于修改是关闭的(Closed for modification)。对模块行为进行扩展时,不必改动模块的源代码或者二进制代码。模块的二进制可执行版本,无论是可链接的库、DLL或者.EXE文件,都无需改动。原创 2015-12-27 15:15:26 · 668 阅读 · 0 评论 -
设计模式六大原则(1):单一职责原则
不要存在多于一个导致类变更的原因。通俗的说,即一个类只负责一项职责。可以降低类的复杂度,一个类只负责一项职责,其逻辑肯定要比负责多项职责简单的多;提高类的可读性,提高系统的可维护性;变更引起的风险降低,变更是必然的,如果单一职责原则遵守的好,当修改一个功能时,可以显著降低对其他功能的影响。 需要说明的一点是单一职责原则不只是面向对象编程思想所特有的,只要是模块化的程序设计,都适用单一职责原则。原创 2015-12-26 18:28:28 · 453 阅读 · 0 评论 -
23种设计模式(23)_行为型_访问者模式(Vistor Pattern)
定义:封装某些作用于某种数据结构中各元素的操作,它可以在不改变数据结构的前提下定义作用于这些元素的新的操作。类型:行为类模式。符合单一职责原则:凡是适用访问者模式的场景中,元素类中需要封装在访问者中的操作必定是与元素类本身关系不大且是易变的操作,使用访问者模式一方面符合单一职责原则,另一方面,因为被封装的操作通常来说都是易变的,所以当发生变化时,就可以在不改变元素类本身的前提下,实现对变化部分的扩展。扩展性良好:元素类可以通过接受不同的访问者来实现对不同操作的扩展。原创 2015-12-27 16:35:28 · 672 阅读 · 0 评论 -
23种设计模式(22)_行为型_责任链模式(Chain of Responsibility Pattern)
定义:使多个对象都有机会处理请求,从而避免了请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。责任链模式与if…else…相比,他的耦合性要低一些,因为它把条件判定都分散到了各个处理类中,并且这些处理类的优先处理顺序可以随意设定。责任链模式也有缺点,这与if…else…语句的缺点是一样的,那就是在找到正确的处理类之前,所有的判定条件都要被执行一遍,当责任链比较长时,性能问题比较严重。原创 2015-12-27 16:45:52 · 535 阅读 · 0 评论 -
23种设计模式(21)_行为型_策略模式(Stragety Pattern)
定义:定义一组算法,将每个算法都封装起来,并且使他们之间可以互换。策略模式的主要优点有:策略类之间可以自由切换,由于策略类实现自同一个抽象,所以他们之间可以自由切换。易于扩展,增加一个新的策略对策略模式来说非常容易,基本上可以在不改变原有代码的基础上进行扩展。避免使用多重条件,如果不使用策略模式,对于所有的算法,必须使用条件语句进行连接,通过条件判断来决定使用哪一种算法,在上一篇文章中我们已经提到,使用多重条件判断是非常不容易维护的。原创 2015-12-27 16:54:29 · 774 阅读 · 0 评论 -
23种设计模式(7)_结构型_桥接模式(Bridge Pattern)
桥接模式即将抽象部分与实现部分脱耦,使它们可以独立变化。对于上面的问题中,抽象化也就是RemoteControl类,实现部分也就是On()、Off()、NextChannel()等这样的方法(即遥控器的实现),上面的设计中,抽象化和实现部分在一起,桥接模式的目的就是使两者分离,根据面向对象的封装变化的原则,我们可以把实现部分的变化(也就是遥控器功能的变化)封装到另外一个类中,这样的一个思路也就是桥接模式的实现,大家可以对照桥接模式的实现代码来解决我们的分析思路。原创 2015-12-27 18:28:21 · 1245 阅读 · 0 评论 -
23种设计模式(9)_结构型_组合模式(Composite Pattern)
组合模式的优点:组合模式使得客户端代码可以一致地处理对象和对象容器,无需关系处理的单个对象,还是组合的对象容器。将”客户代码与复杂的对象容器结构“解耦。可以更容易地往组合对象中加入新的构件。缺点:使得设计更加复杂。客户端需要花更多时间理清类之间的层次关系。(这个是几乎所有设计模式所面临的问题)。原创 2015-12-27 18:38:55 · 952 阅读 · 0 评论 -
23种设计模式(10)_结构型_外观模式(Facade Pattern)
外观模式提供了一个统一的接口,用来访问子系统中的一群接口。外观定义了一个高层接口,让子系统更容易使用。使用外观模式时,我们创建了一个统一的类,用来包装子系统中一个或多个复杂的类,客户端可以直接通过外观类来调用内部子系统中方法,从而外观模式让客户和子系统之间避免了紧耦合。优点:外观模式对客户屏蔽了子系统组件,从而简化了接口,减少了客户处理的对象数目并使子系统的使用更加简单。外观模式实现了子系统与客户之间的松耦合关系,而子系统内部的功能组件是紧耦合的。松耦合使得子系统的组件变化不会影响到它的客户。缺点:如果增加原创 2015-12-27 20:37:23 · 687 阅读 · 0 评论 -
23种设计模式(11)_结构型_享元模式(Flyweight Pattern)
享元模式——运用共享技术有效地支持大量细粒度的对象。享元模式可以避免大量相似类的开销,在软件开发中如果需要生成大量细粒度的类实例来表示数据,如果这些实例除了几个参数外基本上都是相同的,这时候就可以使用享元模式来大幅度减少需要实例化类的数量。如果能把这些参数(指的这些类实例不同的参数)移动类实例外面,在方法调用时将他们传递进来,这样就可以通过共享大幅度地减少单个实例的数目。优点:降低了系统中对象的数量,从而降低了系统中细粒度对象给内存带来的压力。缺点:为了使对象可以共享,需要将一些状态外部化,这使得程序的逻辑原创 2015-12-27 20:42:00 · 672 阅读 · 0 评论 -
23种设计模式(12)_结构型_代理模式(Proxy Pattern)
代理模式——就是给某一个对象提供一个代理,并由代理对象控制对原对象的引用。在一些情况下,一个客户不想或者不能直接引用一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。例如电脑桌面的快捷方式就是一个代理对象,快捷方式是它所引用的程序的一个代理。优点:代理模式能够将调用用于真正被调用的对象隔离,在一定程度上降低了系统的耦合度;代理对象在客户端和目标对象之间起到一个中介的作用,这样可以起到对目标对象的保护。代理对象可以在对目标对象发出请求之前进行一个额外的操作,例如权限检查等。缺点:由于在客户端和真实原创 2015-12-28 12:10:29 · 739 阅读 · 0 评论 -
23种设计模式(8)_结构型_装饰者模式(Decorator Pattern)
装饰者模式优点:装饰这模式和继承的目的都是扩展对象的功能,但装饰者模式比继承更灵活。通过使用不同的具体装饰类以及这些类的排列组合,设计师可以创造出很多不同行为的组合。装饰者模式有很好地可扩展性。缺点:装饰者模式会导致设计中出现许多小对象,如果过度使用,会让程序变的更复杂。并且更多的对象会是的差错变得困难,特别是这些对象看上去都很像。原创 2015-12-27 18:33:59 · 655 阅读 · 0 评论 -
23种设计模式(13)_行为型_模版方法模式(Template Method)
定义一个操作中算法的框架,而将一些步骤延迟到子类中,使得子类可以不改变算法的结构即可重定义该算法中的某些特定步骤。这就是模版方法模式。大部分刚步入职场的毕业生应该都有类似B的经历。一个复杂的任务,由公司中的牛人们将主要的逻辑写好,然后把那些看上去比较简单的方法写成抽象的,交给其他的同事去开发。这种分工方式在编程人员水平层次比较明显的公司中经常用到。比如一个项目组,有架构师,高级工程师,初级工程师,则一般由架构师使用大量的接口、抽象类将整个系统的逻辑串起来,实现的编码则根据难度的不同分别交给高级工程师和初级工原创 2015-12-26 18:37:06 · 654 阅读 · 0 评论 -
23种设计模式(14)_行为型_命令模式(Command Pattern)
定义:将一个请求封装成一个对象,从而让你使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能。命令模式的封装性很好:每个命令都被封装起来,对于客户端来说,需要什么功能就去调用相应的命令,而无需知道命令具体是怎么执行的。比如有一组文件操作的命令:新建文件、复制文件、删除文件。如果把这三个操作都封装成一个命令类,客户端只需要知道有这三个命令类即可,至于命令类中封装好的逻辑,客户端则无需知道。其次,命令模式的扩展性很好,在命令模式中,在接收者类中一般会对操作进行最基本的封装,命令原创 2015-12-27 16:39:44 · 742 阅读 · 0 评论 -
23种设计模式(15)_行为型_迭代器模式(Iterator Pattern)
定义:提供一种方法访问一个容器对象中各个元素,而又不暴露该对象的内部细节。迭代器模式的优点有:简化了遍历方式,对于对象集合的遍历,还是比较麻烦的,对于数组或者有序列表,我们尚可以通过游标来取得,但用户需要在对集合了解很清楚的前提下,自行遍历对象,但是对于hash表来说,用户遍历起来就比较麻烦了。而引入了迭代器方法后,用户用起来就简单的多了。可以提供多种遍历方式,比如说对有序列表,我们可以根据需要提供正序遍历,倒序遍历两种迭代器,用户用起来只需要得到我们实现好的迭代器,就可以方便的对集合进行遍历了。封装性良好原创 2015-12-27 17:25:31 · 601 阅读 · 0 评论 -
23种设计模式(16)_行为型_观察者模式(Observer Pattern)
定义:定义对象间一种一对多的依赖关系,使得当每一个对象改变状态,则所有依赖于它的对象都会得到通知并自动更新。观察者与被观察者之间是属于轻度的关联关系,并且是抽象耦合的,这样,对于两者来说都比较容易进行扩展。观察者模式是一种常用的触发机制,它形成一条触发链,依次对各个观察者的方法进行处理。但同时,这也算是观察者模式一个缺点,由于是链式触发,当观察者比较多的时候,性能问题是比较令人担忧的。并且,在链式结构中,比较容易出现循环引用的错误,造成系统假死。原创 2015-12-27 16:22:46 · 624 阅读 · 0 评论 -
23种设计模式(17)_行为型_中介者模式(Mediator Pattern)
定义:用一个中介者对象封装一系列的对象交互,中介者使各对象不需要显示地相互作用,从而使耦合松散,而且可以独立地改变它们之间的交互。一般来说,同事类之间的关系是比较复杂的,多个同事类之间互相关联时,他们之间的关系会呈现为复杂的网状结构,这是一种过度耦合的架构,即不利于类的复用,也不稳定。例如在下图中,有六个同事类对象,假如对象1发生变化,那么将会有4个对象受到影响。如果对象2发生变化,那么将会有5个对象受到影响。也就是说,同事类之间直接关联的设计是不好的。原创 2015-12-27 15:57:15 · 750 阅读 · 0 评论 -
23种设计模式(18)_行为型_备忘录模式(Memento Pattern)
定义:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样就可以将该对象恢复到原先保存的状态。备忘录模式的优点有:当发起人角色中的状态改变时,有可能这是个错误的改变,我们使用备忘录模式就可以把这个错误的改变还原。备份的状态是保存在发起人角色之外的,这样,发起人角色就不需要对各个备份的状态进行管理。备忘录模式的缺点:在实际应用中,备忘录模式都是多状态和多备份的,发起人角色的状态需要存储到备忘录对象中,对资源的消耗是比较严重的。原创 2015-12-27 17:39:58 · 529 阅读 · 0 评论 -
23种设计模式(19)_行为型_解释器模式(Interpreter Pattern)
定义:给定一种语言,定义他的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中句子。解释器是一个简单的语法分析工具,它最显著的优点就是扩展性,修改语法规则只需要修改相应的非终结符就可以了,若扩展语法,只需要增加非终结符类就可以了。但是,解释器模式会引起类的膨胀,每个语法都需要产生一个非终结符表达式,语法规则比较复杂时,就可能产生大量的类文件,为维护带来非常多的麻烦。同时,由于采用递归调用方法,每个非终结符表达式只关心与自己相关的表达式,每个表达式需要知道最终的结果,必须通过递归方式,无论是面向原创 2015-12-27 17:29:43 · 670 阅读 · 0 评论 -
23种设计模式(20)_行为型_状态者模式(State Pattern)
状态模式——允许一个对象在其内部状态改变时自动改变其行为,对象看起来就像是改变了它的类。状态者模式的主要优点是:将状态判断逻辑每个状态类里面,可以简化判断的逻辑。当有新的状态出现时,可以通过添加新的状态类来进行扩展,扩展性好。优点是:将状态判断逻辑每个状态类里面,可以简化判断的逻辑。当有新的状态出现时,可以通过添加新的状态类来进行扩展,扩展性好。原创 2015-12-27 18:13:36 · 718 阅读 · 0 评论 -
设计模式六大原则(2):里氏替换原则
里氏替换原则通俗的来讲就是:子类可以扩展父类的功能,但不能改变父类原有的功能。它包含以下4层含义:子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法。子类中可以增加自己特有的方法。当子类的方法重载父类的方法时,方法的前置条件(即方法的形参)要比父类方法的输入参数更宽松。当子类的方法实现父类的抽象方法时,方法的后置条件(即方法的返回值)要比父类更严格。原创 2015-12-26 18:34:36 · 817 阅读 · 0 评论