![](https://img-blog.csdnimg.cn/20201014180756754.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
设计模式
Wenlong_L
这个作者很懒,什么都没留下…
展开
-
程序设计原则之依赖倒置原则
一、什么是依赖倒置原则高层模块的实现尽量不要依赖低层模块的实现,他们应该共同依赖抽象尽量面向接口或抽象编程,而不是面向实现编程,也就是说要从接口或者抽象扩展,而不是从实现扩展二、看一个高层模块依赖低层模块的例子以学习课程为例:上面这个输出的是学习java课程,如果想要扩展学习前端课程,就得修改低层的Lwl实现类:上面的软件设计是很不科学的,修改低层实现比较容...原创 2018-09-16 14:26:14 · 324 阅读 · 0 评论 -
设计模式之单例模式四(饿汉式)
前面讲了懒汉式的单例模式,所谓懒汉式就是延迟加载,什么时候需要什么时候构造。前面的博客中讲了两种实现方法。第一种懒汉式的实现是在getInstance中直接new一个单例对象,这种实现方法就得自己考虑线程安全而加锁,具体加锁的实现也讲了两种方法,一种是基于同步方法;另一种是采用double check的方法。第二种懒汉式的实现是采用私有静态内部类的方式进行延迟加载,让单例对象在内部类的初始化阶段进...原创 2018-09-19 11:35:40 · 2742 阅读 · 0 评论 -
设计模式之装饰者模式
我们常见的面向对象的程序扩展方式是采用继承,而装饰者模式也是程序扩展的一种方式,其也是通过继承实现,一般装饰者继承被装饰者,相比于继承的静态扩展,装饰者模式可以达到动态扩展的功能,下面我们看一下使用继承与装饰者模式实现不同的扩展时的区别:场景:假如路边的摊贩卖煎饼,一个煎饼8元,煎饼可以加鸡蛋,可以加香肠,加一个鸡蛋加1元,加一根香肠加2元,鸡蛋与香肠的数量不限。采用继承的方式实现:...原创 2018-09-24 10:53:37 · 982 阅读 · 0 评论 -
设计模式之适配器模式
一、适配器模式适配器可想而知是为了解决兼容问题,将一个类的接口转化为另一种目标接口形式,使得原本两个接口不兼容的类可以一起工作,这就是适配者模式,适配者模式一般不用在软件的设计阶段,一般是用在维护阶段,或者是需要使用别的厂家提供的功能上能达到要求但是接口不兼容的情况。适配者模式主要分为类适配者模式与对象适配者模式,类适配者模式主要采用继承的方法,可以调用父类的实际解决问题的方法,对象适配器模式...原创 2018-09-24 15:45:43 · 168 阅读 · 0 评论 -
设计模式之享元模式
享元模式是指尽量少的创建对象,做到对象的复用,少的对象就可以节省内存空间,同时少创建(new)对象也可以减少时间上的开销,还有一些系统的固有资源是有限的,比如文件句柄等,这些都要合理的进行复用,享元模式就是一个很好的体现。但是享元模式由于共享对象,可能会造成线程不安全,这是非常应该注意的,同时享元会造成系统的复杂性,如果由于客户端对具体享元的形式不清楚,可能会造成程序上的阅读障碍,例如对于Inte...原创 2018-09-24 21:41:10 · 148 阅读 · 0 评论 -
设计模式之组合模式
有一些对象由一些单个对象组成,我们称这个对象为组合对象,组合对象与单个对象之间也呈现树形关系,我们可以将组合对象与单个对象都继承自相同的抽象或者实现相同的接口,使得对组合对象与单个对象进行统一的访问,这样就可以简化客户端代码的实现。但是一旦在程序中涉及到对组合对象与单个对象具体的类型限定时,就不能依赖本有的类型系统,我们应该在运行时进行类型检查,因为他们来自相同的接口;再者如果组合对象与单个对象功...原创 2018-09-25 09:40:19 · 116 阅读 · 0 评论 -
设计模式之桥接模式
一、桥接模式介绍桥接模式是指将程序的抽象部分与具体实现部分进行分离,抽象部分与具体实现部分作为两个维度,可以分别进行扩展,也就是说抽象部分有其抽象类与具体实现类,具体实现部分也有其抽象类与具体实现类,这样两个维度实现解耦,具体功能的实现由抽象部分委托给具体实现部分,这符合开闭原则。而所谓桥接,就是将抽象部分的类与具体实现部分的类通过组合的方式进行串联起来,这符合组合复用原则。抽象部分与具体实现...原创 2018-09-25 11:28:50 · 182 阅读 · 0 评论 -
设计模式之代理模式
一、什么是代理模式代理模式即找一个中介类代理控制访问目标类,可以将客户端与目标类进行隔离,同时在代理类中可以增强目标类的方法调用。代理模式又分为静态代理与动态代理,静态代理指直接创建代理类,在代理类中对目标类的方法进行加强。而动态代理只能针对对实现了接口的目标类,代理类实现了invocationHandler接口,在使用动态代理调用目标类中的方法时由jvm动态创建代理类对象。代理的缺点同样存在...原创 2018-09-25 20:07:36 · 263 阅读 · 0 评论 -
设计模式之模板模式
所谓模板就是定义了一个算法的基本骨架,也就是说一个算法的步骤的执行顺序是固定的,算法中有些步骤是不变的,有些步骤是根据具体情况可变的,我们可以将这些不变的全部抽象在父类中实现,而将可变的部分在不同的子类中具体实现,这样可以提高复用性与扩展性。算法中不能变的步骤一般申明为final,可以被重写的方法一般称为钩子方法,即在父类中给一个默认实现,在子类中可以重写,一定要在子类中进行实现的申明为抽象方法。...原创 2018-09-25 22:11:00 · 234 阅读 · 0 评论 -
设计模式之单例模式五(序列化与反序列化破坏)
单例模式的核心是要保证单例,但是在将一个实例序列化到一个文件中后,再反序列化得到一个实例,这两个实例是不同的,这就违反了单例原则,如下面恶汉式单例模式对序列化的测试:由上面的打印信息可知得到的是两个不同的实例,通过调试跟代码可以很容易发现,在反序列化时通过反射newInstance了一个新的实例,我们可以通过下面方法防止这种序列化与反序列化的破坏:上面的输出信息中可...原创 2018-09-22 11:05:37 · 586 阅读 · 0 评论 -
设计模式之单例模式六(防反射攻击)
一、防反射攻击在单例模式的设计过程中,我们说过很关键的一点是一定要将构造器设计为私有构造器,因为这样可以防止从外部构造对象。但是这样真的就会安全吗,答案肯定是不一定的。我们知道通过反射我们可以获取类中的域、方法、构造器,可以修改他们的访问权限,这样可以通过反射构造对象。如下所示:上面的例子就是一个反射破坏的例子,针对的是恶汉式的单例模式,我们可以稍作修改防止这种反射攻击:...原创 2018-09-22 16:55:31 · 2011 阅读 · 1 评论 -
设计模式之单例模式七(使用枚举类的最佳实践)
前面讲了单例模式的防序列化破坏与防反射攻击,下面讲一下单例模式的最佳实践----使用枚举类实现单例模式,借助枚举类天然的在IO类与反射类方面的特殊处理,可以天然的防反射攻击,防序列化与反序列化破坏。这样实现的单例模式既简单又安全。一、反射攻击的例子上面可以看出通过反射构造实例时抛出了异常,我们进入到newInstance方法中可以看到下面这一行代码:在newInstan...原创 2018-09-22 21:18:53 · 2902 阅读 · 0 评论 -
设计模式之单例模式三(基于类初始化延迟的懒汉式单例)
前一篇博客中采用double check的方式减轻了同步锁的开销,为了防止指令重排序引起的错误,使用了volatile关键字,该关键字的主要作用有两个:一、内存的可见性;二、防止局部指令的重排序。在这里由于指令重排序可能导致另一个线程取到的对象还未被初始化的问题可以采用第二种方法实现,也就是说让另一个线程看不到这种重排序。这就要引入采用类初始化加载的方式。类初始化发生在什么时候呢?当第一次...原创 2018-09-19 10:03:10 · 519 阅读 · 0 评论 -
设计模式之外观模式
一、外观模式所谓的外观模式,即一个门面类,门面类负责和各个子系统之间交互,执行相应的交互逻辑,客户端直接与门面类交互,使得客户端与各子系统之间隔离。对于子系统繁多,业务复杂的场景很实用,从上面的解释中也看到了外观模式是迪米特原则一个很好的应用,其秉承着客户端最少知道的思想。二、业务场景假设一个网站做活动,需要添加积分兑换礼物的业务,积分兑换礼物主要分三个模块,一个是资格校验(看一个人拥...原创 2018-09-23 20:32:55 · 153 阅读 · 0 评论 -
程序设计原则之接口隔离原则
一、什么是接口隔离原则尽量使用多个专有接口,而不是使用单一的总接口,客户端不应该依赖它不要的接口方法但是接口数量也不能过多,要适量,否则会增加程序设计的复杂性二、一个单一总接口的例子其类图如下:这样设计就违背了接口隔离的原则,不是所有的鸟都能游泳和飞翔,但是这样实现的Bird类型受限于单一总接口的形式,必须实现这两个方法,哪怕是两个空方法;同样的道理,狗并不能飞...原创 2018-09-16 17:01:19 · 332 阅读 · 0 评论 -
程序设计原则之迪米特原则
一、什么是迪米特原则迪米特原则也叫最小知道原则,即对其他的类尽量保持最少知道。只关心自己的直接朋友类,而不关心其他的类。直接朋友类:出现在自己的域中、方法入参中、方法出参中的类叫直接朋友类;那些在方法中出现的局部类不叫直接朋友类。二、结合场景分析假设这么一个场景:一个培训机构的老板叫小组领导查看开设的课程数量。老板应该只和小组领导保持直接朋友,而不管课程,直接下发命令给组领导后...原创 2018-09-16 19:19:05 · 280 阅读 · 0 评论 -
程序设计原则之里氏替代原则
一、什么是里氏替代原则定义:T1类的对象O1,T2类的对象O2,如果在程序P中将T1的对象O1全部替换成T2的对象O2,程序P的行为不发生变化,则我们说T2是T1的子类。定义引申:1、子类可以扩展父类的方法,但最好不要重写覆盖父类已有的非抽象方法。2、子类重写/重载父类的方法时入参类型的范围不应该缩小,也就是说应该是原入参类型或者是其父类。3、子类重写/重载父类的方法时出参...原创 2018-09-17 08:47:20 · 208 阅读 · 0 评论 -
程序设计原则之组合/聚合复用原则
一、什么是组合/聚合复用原则尽量采用组合(contains-a)、聚合(has-a)的方式而不是继承(is-a)的关系来达到软件的复用目的组合/聚合优点:类之间的耦合比较低,一个类的变化对其他类造成的影响比较少缺点:类的数量增多实现起来比较麻烦继承的优点:由于很多方法父类已经实现,子类的实现会相对比较简单缺点:将父类暴露给了子类,一定程度上破坏了封装性,父类的改...原创 2018-09-17 10:23:50 · 1079 阅读 · 0 评论 -
设计模式之简单工厂模式
一、什么是简单工厂模式采用工厂对象的方法统一生产不同的产品对象的实例。二、场景分析假设一个平台上有各种各样的学习视频,以java与python课程为例,写出下面业务代码:上面这种写法就是一种很常规的写法,需要什么样课程的实例就new一个什么样的对象,上面这种模拟情况所有的类都在一个包中,对于导入包依赖的麻烦之处没有体现出来,但是此问题是存在的,如果我们将生产这些课程...原创 2018-09-17 15:21:50 · 152 阅读 · 0 评论 -
设计模式之工厂方法
一、什么是工厂方法定义一个工厂的抽象,提供一个契约与规定,将具体创建产品类的任务交给该抽象的实现,一个具体工厂的实现负责一个产品类的创建。优点:符合开闭原则,当有新的产品类加入时,只需要扩展工厂的抽象,不必要更改原来已有的工厂类的实现,这一点比简单工厂要好一些。缺点:当有很多产品类时,就需要引入很多工厂类的实现,可能会导致类的数量过多甚至爆炸,使得系统复杂性变高。二、具体的...原创 2018-09-17 19:12:56 · 104 阅读 · 0 评论 -
设计模式之抽象工厂
一、什么是抽象工厂抽象工厂提供一次性生产一个产品族中不同产品的接口,由各个具体产品族的工厂方法实现这些接口,一个产品族工厂对应一个产品族的创建优势:应用层无需关心产品的具体实现,只用借助相应的工厂方法就能创建产品。相对于工厂方法,抽象工厂将一个产品族的产品一起创建,这样可以减少类的创建,减少提交大量重复的代码。缺点:由于抽象工厂提供的是一次性创建产品族中所有产品的接口,故只适合...原创 2018-09-18 09:14:37 · 175 阅读 · 0 评论 -
设计模式之建造者模式
一、什么是建造者模式对于一个复杂的对象,由多个组件构成(属性很多),将对象的构造与表示分离,使得同样的构造过程可以创造不同的表现,也就是说组件相同,但是构造的顺序可以不同,最终可以创建具有不同属性的对象。建造者模式适用于复杂的对象,应用程序不需要知道具体的构造细节,只负责使用构造出来的对象。二、具体的场景分析场景:一门课程有多个属性,我们要获取这门课程,客户端不需要知道课程具体...原创 2018-09-18 16:03:29 · 119 阅读 · 0 评论 -
设计模式之单例模式一(懒汉式)
单例模式:只保证对象的一个实例,这样可以节约内存,防止对资源的多重占用,设置全局访问点,严格控制访问。但是由于没有接口,所以扩展起来相对麻烦。下面是单例模式的一种实现方式(懒汉式):上面这种单例模式的实现是存在问题的,上面是在多线程中,其实现是非线程安全的,采用多线程debug的方式,设置如上所示的断点,当线程一执行完判断lazySingleton对象是否为空后,认为干预执...原创 2018-09-18 20:21:58 · 285 阅读 · 0 评论 -
设计模式之单例模式二(懒汉式double check)
上一篇文章中的懒汉式单例模式采用同步方法保证了线程安全,但是开销很大,每次执行该方法都会检查锁。下面采用double check的方式进行改写,下面这种实现看似可行,实则有缺陷,具体缺陷在后文分析:注意上面第二幅图中对lazyDoubleCheckSingleton对象创建时的解析,该创建过程实际上是分为三个步骤的,一、分配内存;二、初始化内存;三、将lazyDoubleCheck...原创 2018-09-18 21:58:39 · 581 阅读 · 0 评论 -
设计模式之原型模式
一、原型模式原型模式:创建一个原型模板,用此模板来创建对象,主要使用其clone方法。当一个对象的构造过程太复杂,消耗的资源太多,或者是需要创建太多这样对象的实例,比如在一个循环中不停的创建对象,采用原型模式是比较好的选择。原型模式主要实现cloneable接口,重写clone方法,使用重写的clone方法进行新对象的构建,所以需要格外小心的是浅拷贝与深拷贝的问题,由于创建的是一个个不同的实例...原创 2018-09-23 16:47:49 · 122 阅读 · 0 评论 -
设计模式之单例模式八(采用ThreadLocal实现)
ThreadLocal可以保证同一个线程中保留一份实例,对不同的线程,都有这个实例的一个副本,这样保证线程安全。在不考虑反射攻击与序列化与反序列化破坏的情况下,下面这一种单例模式的实现也有可取之处:从上面的输出结果可以看到同一个线程main中的对象是同一个,不同线程Thread0与Thread1中的对象不同。保证了一个线程中一个单例副本。...原创 2018-09-23 09:40:18 · 1220 阅读 · 0 评论