Thanks to visit codestin.com
Credit goes to github.com

Skip to content

VbiosWen/Design-pattern

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

78 Commits
 
 
 
 
 
 

Repository files navigation

Design-pattern

java设计模式学习以及个人理解

一.设计模式七大原则

1.单一性原则(SRP)

单一性原则在我看来就是需要每个类各司其职,做好自己的工作。比如说UserDo类,就是存放用户的信息,与数据库字段进行映射DBConnection类,就是连接数据库,获取数据库连接。DBOperation类就是实现数据库的操作,执行sql语句。

2.开闭原则(OCP)

开闭原则的定义为一个软件实体应该对扩展开放,对修改关闭。即软件实体应该尽量在不修改代码的情况下对外扩展。作用在一个功能上就是比如说一个动物群,里面有猴子,猪等,现在想知道这些东西都吃什么,通过定义一个抽象类。将动物的共同特点在抽象类定义,然后通过继承的方式,使得各个动物吃不同的食物。然后通过一个动物基类去获取这些动物,通过传入不同的对象,来获取动物吃的食物。

3.里氏代换原则(LCP)

里氏代换原则定义为所有引用基类(父类)的地方必须能透明地使用其子类的对象。比如说需要给CommonCustomer和VIPCustomer发送邮件,而且二者发送邮件的方式相同,通过LCP定义我们可以使用基类包含需要发送邮件的所有属性,然后commonCustomer和VIPCustomer通过继承BaseCustomer的方式来继承父类的所有属性,在发送的时候只要将基类对象baseCustomer传给emailSender的send方法,就能实现给不同级别的人发送邮件。

4.依赖倒转原则(DIP)

依赖倒转原则定义为抽象不应该依赖于细节,细节应该依赖于抽象。意思就是不应该针对实现编程,应该针对接口编程。依赖倒转原则要求尽量不要引用具体的实现类,而是通过实体类所对应的基类(抽象类),基于这个原则,就要避免在子类中定义和实现自己的方法,保证所有的方法和属性都在基类(抽象类)中定义,而子类则只需要实现基类中的抽象方法就行,这种方法能使系统具有很好的灵活性。这就要求我们在编码前需要进行需求分析,规划一下系统。

5.接口隔离原则(ISP)

接口隔离原则定义为使用多个专门的接口,而不是使用一个单一的总接口。这就告诉我们需要在接口设计时将接口分为一个个小的接口,每一个接口承担一种相对独立的角色,划分规则有两种:1.角色隔离原则,2.定制服务。

6.合成复用原则(CRP)

合成复用原则定义为尽量使用对象组合而不是继承来达到复用的目的。尽量使用对象组合而不是继承并不是说都用对象组合,我们在考虑合成复用原则的时候要根据对象之间的关系确定,如果对象之间是Has-A关系,则用对象组合,如果Is-A的关系,则采用继承的方式。继承一个非常大的缺点就是如果基类发生改变,子类的实现不得不发生改变,没有足够的灵活性。

7.迪米特法则

迪米特法则的定义为一个软件实体应尽可能少地与其他实体发生相互作用。在此规则下,各个实体之间相互关联就很少了,能使系统遵循低耦合的规则。迪米特法则有一下几点规则,对于一个对象,其朋友包含一下几类:
1.当前对象本身(this)
2.以参数形式传入到当前方法中的对象
3.当前对象的成员对象
4.如果当前对象的成员对象是一个集合,那么集合内的元素也是他的朋友
5.当前对象所创建的对象

二.六个创建型模式

1.简单工厂模式

简单工厂模式不属于GOF23中设计模式,但是在软件开发应用中使用比较频繁。作为工厂模式的‘小弟’,我们有必要了解他。简单工厂模式包含以下角色:
1.抽象产品角色(Product)
2.具体产品角色(ConcreteProduct)
3.工厂角色(Factory)
具体模型如下:
简单工厂模式模型图
优点:简单工厂方法将创建产品的细节隐藏,通过对工厂类传入一个参数,就能根据参数创建对应的产品。使得系统的扩展性很好,如果要加入一个新的产品,只要继承抽象产品角色,并在工厂类中设置参数,就可以了。 实现了对象的使用和创建的分离,通过引入配置文件,可以帮助我们在不修改任何代码的情况下获取到不同的产品
缺点:因为每次新增一个产品就需要修改工厂角色的代码,所以不符合开闭原则。由于工厂类集合了所有的产品的创建过程,一旦工厂类无法使用,则整个系统就不能使用,工厂类与产品类的耦合度太高。

2.工厂模式

