创建型模式解析.docx
- 文档编号:14192110
- 上传时间:2023-06-21
- 格式:DOCX
- 页数:16
- 大小:188.31KB
创建型模式解析.docx
《创建型模式解析.docx》由会员分享,可在线阅读,更多相关《创建型模式解析.docx(16页珍藏版)》请在冰点文库上搜索。
创建型模式解析
创建型模式
创建型模式抽象了实例化过程。
它们帮助一个系统独立于如何创建、组合和表示它的那些对象。
一个类创建型模式使用继承改变被实例化的类,而一个对象创建型模式将实例化委托给另一个对象。
一它们都将关于该系统使用哪些具体的类的信息封装起来。
二它们隐藏了这些类的实例是如何被创建和放在一起的。
整个系统关于这些对象所知道方法的是由抽象类所定义的接口。
工厂模式
专门负责将大量有共同接口的类实例化。
可以动态决定将哪一个类实例化,不必事先知道每次要实例化哪一个类。
工厂模式有以下几种形态:
简单工厂(SimpleFactory)模式,工厂方法(FactoryMethod)模式,抽象工厂(AbstractFactory)模式
设计模式(DesignPattern)需要的四个要素:
模式名称(patternname)一个助记名,
问题(problem)描述了应该在何时使用模式。
解决方案(solution)描述了设计的组成成分,它们之间的相互关系及各自的职责和协作方式。
效果(consequences)描述了模式应用的效果及使用模式应权衡的问题。
简单工厂模式
简单工厂模式是类的创建模式。
一个具体工厂类通过条件语句创建不同产品,根据传入的参量动态决定创建出哪一种产品类的实例
角色(参与者)
工厂类(Creator)角色:
由客户端的直接调用,创建产品对象,往往由一个具体类实现。
抽象产品(Product)角色:
由工厂方法模式所创建的对象的父类或它们共同拥有的接口。
可以用一个接口或者抽象类实现。
具体产品(ConcreteProduct)角色:
工厂方法模式所创建的任何对象都是这个角色的实例,由一个具体类实现。
简单工厂模式优缺点
实现了对责任的分割。
模式的核心是工厂类。
这个类含有必要的判断逻辑。
而客户端仅仅负责“消费”产品,免除直接创建产品对象的责任。
缺点:
1、工厂类集中了所有的产品创建逻辑(GodClass),其运行状态正常至关重要
2、工厂类负责判断在什么时候创建哪种产品。
判断逻辑混合在一起,使得系统在将来进行功能扩展时较为困难。
3、由于简单工厂模式使用静态方法作为工厂方法,而静态方法无法由子类继承,因此工厂角色无法形成基于继承的等级结构。
工厂方法模式
名称:
工厂方法模式是类的创建模式,又叫做虚拟构造子(VirtualConstructor)模式或者多态性工厂(PolymorphicFactory)模式。
问题:
谁有责任创建一些特殊考虑的对象?
比如说有复杂的创建逻辑,为了更好的内聚性而希望分离创建职责。
解决方案:
创建一个称为工厂(Factory)的纯虚构对象来处理这种创建。
适用性
·当一个类不知道它所必须创建的对象的类的时候。
·当一个类希望由它的子类来指定它所创建的对象的时候。
·当类将创建对象的职责委托给多个子类中的某一个,并且你希望将哪一个子类是代理者这一信息局部化的时候。
参与者
抽象产品Product(Operation):
定义工厂方法所创建的对象的接口。
具体产品ConcreteProduct(OperationAdd等):
实现Product接口(GetResult)。
抽象工厂Creator(IFactory):
1)声明工厂方法,该方法返回一个Product类型的对象。
Creator也可以定义一个工厂方法的缺省实现,它返回一个缺省的ConcreteProduct对象。
2)可以调用工厂方法以创建一个Product对象。
具体工厂ConcreteCreator(AddFactory等):
重定义工厂方法以返回一个ConcreteProduct实例。
抽象工厂模式
适用性
一个系统要独立于它的产品的创建、组合和表示时。
一个系统要由多个产品系列中的一个来配置时。
当要强调一系列相关的产品对象的设计以便进行联合使用时。
当提供一个产品类库,而只想显示它们的接口而不是实现时。
参与者
抽象工厂AbstractFactory:
声明一个创建抽象产品对象的操作接口。
具体工厂ConcreteCreator(CarFactory等):
实现创建具体产品对象的操作。
抽象产品Product(Auto):
为一类产品对象声明一个接口。
具体产品ConcreteProduct(Car等):
定义一个将被相应的具体工厂创建的产品对象实现AbstractProduct接口。
客户端Client:
仅使用由AbstractFactory和AbstractProduct类声明的接口
协作:
通常在运行时刻创建一个ConcreteFactroy类的实例。
这一具体的工厂创建具有特定实现的产品对象。
为创建不同的产品对象,客户应使用不同的具体工厂。
AbstractFactory将产品对象的创建延迟到它的ConcreteFactory子类
效果
1)将客户与类的实现分离。
产品的类名也在具体工厂的实现中被分离。
2)一个具体工厂类在一个应用中仅出现一次—即在它初始化的时候。
这使得改变一个应用的具体工厂变得很容易。
3)它有利于产品的一致性。
当一个系列中的产品对象被设计成一起工作时,应用一次只能使用同一个系列中的对象,
4)缺:
AbstractFactory接口确定了可以被创建的产品集合,支持新种类的产品就需要扩展该工厂接口。
抽象工厂模式与工厂方法模式的最大区别就在于
工厂方法模式针对的是一个产品等级结构;抽象工厂模式则需要面对多个产品等级结构
名词解释:
产品族(ProductFamily):
指位于不同产品等级结构中,功能相关联的产品组成的家族。
设计模式题(程序分析)
1.使用三种工厂模式解决运算类,货架问题
建造者模式(生成器)
•问题的提出:
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
适用性
•当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。
•当构造过程必须允许被构造的对象有不同的表示时。
•参与者
•Builder(抽象建造者)
—为创建一个Product对象的各个部件指定抽象接口。
—有多少组成部件就有多少个接口
•BuilderImplx(具体建造者角色)
—实现Builder的接口以构造和装配该产品的各个部件。
—给出一步一步完成创建产品实例的操作。
—在建造过程完成后提供产品实例
•Director(导演者)
—构造一个使用Builder接口的对象。
调用具体建造者角色以创建产品对象。
导演者本身没有产品类的具体知识。
•Product(产品)
—表示被构造的复杂对象。
ConcreteBuilder创建该产品的内部表示并定义它的装配过程。
—包含定义组成部件的类,包括将这些部件装配成最终产品的接口。
协作
•客户创建Director对象,并用它所想要的Builder对象进行配置。
•一旦产品部件被生成,导向器就会通知生成器。
•生成器处理导向器的请求,并将部件添加到该产品中。
•客户从生成器中检索产品。
实现要点:
1、建造者模式主要用于“分步骤构建一个复杂对象”。
其中,分步骤是一个固定的算法,复杂对象的各个部分经常发生变化
2、产品不需要抽象类
3、创建者中的创建子部件的接口方法不是抽象方法,而是空方法,不进行任何操作,具体创建者只需要覆盖需要的方法就可以
4、抽象工厂模式解决系列对象的需求变化,创建者模式解决对象部分的需求变化,经常和组合模式结合使用。
效果
•可以改变一个产品的内部表示
—Builder对象提供给导向器一个构造产品的抽象接口。
该接口使得生成器可以隐藏这个产品的表示和内部结构。
它同时也隐藏了该产品是如何装配的。
因为产品是通过抽象接口构造的,你在改变该产品的内部表示时所要做的只是定义一个新的生成器。
•将构造代码和表示代码分开
—客户不需要知道定义产品内部结构的类的所有信息;这些类是不出现在Builder接口中的。
每个BuilderImplx包含了创建和装配一个特定产品的所有代码。
这些代码只需要写一次;不同的Director可以复用它以在相同部件集合的基础上构作不同的Product。
•可对构造过程进行更精细的控制
—是在导向者的控制下一步一步构造产品的。
仅当该产品完成时导向者才从生成器中取回它。
设计模式题或程序分析
一,KFC套餐题的代码实现
1、所有组合都包含四个固定类型产品
2、每个类型具体产品任意搭配
分析出变化的部分是:
1、组合过程
2、组合的具体产品
二,以下类图的实现
原型模式
问题的提出:
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
将一个原型对象传给要创建的对象,新对象通过请求原型对象的拷贝来实现创建
适用性
•当一个系统应该独立于它的产品创建、构成和表示时
•当要实例化的类是在运行时刻指定时,例如,通过动态装载
•为了避免创建一个与产品类层次平行的工厂类层次时
•当一个类的实例只能有几个不同状态组合中的一种时。
•参与者
Prototype—声明一个克隆自身的接口。
ConcretePrototype—实现一个克隆自身的操作。
Client—让一个原型克隆自身从而创建一个新的对象。
•协作
客户请求一个原型克隆自身。
•效果
Prototype对客户隐藏了具体的产品类,因此减少了客户知道的名字的数目。
原型模式优缺点
•优点
(l)允许动态地增加或减少产品类。
(2)提供简化的创建结构。
工厂方法模式常常需要有个与产品类等级结构相同的等级结构,而原始模型模式就不需要这样。
对于Java设计师米说,因为Java语言天生就将原始模型模式设计到了语言模型里面。
善于利用原始模型模式和Java语言的特点,可以事半而功倍。
(3)具有给一个应用软件动态加载新功能的能力。
(4)产品类不需要非得有任何事先确定的等级结构,因为原始模型模式适用于任何的等级结构。
缺点:
每一个类都必须配备一个克隆方法。
•优点(?
?
?
)
运行时刻增加和删除产品;改变值以指定新对象;改变结构以指定新对象;减少子类的构造;
用类动态配置应用
深克隆和浅克隆
•浅克隆
被克隆对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用都仍然指向原来的对象。
•深克隆
被克隆对象的所有的变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。
那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。
设计题或代码
1.图中原型模式的代码实现
2.浅克隆与深克隆的代码实现
单例模式重点
名称:
单例模式(Singleton)
模式名:
单例(Singleton)
问题:
一个单例类1)只能有一个实例2)必须自己创建这个实例
3)必须自行向整个系统提供这个实例
解决方案:
对类定义静态方法以返回单实例。
适用性:
1)当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时。
2)当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需更改代码就能使用一个扩展的实例时。
参与者:
1)一个getInstance操作,允许客户访问它的唯一实例。
2)可能负责创建它自己的唯一实例。
协作:
----客户只能通过Singleton的getInstance操作访问一个Singleton的实例。
效果-优点:
1)对唯一实例的受控访问
2)缩小名空间,避免了那些存储唯一实例的全局变量污染名空间。
3)允许对操作和表示的精化。
Singleton类可以有子类,而且用这个扩展类的实例来配置一个应用是很容易的。
你可以用你所需要的类的实例在运行时刻配置应用。
4)允许可变数目的实例
5)比类操作更灵活
使用范围:
1)功能
1)确保一个类只有一个实例被建立
2)提供了一个对对象的全部访问指针
3)在不影响单例类的客户端的情况下允许将来有多个实例
2)优点
为一个面向对象的应用程序提供了对象的唯一访问点,不管实现何种功能
3)缺点
构造方法私有造成派生有困难
单例模式-饿汉式
publicclassSingleton{
privatestaticfinalSingletonsingleton=newSingleton();//具有私有的静态属性,维护自身实例
//final修饰的变量只能被赋值一次,所以达到维护自身实例的效果
PrivateSingleton(){}//构造方法私有
publicstaticSingletongetInstance(){//具有共有的服务
Returnsingleton;
}
}
单例模式-懒汉式
//该程序有线程安全问题
publicclassSingletonLazyload{
privatestaticSingletonLazyloadsingleton;
PrivateSingletonLazyload(){}
PublicstaticSingletonLazyloadgetInstance(){
//先判断存储实例的变量是否有值,如果有,直接使用;如果没有,就先创建一个类实//例,并把值赋给存储类实例的变量
(1)if(singleton==null){
(2)singleton=newSingletonLazyload();
}
returnsingleton;}}
懒汉式与饿汉式区别:
在与建立单例对象的时间不同。
“懒汉式”是在你真正用到的时候才去建这个单例对象
“饿汉式”是在不管你用的用不上,一开始就建立这个单例对象
懒汉式如果在创建实例对象时不加上synchronized则会导致对对象的访问不是线程安全的
饿汉式是线程安全的,在类创建的同时就已经创建好一个静态的对象供系统使用,以后不在改变
懒汉式单例类在第一次被引用时将自己实例化。
饿汉式是线程安全的,因为虚拟机保证了只会装载一次,在装载类的
时候是不会发生并发的。
.
解决懒汉式线程安全
1>加关键字synchronized
同步(synchronized)的作用:
l同步的方法不能被两个线程同时访问,当一个线程执行同步代码块时,其他所有调用此同步代码块的方法暂停,直到第一个线程执行完成
l执行线程从同步方法退出时,JVM将会在阻塞的线程中选择一个进入此方法,其他线程依旧等待,保证了所有使用此方法的线程会依次被调用
PubliclassSingletonLazyloadSyn{
PrivatestaticSingletonLazyloadSynsingleton;
PrivateSingletonLazyloadSyn(){}
publicstaticSingletonLazyloadSyngetInstance(){
if(singleton==null){
synchronized(SingletonLazyloadSyn.class){
if(singleton==null){
singleton=newSingletonLazyloadSyn();
}}}
returnsingleton;
}}
2>使用静态内部类
/***单例模式线程安全*/
publicclassSingletonLazyloadSynSafe{
//内部类,外部类创建时并未产生对象
privatestaticclassSingletonHolder{
staticfinalSingletonLazyloadSynSafeuniqueInstance
=newSingletonLazyloadSynSafe();
}
/***私有构造方法*/
privateSingletonLazyloadSynSafe(){}
/***共有的静态获得实例方法*/
publicstaticSingletonLazyloadSynSafegetInstance(){
returnSingletonHolder.uniqueInstance;
}}
类级内部类:
有static修饰的成员式内部类。
如果没有static修饰的成员式内部类被称为对象级内部类。
1>类级内部类相当于其外部类的static成分,它的对象与外部类对象间不存在依赖关系,因此可直接创建。
2>类级内部类中,可以定义静态的方法,在静态方法中只能够引用外部类中的静态成员方法或者成员变量。
3>类级内部类相当于其外部类的成员,只有在第一次被使用的时候才会被装载。
当getInstance方法第一次被调用的时候,它第一次读取SingletonHolder.getinstance,导致SingletonHolder类得到初始化;这个类在装载并被初始化的时候,会初始化它的静态域,从而创建Singleton的实例,由于是静态的域,因此只会被虚拟机在装载类的时候初始化一次,并由虚拟机来保证它的线程安全性。
这个模式的优势在于,getInstance方法并没有被同步,并且只是执行一个域的访问,因此延迟初始化并没有增加任何访问成本。
两种使用情况(?
?
?
)
1)直接新建单例对象
2)通过反射构造单例对象
登记式
登记式单例类是GoF为了克服饿汉式单例类及懒汉式单例类均不可继承(构造函数私有)的缺点而设计的。
publicclassRegSingleton{
StaticprivateHashMapm_registry=newHashMap();
static{
RegSingletonx=newRegSingleton();
m_registry.put(x.getClass().getName(),x);
}
protectedRegSingleton(){//保护的默认构造子}
publicstaticRegSingletongetInstance(Stringname){
if(name==null){name="RegSingleton";}
if(m_registry.get(name)==null){
m_registry.put(name,Class.forName(name).newInstance());
}
return(RegSingleton)(m_registry.get(name));
}
子类实例化的方式只能是懒汉式的,
publicclassRegSingletonChildextendsRegSingleton{
publicRegSingletonChild(){}
StaticpublicRegSingletonChildgetInstance(){
return(RegSingletonChild)RegSingleton.getInstance
("RegSingletonChild");
}
}
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 创建 模式 解析