设计模式总结.docx
- 文档编号:10473700
- 上传时间:2023-05-26
- 格式:DOCX
- 页数:132
- 大小:3.68MB
设计模式总结.docx
《设计模式总结.docx》由会员分享,可在线阅读,更多相关《设计模式总结.docx(132页珍藏版)》请在冰点文库上搜索。
设计模式总结
Java设计模式
简介
设计模式按目的分为:
创建型,结构型和行为型
设计模式按范围分为:
类模式和对象模式(范围指出模式是用于类还是对象)
类模式处理类和子类之间的关系,这些关系是通过继承建立,是静态的,在编译器就确定下来了。
对象模式处理对象之间的关系,这些关系在运行时刻是可以变化的,更具动态性。
表0-1(设计模式空间)
目的
创建型
结构型
行为型
范围
类
FactoryMethod
Adapter
Interpreter
TemplateMethod
对象
AbstractFactory
Builder
Prototype
Singleton
Adapter(对象)
Bridge
Composite
Decorator
Facade
Flyweight
Proxy
ChanofResponsibility
Command
Iterator
Mediator
Memento
Observer
State
Strategy
Vistor
●创建型
创建型类模式:
将对象的部分创建工作延迟到子类
创建型对象模式:
将对象的部分创建工作延迟到另一个对象
●结构型
结构型类模式:
使用继承机制来组合类
结构型对象模式:
描述了对象的组装方式
●行为型
行为型类模式:
使用继承描述算法和控制流
行为型对象模式:
描述一组对象怎样写作完成单个对象所无法完成的任务
设计模式的选择:
选择设计模式应该考虑你的设计中哪些是可变的。
它不是考虑什么会迫使你的设计改变,而是考虑你想要什么变化却又不会引起重新设计。
最重要的一点是封装变化的概念,这是许多设计模式的主题。
(表0-2设计模式所支持的设计的可变方面)
目的
设计模式
可变的方面
创建
AbstractFactory
产品对象家族
Builder
如何创建一个组合对象
FactoryMethod
被实例化的子类
Prototype
被实例化的类
Singleton
一个类的唯一实例
结构
Adapter
对象的接口
Bridge
对象的实现
Composite
一个对象的结构和组成
Decorator
对象的职责,不生成子类
Façade
一个子系统的接口
Flyweight
对象的存储开销
Proxy
如何访问一个对象,该对象的位置
行为
ChainofResponsibility
满足一个请求的对象
Command
何时,怎样满足一个请求
Interpreter
一个语言的文法及解释
Iterator
如何遍历,访问一个聚合的各元素
Mediator
对象间怎样交互,和谁交互
Memento
一个对象中哪些私有信息存放在该对象之外,以及在什么时候进行存储
Observer
多个对象依赖于另外一个对象,而这些对象又如何保持一致
State
对象的状态
Strategy
算法
TemplateMethod
算法中的某些步骤
Vistor
某些可作用于一个(组)对象上的操作,但不修改这些对象的类
1.1创建型模式
类创建型模式使用继承改变被实例化的类
对象创建型模式将实例化委托给另一个对象
创建型模式有两个主旋律:
●它们都将系统使用哪些具体的类的信息封装起来
●它们因此了这些类的实例是如何被创建和放在一起的
1.1.1工厂方法模式(FactoryMethod)
●意图
定义一个用于创建对象的接口,让子类决定实例化哪一个类。
FactoryMethod使一个类实例化延迟到其子类
●适用性
1)当一个类不知道它所创建的对象的类的时候
2)当一个类希望由它的子类来指定它所创建的对象的时候
3)当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候
●结构
●参与者
1)Product
定义工厂方法所创建的对象的接口
2)ConcreteProduct
实现Product接口
3)Creator
声明工厂方法,该方法返回一个Product对象。
Creator也可以定义一个工厂方法的默认实现,它返回一个缺省的ConcreteProduct对象;
可以调用工厂方法以创建一个Product对象
4)ConcreteCreator
重定义工厂方法以返回一个ConcreteProduct对象
●优缺点
1)工厂方法不再将与特定应用有关的类绑定到你的代码中
代码仅处理Product接口;因此它可以与用户定义的任何ConcreteProduct类一起使用
2)仅仅为了创建一个ConcreteProduct对象,就不得不创建Creator子类
当Creator子类不必需时,客户现在必然要处理类演化的其他方面;但当客户无论如何必需创建Creator子类时,创建子类也是可行的
3)为子类提供挂钩(hook)
用工厂方法在一个类的内部创建对象通常比直接创建对象更灵活。
FactoryMethod给子类一个hook以提供对象的扩展版本
4)连接平行的类层次
工厂方法并不往往只被Creator调用,客户可以找到一些有用的工厂方法,尤其在平行类层次的情况下。
当一个类把它的一些指责委托给一个独立的类的时候,就产生了平行类层次。
●实现
FactoryMethod模式主要有两种不同的情况:
1)Creator是一个抽象类,并且不提供它所声明的工厂方法的实现
需要子类来定义实现,因为没有合理的缺省实现。
它避免了不得不实例化不可预见类的问题
2)Creator是一个具体类,而且为工厂方法提供了一个缺省的实现
具体的Creator主要因为灵活性才使用工厂方法。
它所遵循的准则是:
“用一个独立的操作创建对象,这样子类才能重定义它们的创建方式”,这条准则保证了子类的设计者能够在必要的时候改变父类所实例化对象的类
●例子
Product
publicabstractclassWork{
publicabstractvoiddoWork();
}
ConcreteProduct
publicclassStudentWorkextendsWork{
publicvoiddoWork(){
System.out.println("学生做作业!
");
}
}
publicclassTeacherWorkextendsWork{
publicvoiddoWork(){
System.out.println("老师审批作业!
");
}
}
Creator
publicabstractclassWorkFactory{
publicabstractWorkgetWork();
}
ConcreteCreator
publicclassStudentWorkFactoryextendsWorkFactory{
publicWorkgetWork(){
returnnewStudentWork();
}
}
publicclassTeacherWorkFactoryextendsWorkFactory{
publicWorkgetWork(){
returnnewTeacherWork();
}
}
Client
publicclassTest{
publicstaticvoidmain(String[]args){
WorkFactorystudentWorkFactory=newStudentWorkFactory();
studentWorkFactory.getWork().doWork();
WorkFactoryteacherWorkFactory=newTeacherWorkFactory();
teacherWorkFactory.getWork().doWork();
}
}
学生做作业!
老师审批作业!
●FactoryMethod模式在JDK中的应用
1)java.lang.Object#toString()
Object仅仅定义了返回String,由Object子类决定如何生成这个字符串,甚至可以生成字符串的子类(如果字符串不是final的话)。
返回结果是String(Product),Object(Creator),当调用Object子类的toString()方法时,子类就是ConcreteCreator。
2)Collection.iterator方法
●AbstractFactory和FactoryMethod的区别
抽象工厂模式:
提供一个一系列相关或相互依赖对象的接口,而无需指定它们具体的类
工厂方法模式:
定义一个用于创建对象的接口,让子类去决定实例化哪一个类
可以看出AbstractFactory针对多个产品,FactoryMethod针对一个产品:
FactoryMethod
AbstractFactory
针对一个产品等级结构
针对多个产品等级结构
一个抽象产品类
多个抽象产品类
可以派生出多个具体产品类
每个抽象产品类可以派生出多个具体产品类
一个抽象工厂类,可以派生出多个具体工厂类
一个抽象工厂类,可以派生出多个具体工厂类
每个具体工厂只能创建一个具体产品类的实例
每个具体工厂可以创建多个具体产品类的实例
举个例子说明下:
用种蔬菜的例子来说明事实,最初的时候,由于规模小,只种植一种蔬菜,根菜类蔬菜,这个时候由于种植方式比较简单,采用简单工厂模式即可,主要目的是让工人轻松,下达工厂种植即可,但是随着种植厂的发展以及市场的需求,要增加一种蔬菜类型种植了,茎菜,由于茎菜与根菜种植方式不一致,就需要两个专门的种植工厂来进行管理,那么久采用工厂模式来管理,一个工厂负责一种作物的种植,这个时候产品可以理解为仍然在一个层次。
但是随着科技的发展,我们逐步要种植转基因与非转基因食品了,在以前的蔬菜种类上又增加了一个层次,这个时候无法将其作为一个层次来解决,所以必须采用抽象工厂的方式来解决。
我用UML图表示三种结构:
上面的UML图可以看出:
抽象工厂可以创建多个产品类的对象。
在每一个层次,种菜工人所关心的对象也不一样:
在简单工厂模式中,工人想到的是种萝卜还是白菜;在工厂方法模式中,工人想到的是种根菜还是茎菜;在抽象工厂模式中,工人想到的是种基因菜还是非基因菜
1.1.2抽象工厂模式(AbstractFactory)
●意图
提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类
●适用性
1)一个产品要独立于它的产品的创建,组合和表示时
2)一个系统要由多个产品系列中的一个来配置时
3)当你强调一系列相关产品对象的设计以便进行联合使用时
4)当提供一个产品类库,而只想显示他们的接口而不是实现时
●结构
●参与者
1)AbstractFactory
声明一个创建抽象产品对象的操作接口
2)ConcreteFactory
实现创建具体产品对象的操作
3)AbstractProduct
为一类产品对象声明一个接口
4)ConcreteProduct
定义一个将被相应的具体工厂创建的产品对象
实现AbstractProduct接口
5)Client
仅使用由AbstractFactory和AbstractProduct声明的接口
●优缺点
1)它分离了具体的类
AbstractFactory帮你控制一个应用创建的对象的类。
因为一个工程封装创建产品对象的责任和过程,它将客户与类的实现分离。
客户通过它们的抽象接口操作实例。
产品的类名也在具体工厂的实现中分离;它们将不出现在客户代码中。
2)它使得易于交换产品系列
一个具体工厂类在应用中只出现一次-即在它初始化的时候。
这使得改变一个应用的具体工厂变得很容易。
它只需改变具体的工厂即可使用不同的产品配置,这是因为一个抽象工厂创建了一个完整的产品系列,所以整个产品系列会立刻改变。
3)它有利于产品的一致性
当一个系列中的产品对象被设计成在一起工作时,一个应用一次只能使用同一个系列中的对象,这一点很重要。
而AbstractFactory很容易实现这一点。
4)难以支持新种类的产品
难以扩展抽象工厂以生产新种类的产品。
这是因为AbstractFactory接口确定了可以被创建的产品集合。
支持新种类的产品就需要扩展该工厂接口,这将涉及AbstractFactory类及其所有子类的改变。
●例子
AbstractFactory
publicabtractclassAnimalFactory{
publicabstractCatcreateCat();
publicabstractDogcreateDog();
}
ConcreteFactory
publicclassBlackAnimalFactoryextendsAnimalFactory{
publicCatcreateCat(){
returnnewBlackCat();
}
publicDogcreateDog(){
returnnewBlackDog();
}
}
publicclassWhiteAnimalFactoryextendsAnimalFactory{
publicCatcreateCat(){
returnnewWhiteCat();
}
publicDogcreateDog(){
returnnewWhiteDog();
}
}
AbstractProduct
publicabstractclassCat{
voideat();
}
publicabstractclassDog{
voideat();
}
ConcreteProduct
publicclassBlackCatextendsCat{
publicvoideat(){
System.out.println("Theblackcatiseating!
");
}
}
publicclassWhiteCatextendsCat{
publicvoideat(){
System.out.println("Thewhitecatiseating!
");
}
}
publicclassBlackDogextendsDog{
publicvoideat(){
System.out.println("Theblackdogiseating");
}
}
publicclassWhiteDogextendsDog{
publicvoideat(){
System.out.println("Thewhitedogiseat*ng!
");
}
}
Client
publicstaticvoidmain(String[]args){
AnimalFactoryblackAnimalFactory=newBlackAnimalFactory();
CatblackCat=blackAnimalFactory.createCat();
blackCat.eat();
DogblackDog=blackAnimalFactory.createDog();
blackDog.eat();
AnimalFactorywhiteAnimalFactory=newWhiteAnimalFactory();
CatwhiteCat=whiteAnimalFactory.createCat();
whiteCat.eat();
DogwhiteDog=whiteAnimalFactory.createDog();
whiteDog.eat();
}
Theblackcatiseating!
Theblackdogiseating!
Thewhitecatiseating!
Thewhitedogiseating!
●JDK中使用AbstractFactory的例子
1)java.sql包
Java.sql.DriverManager的getConnection定义如下:
privatestaticConnectiongetConnection(Stringurl,java.util.Propertiesinfo,ClassLoadercallerCL)throwsSQLException
这个方法的主要作用是从已加载的驱动中,尝试请求一个连接:
Connectionresult=di.driver.connect(url,info);
其中Connection是连接接口,di.driver是Driver接口,其中有获取Connection的方法:
Connectionconnect(Stringurl,java.util.Propertiesinfo)throwsSQLException;
当我们想获取数据库连接之前,首先要指定好一个数据库驱动程序。
而这个驱动程序就可以理解成Driver的一个子类,它负责为我们创建基于一种数据库技术的Connection.至于它如何被创建,作为用户的我们并不关心,我们只是使用Connection接口,即抽象的Connection来操作我们的业务。
所以当我们改成使用其他数据库时,只需要更改相应的驱动,而代码不需要改动。
从上面的例子可以看出,Driver就相当于一个AbstractFactory,而具体数据库的驱动就相当于ConcreteFactory。
Connection相当于AbstractProduct。
而由ConcreteFactory(具体数据库的驱动)返回的Connection的真正实例(被驱动程序隐藏了)就相当于ConcreteProduct。
如果看懂了这个例子,那么Connection的createStatement()也是同理。
1.1.3建造者模式(Builder)
●意图
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示
●适用性
1)当创建对象的复杂算法应该独立于该对象的组成部分以及装配方式时
2)当构造过程必须允许被构造对象有不同的表示时
●结构
●参与者
1)Builder
为创建一个Product对象的各个部件指定抽象接口
2)ConcreteBuilder
实现Builder接口以构造和装配该产品的各个部件;
定义并明确它所创建的表示;
提供一个检索产品的接口
3)Director
构造一个使用Builder接口的对象
4)Product
表示被构造的复杂对象。
ConcreteBuilder创建该产品的内部表示并定义它的装配过程;
包含定义组成部件的类,包括将这些部件装配成最终产品的接口
●优缺点
1)它使你可以改变一个产品的内部表示
Builder对象提供给导向器(Director)一个构造产品的抽象接口。
该接口使得生成器可以隐藏该产品的表示和内部结构,它同时也隐藏了该产品的装配过程。
因为产品是通过抽象接口构造的,当你想改变产品的内部表示时所要做的只是定义一个新的生成器
2)它将构造代码和表示代码分开
Builder模式通过封装一个复杂对象的创建和表示方式提高了对象的模块性。
客户不需要知道定义产品内部结构的类的所有信息,这些类是不出现在Builder接口中的。
每个ConcreteBuilder包含了创建和装配一个特定产品的所有代码。
这些代码只需要写一次;然后不同的Director可以复用它以在相同部件集合的基础上构建不同的Product。
3)它使你对构造过程进行更精细的控制
Builder模式与一下子就生成Product的创建型模式不同,它是在导向者(Director)的控制下一步一步构造产品的。
仅当该产品完成时导向者才从生成器中取回它。
因此Builder接口相比其他创建型模式能更好的反映产品的构造过程。
这使你可以更精细的控制构建过程,从而能更精细的控制所得产品的内部结构
●例子
Builder
publicabstractclassPersonBuilder{
publicabstractvoidbuildHead();
publicabstractvoidbuildBody();
publicabstractvoidbuildFoot();
publicabstractPersonbuildPerson();
}
ConcreteBuilder
publicclassManBuilderextendsPersonBuilder{
Personperson;
publicManBuilder(){
person=newMan();
}
publicvoidbuildBody(){
person.setBody("建造男人的身体");
}
publicvoidbuildFoot(){
person.setFoot("建造男人的脚");
}
publicvoidbuildHead(){
person.setHead("建造男人的头");
}
publicPersonbuildPerson(){
returnperson;
}
}
publicclassWomanBuilderextendsPersonBuilder{
Personperson;
publicManBuilder(){
person=newWoman();
}
publicvoidbuildBody(){
person.setBody("建造女人的身体");
}
publicvoidbuildFoot(){
person.setFoot("建造女人的脚");
}
publicvoidbuildHead(){
person.setHead("建造女人的头");
}
publicPersonbuildPerson(){
returnperson;
}
}
Director
publicclassPersonDirector{
publicPersonconstructPerson(PersonBuilderpb){
pb.buildHead();
pb.buildBody();
pb.buildFoot();
returnpb.buildPerson();
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 设计 模式 总结