在简单工厂模式中,因为只有一个工厂类,导致整个系统的耦合度非常高,因此工厂模式就是为了解决这个问题。
在工厂模式中,通过定义一个抽象的工厂类,通过对产品进行分类,提供给不同的工厂类进行生产。
工厂模式主要包括以下角色:
1.抽象工厂角色(abstract factory)
2.具体工厂角色(factory)
3.抽象产品角色(abstract product)
4.具体产品角色(product)
模型图为:
工厂模式模型图
优点:
1.工厂模式中,用来生产具体产品的细节被隐藏,用户只需要关心产品所对应的工厂就行了,不需要关心具体细节,甚至不需要知道具体产品类的类名。
2.由于工厂和产品的多态性,可以让工厂自主确定生产何种产品,而且生产产品的具体细节隐藏在工厂内部。工厂模式又称为多态工厂模式,就正是因为所有的具体工厂类都具有同一个抽象的父类。
3.在加入新产品的情况下,无需修改工厂类,只要添加具体的产品类以及工厂类就能实现了,这样系统的扩展性就很好了,完全符合“开闭原则”。
缺点:
1.在添加新产品的时候,不仅要添加新的产品类,还要添加具体的产品工厂类,类的个数成对增加,加大了系统的复杂度,增加了系统的开销。
2.由于考虑到系统的扩展性,需要引入抽象层,在客户端代码中均使用抽象层定义,增加了系统的抽象度和理解难度。在实现中,还需要使用反射,DOM等手段,增加了系统的实现难度。

3.抽象工厂模式

在工厂模式中,因为每一个产品就对应一个工厂类,导致了系统很大的开销,所以我们考虑使用抽象的思想,将产品进行分类,然后建立产品组的工厂,这样就节省了很多工厂类的开销。
抽象工厂模式主要包括以下角色:
1.抽象工厂角色(将工厂分类考虑)
2.具体工厂角色
3.抽象产品角色
4.具体产品角色
模型图为:
抽象工厂模式模型图
优点:抽象工厂模式相对于工厂模式,减少了工厂类的创建,通过将一个产品组的组成一个工厂类,减少每个小的零件都需要建立一个工厂的方式,大大减少了工厂类的创建。同时,抽象工厂模式在横向方向具有很好的扩展性,比如说我们需要新增加一个产品组,只需要实现抽象工厂类和抽象产品类就行了。
缺点:在抽象工厂模式中如果我们需要在纵向加入了一个组件,比如在例子中我们可能需要新增一个输入框,这个时候我们就要修改抽象工厂,这就违背了设计模式的开闭原则,同时我们还需要修改每一个具体的工厂类,编码工作非常大,这样也就不符合设计模式的初衷了。所以在系统开发前,做好软件项目的设计非常重要。

4.单例模式

单例模式:在单例类的内部实现只生成一个实例,同时它提供一个静态的getInstance()工厂方法,让客户可以访问单一的一个实例;为了防止在外部对其实例化,需要将构造函数设计为私有函数,其内部提供一个singleton的静态对象,作为外部共享的唯一实例。
模型图:
单例模式模型图
单例模式适应情景:单例模式作为结构最简单的设计模式,在很多地方都有非常大的用处。比如说web框架常用的spring框架,其里面的bean生成方式默认就为单例模式,这样既节省了系统资源又能够提高效率。
单例模式分为饱汉模式,懒汉模式和IoDH模式,饱汉模式是在jvm加载类的时候就会创建实例对象,优点是不用考虑线程安全问题,缺点是当前单例未使用情况下依然会占据系统资源。懒汉模式则是在需要的时候创建,但是在多线程情况下会出现创建多个实例对象的问题,解决办法是对创建过程加锁,虽然节省了资源,但是因为在线程创建时加锁,会导致系统性能下降很多,所以也不推荐使用。IoDH模式是使用java的代码特性,通过静态内部类的方式进行创建,因为静态内部类是在调用的使用才会编译,所以不用担心资源问题。同时jvm在加载类的时候又保证了线程安全,所以不用考虑会创建多个实例,是目前单例模式最好的解决办法。

5.原型模式

原型模式:原型模式作为一种快速创建大量相同或者相似对象的方式,在软件开发中应用十分广泛,很多软件提供复制粘贴操作就是原型模式的典型应用。
原型模式模型图
优点:
1.当创建新的实例较为复杂时,可以通过原型模式简化创建过程,通过复制一个已有实例达到快速创建的效果,节省了实例的创建效率,同时简化了代码。
2.扩展性较好,原型模式定义了一个抽象的原型类,通过针对原型类进行编程,而将具体原型类写在配置文件中,增加或者减少产品类对系统都没有影响。
3.原型模式提供了简化的创建过程,工厂模式必须有一个跟产品同等级结构,而原型模式只需要实现封装在抽象类中的clone方法就能实现,无需专门的工厂类创建专门的产品。
4.可以使用深克隆的方式创建克隆对象,通过深克隆的方式可以保存对象的某个状态,方便在数据出错的时候进行数据恢复。 缺点:
1.需要为每一个类配备一个clone方法,并且该克隆类位于实现类的内部,当对已有的类进行改造时,需要修改源代码,违背了‘开闭原则’。 2.在实现深克隆的时候需要编写较为复杂的代码,当对象是嵌套的深克隆时,嵌套的对象也必须实现深克隆,较为复杂。 适用场景: 1.当创建对象成本较大(当初始化需要大量的时间,或者创建时需要消耗很多的cpu资源或者网络资源时)
2.系统需要保存对象的状态时,而对象的状态变化很小时,或者对象占用的内存很少时,可以使用原型模式配合备忘录模式进行使用

6.建造者模式

建造者模式的定义:建造者模式将一个复杂对象的构建与它的表示分离,使得同样的构建过程构建不同的表示。建造者模式是一种对象创建型模式。
建造者模式包含一下对象:
1.Builder(抽象建造者类) 目的为创建一个产品Product对象的各个部件指定抽象接口,在该接口中一般声明两类方法,一类方式是buildPartX(),它们用于创建对象的各个部件。另一个方法是getResult(),它们用于返回复杂对象。Builder既可以是抽象类又是接口。
2.ConcreteBuilder(具体建造者类) 具体建造者类通过继承或者实现抽象建造者类的接口,实现各个部件的具体构造和装配方法,定义并明确它所创建的对象,也可以提供一个方法返回创建好的复杂产品对象。
3.Product(产品角色类) 它是被构建的复杂对象,包含多个组件,具体创建者创建该产品的内部表示并定义它的装配过程。
4.Director(指挥者类)
建造者模式模型图
优点:
1.在建造者模式中,开发者不必知道产品组装的具体细节,只需要通过传入具体的建造类,就能获取对应的产品。将产品本身与产品的创建进行拆解。
2.每一个建造者类相对独立,因此可以很方便的替换掉某个具体的建造者类,或则增加新的建造者类。由于指挥者针对抽象建造者类进行编程,增加新的具体建造者类,无需修改原有代码,符合设计模式的“开闭原则”。 3.可以更加精细化的管理产品的建造过程,将产品的不同部件分解在不同的方法中,使得创建过程更加清晰,也更方便使用程序来控制建造过程。
缺点:
1.建造者模式主要运用在产品具有多个共同点,组成部分相似,如果产品之间的差异性很大,就不适合了,因此使用范围有一定的限制。
2.如果产品的内部变化复杂,可能会导致需要创建更多的具体创建者类来实现这种变化,增加了系统的理解难度和运行成本。
适用场景:
1.需要创建的产品具有复杂的内部结构,通常包含多个成员属性。
2.需要生成的产品对象属性相互依赖,需要指定其生成顺序。
3.对象的创建过程独立于产品本身。在建造者引入指挥者角色,将创建过程封装在指挥者类中,而不在建造者类和客户端中。

三.七个结构型模式

1.适配器模式

适配器模式的定义为:将一个接口转换为客户希望的接口,使接口不兼容的哪些类能够共同工作,其别名为包装器(Wrapper)。适配器模式可以为类结构型模式,还可以作为对象结构型模式。
适配器包含以下角色:
1.target(目标抽象类):目标抽象类定义为客户端需要的接口,可以是抽象类或者接口,也可以是一个具体类。
2.adapter(适配器类):适配器可以作为一个转换器,调用另一个接口,对target和adaptee进行适配。
3.adpatee(适配者类):适配者类包含客户端需要的方法,在某些情况下可能没有适配者的源代码。
适配器模式模型图
优点:适配器模式主要解决两个模块之间互相不兼容的问题,比如模块A调用模块B的方法,但是模块A中所提供的参数只有A,但是在模块B中需要使用A,B,C三个参数。根据设计模式的开闭原则,我们不能修改A模块或者B模块中的方法,这个时候采用适配器模式将二者结合起来,就能很有效的解决不兼容的问题。
缺点:因为在java中使用的是单继承,所以无法适配多个适配者。

2.桥接模式

如果软件中某个类存在两个独立变化的维度,通过该模式可以将两个维度分离出来,使二者独立扩展,让系统更加符合单一职责原则。与多层继承方案不同,它将两个独立变化的维度设计为两个独立的继承等级结构,并且在抽象层建立一个抽象关联,该关系类似于一个连接两个独立结构的桥,故名桥接模式。
在桥接模式结构图中包含如下几个角色: Abstraction(抽象类):用于定义抽象类的接口,一般是抽象类而不是接口,其中定义了一个Implementor(实现类接口)类型的对象,并可以维护该对象,它与Implementor之间具有关联关系,即可以包含抽象业务方法,也可以包含具体的实现方法。
RefinedAbstraction(具体抽象类):扩充由Abstraction定义的接口,通常情况下不再是抽象类,而是具体类,实现了抽象类声明的抽象业务方法。在此类中可以调用Implementor定义的业务方法。
Implementor(实现类接口):定义实现类的接口,只提供基本操作,具体实现交给子类。
ConcreteRefinedImplementor(具体类接口):实现Implementor接口,在不同的具体类接口中提供不同的实现,运行时替换为父类对象,提供给抽象类具体的业务方法。
桥接模式

About

java设计模式学习以及个人理解

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages