系统的演化应当依赖于组合,而不是继承;这就提出了将类的实例化委托给一个对象的要求,因此创建型模式将变的越来越重要。
创建型模式属于对象创建模型。所谓对象创建模型就是说将实例化的工作委托给另一个对象来做。与之相对应的是类创建模型,这是一种通过继承改变被实例化的类。
创建型模式有两个重要的特点:
1) 客户不知道创建的具体类是什么(除非看源代码)
2) 隐藏了类的实例是如何被创建和放在一起的
一。抽象工厂模式
1.意图:提供一个创建
一系列相关或相互依赖对象的接口,而无需指定它们的具体的类。
2.适用场景:
1)一个系统要独立于它的产品的创建、组合和表示时
2)一个系统要由多个产品系列中的一个来配置时
3)当你要强调一系列相关的产品对象的设计以便进行联合使用时
4)当你提供一个产品类库,而只想显示它们的接口而不是实现时
3.UML图——结构
4.效果:
1)分离了具体的类,通过抽象接口将客户与具体的类分离
2)易于交换产品系列
3)有利于产品的一致性
4)难以支持新种类的产品,比如我们现在有一个ProductC产品,我们需要增加类AbstractProductC,增加AbstractFactory::
CreanteProductC方法,并且两个产品系列的实际创建者ConCreateFactory1、ConCreateFactor2都要实现该方
法。
可以通过给方法加参数的方式来指明创建的是什么产品,这样客户代码就无需改变,只要传递不同的参数。AbstractFactory类只需要提供一个CreateProduct(const string& name)方法即可。
5.代码实现,以《深入浅出设计模式(java C#)》的动物工厂为例:
<!---->using System;
namespace AnimalWorld
{
// 抽象大陆工厂
abstract class ContinentFactory
{
abstract public Herbivore CreateHerbivore();
abstract public Carnivore CreateCarnivore();
}
//非洲大陆,有角马,狮子
class AfricaFactory : ContinentFactory
{
override public Herbivore CreateHerbivore()
{
return new Wildebeest();
}
override public Carnivore CreateCarnivore()
{
return new Lion();
}
}
// 美洲大陆,有狼,野牛
class AmericaFactory : ContinentFactory
{
override public Herbivore CreateHerbivore()
{
return new Bison();
}
override public Carnivore CreateCarnivore()
{
return new Wolf();
}
}
//食草动物"
abstract class Herbivore
{
}
//肉食动物"
abstract class Carnivore
{
//猎食食草动物的方法
abstract public void Eat( Herbivore h );
}
//角马
class Wildebeest : Herbivore
{
}
//狮子"
class Lion : Carnivore
{
//重载猎食食草动物的方法
override public void Eat( Herbivore h )
{
Console.WriteLine( this + " eats " + h );
}
}
//野牛
class Bison : Herbivore
{
}
//狼
class Wolf : Carnivore
{
//重载猎食食草动物的方法
override public void Eat( Herbivore h )
{
Console.WriteLine( this + " eats " + h );
}
}
//动物世界类
class AnimalWorld
{
private Herbivore herbivore;
private Carnivore carnivore;
// 创建两种动物分类
public AnimalWorld( ContinentFactory factory )
{
carnivore = factory.CreateCarnivore();
herbivore = factory.CreateHerbivore();
}
//运行食物链
public void RunFoodChain()
{
//肉食动物猎食食草动物
carnivore.Eat( herbivore );
}
}
/// <summary>
/// 抽象工厂模式客户应用测试
/// </summary>
class GameApp
{
[STAThread]
static void Main(string[] args)
{
//创造并运行非洲动物世界
ContinentFactory africa = new AfricaFactory();
AnimalWorld world = new AnimalWorld( africa );
world.RunFoodChain();
//创造并运行美洲动物世界
ContinentFactory america = new AmericaFactory();
world = new AnimalWorld( america );
world.RunFoodChain();
Console.Read();
}
}
}
二。Builder模式
1.意图:将一个
复杂对象的构建与它的表示相分离,使得同样的构建过程可以创建不同的表示(或者说产品)
2.适用场景:
1)当创建复杂对象的算法应该独立于改对象的组成部分以及它们的装配方式时
2)当构造过程必须允许被构造的对象有不同的表示时
3.UML图——结构
Director接受一个Builder子类对象,完成创建过程,并通知Builder对象返回以及构造好的产品。
4.效果:
1)可以使你改变一个对象的内部表示
2)构造代码和表示代码分开
3)可以对构造过程进行更精细的控制
5。实现:以一个车辆建造过程为例(C#)
<!---->using System;
namespace CarShop
{
using System;
using System.Collections;
//指挥者,Director
class Shop{
public void Construct( VehicleBuilder vehicleBuilder ){
vehicleBuilder.BuildFrame();
vehicleBuilder.BuildEngine();
vehicleBuilder.BuildWheels();
vehicleBuilder.BuildDoors();
}
}
/* "Builder 建造者",Builder
抽象建造者具有四种方法
装配框架
装配发动机
装配轮子
装配车门
*/
abstract class VehicleBuilder
{
protected Vehicle vehicle;
//返回建造完成的车辆
public Vehicle Vehicle{
get{ return vehicle; }
}
abstract public void BuildFrame();
abstract public void BuildEngine();
abstract public void BuildWheels();
abstract public void BuildDoors();
}
//具体建造者-摩托车车间
class MotorCycleBuilder : VehicleBuilder
{
override public void BuildFrame(){
vehicle = new Vehicle( "摩托车" );
vehicle[ "frame" ] = "MotorCycle Frame";
}
override public void BuildEngine(){
vehicle[ "engine" ] = "500 cc";
}
override public void BuildWheels(){
vehicle[ "wheels" ] = "2";
}
override public void BuildDoors(){
vehicle[ "doors" ] = "0";
}
}
//具体建造者-轿车车间
class CarBuilder : VehicleBuilder
{
override public void BuildFrame(){
vehicle = new Vehicle( "轿车" );
vehicle[ "frame" ] = "Car Frame";
}
override public void BuildEngine(){
vehicle[ "engine" ] = "2500 cc";
}
override public void BuildWheels(){
vehicle[ "wheels" ] = "4";
}
override public void BuildDoors(){
vehicle[ "doors" ] = "4";
}
}
// 具体建造者-单脚滑行车车间
class ScooterBuilder : VehicleBuilder
{
override public void BuildFrame(){
vehicle = new Vehicle( "单脚滑行车" );
vehicle[ "frame" ] = "Scooter Frame";
}
override public void BuildEngine(){
vehicle[ "engine" ] = "none";
}
override public void BuildWheels(){
vehicle[ "wheels" ] = "2";
}
override public void BuildDoors(){
vehicle[ "doors" ] = "0";
}
}
//车辆产品类
class Vehicle
{
private string type;
private Hashtable parts = new Hashtable();
//筑构函数,决定类型
public Vehicle( string type ){
this.type = type;
}
//索引
public object this[ string key ]{
get{ return parts[ key ]; }
set{ parts[ key ] = value; }
}
//显示方法
public void Show()
{
Console.WriteLine( "\n---------------------------");
Console.WriteLine( "车辆类类型: "+ type );
Console.WriteLine( " 框架 : " + parts[ "frame" ] );
Console.WriteLine( " 发动机 : "+ parts[ "engine"] );
Console.WriteLine( " #轮子数: "+ parts[ "wheels"] );
Console.WriteLine( " #车门数 : "+ parts[ "doors" ] );
}
}
/// <summary>
/// 建造者模式应用测试
/// </summary>
class CarShop
{
[STAThread]
static void Main(string[] args)
{
// 创造车间及车辆建造者
Shop shop = new Shop();
VehicleBuilder b1 = new ScooterBuilder();
VehicleBuilder b2 = new CarBuilder();
VehicleBuilder b3 = new MotorCycleBuilder();
// 筑构并显示车辆
shop.Construct( b1 );
b1.Vehicle.Show();
shop.Construct( b2 );
b2.Vehicle.Show();
shop.Construct( b3 );
b3.Vehicle.Show();
Console.Read();
}
}
}
三。Factory Method模式
1.意图:定义一个用于创建对象的接口,让子类决定实例化具体的哪一个类。
2.适用场景:
1)当一个类不知道它所必须创建的对象的类的时候,让子类来决定
2)当一个类希望由它的子类来决定它所创建的对象的时候
3。UML图——结构:
4.效果:
1)为子类提供回调函数
2)连接平行的类层次
3) 创建函数可以接收参数来决定创建什么产品
4)Factory Method容易导致创建过多的Creator的子类以对应不同的产品,这个方法可以通过模板技术来解决
6.实现,手机工厂,产品可能是Nokia,也可能是Motorola
<!---->using System;
using System.Collections.Generic;
using System.Text;
namespace HandPhone
{
//手机接口
interface Mobile
{
void call();
}
//手机工厂接口
interface MobileFactory
{
Mobile createMobile();
}
//Nokia
class Nokia:Mobile
{
public void call()
{
Console.WriteLine("This is a {0} phone", this.GetType().Name);
}
}
//Motorola
class Motorola : Mobile
{
public void call()
{
Console.WriteLine("This is a {0} phone", this.GetType().Name);
}
}
//Motorola工厂
class MotorolaFactory : MobileFactory
{
public Mobile createMobile()
{
return new Motorola();
}
}
//Nokia工厂
class NokiaFactroy : MobileFactory
{
public Mobile createMobile()
{
return new Nokia();
}
}
public class Client
{
static void Main(String []args)
{
MobileFactory factory=null;
Mobile mobile=null;
factory=new NokiaFactroy();
mobile=factory.createMobile();
mobile.call();
factory=new MotorolaFactory();
mobile=factory.createMobile();
mobile.call();
}
}
}
四。Prototype模式
1.意图:通过原型实例指定创建对象的种类,并通过拷贝这些原型来创建新的对象
2.适用场景:
1)要实例化的类是在运行时刻指定的,比如动态装载
2)为了避免创建一个与产品层次平行的工厂类层次
3)当一个类的实例只能有几个不同的状态组合中的一种时,建立相应数目的原型并克隆它们可能比每次用合适的状态手工化该类更方便一些。
3.UML图——结构:
4.效果:
1)运行时动态增加或者删除产品
2)减少子类的构造数目
3)用类动态配置应用
4)动态指定新的对象,通过改变结构或者值
5)缺陷在于每一个Prototype的子类都需要实现clone操作
5。实现,无论java还是C#都从语言层次内置了对prototype模式的支持。具体不再详述。
五。singleton模式
1。意图:保证一个类仅有一个实例,并提供一个访问它的全局访问点
2.适用场景:
1)当需要类只有一个实例,并且客户只能通过一个全局点去访问它
2)当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需更改代码就能使用扩展的实例
3.UML图:略
4.效果:
1)对唯一实例的受控访问
2)缩小命名空间
3)允许对操作和表示的细化
4)允许可变数目的实例
5实现,关于singleton在java多线程环境下的实现,请见讨论《当Singleton遇到multi-threading》,C#对singleton多线程环境下的能够正确实现Double-checked模式:
<!---->public sealed class Singleton
{
private static volatile Singleton instance;
private static object syncRoot = new Object();
private Singleton() {}
public static Singleton Instance
{
get
{
if (instance == null)
{
lock (syncRoot)
{
if (instance == null)
instance = new Singleton();
}
}
return instance;
}
}
}
本文仅作速查记忆用,摘记于《设计模式——可复用面向对象软件基础》和《深入浅出设计模式(java C#)》两书
分享到:
相关推荐
这些策略不仅适用于计算教学,也可应用于广泛的学科领域,旨在创建一个以学生为中心,注重兴趣培养和全面发展的教育环境。通过这样的教学方法,学生能够更有效地学习,同时也能够培养出对学习持久的热情。
Fluent软件应用过程中的一些比较重要的说明摘记
软考信息系统管理师考试摘记。 项 目 管 理 知 识 体 系(九大管理) INPUT TOOL OUTPUT 4.1 制定项目章程 1、合同(如果适用) 1、项目选择方法 1、项目章程 2、项目工作说明书 2、项目管理方法系 3、事业环境...
- **解释**: 拷贝构造函数用于创建新对象时拷贝现有对象的状态,而赋值运算符则用于将一个对象的状态复制到另一个已经存在的对象上。设计良好的类应该正确地实现这两个函数,尤其是在处理资源管理时。 ##### No.6: ...
《胡希恕伤寒论坛讲座》摘记.doc
【网络摘记教学设计】 本课程的核心是教授学生如何有效地在网络中查找、搜集信息,并将这些信息整理成有条理的文档,特别是使用Microsoft Word进行简单的排版。教学目标包括三个方面:一是掌握资料查找和搜集的基本...
EJB(Enterprise JavaBeans)是Java EE平台中的一个核心组件,用于构建企业级分布式应用程序。EJB 3是其第三个主要版本,发布于2006年,它引入了...如果你正在探索或使用EJB 3,这些摘记和文档将是你宝贵的参考资料。
例如,`<cacheusage="read-only"/>` 表示缓存模式为只读,这意味着缓存中的数据不会被更新,适用于查询密集型的应用场景;`<cacheusage="read-write"/>` 则支持读写操作,允许数据更新,但可能导致更多的锁竞争。 #...
"胡希恕伤寒论坛讲座摘记" 本文摘记了胡希恕伤寒论坛的讲座要点,总共十八点,涵盖了中医基础理论、方剂学、诊断学等多方面的知识点。 一、温病不能发汗,不能吃泻药,更不能用火攻,只能用白虎汤。 本点讲述了...
Codelife 不止代码 - 自阅读加注标签-技术规划的借鉴 有摘记和感想.md,提供了原文的详细目录大纲,更重要的是给出了自学摘记,记录下诸多感想。 人的学习进步体现在对抽象问题的概括和具体问题的有针对性的见解,...
构建高性能Web站点涉及多个关键领域,包括服务器并发策略、动态内存缓存、动态脚本加速、浏览器缓存、Web服务器缓存以及反向代理缓存。这些策略的优化对于提升网站性能至关重要。 首先,服务器并发策略是提高Web...
近年来,我国大力推动课堂改革,寻求更有效的教学模式。政治学科因其理论性强、抽象概念多的特点,激发学生兴趣尤为困难。因此,我们需要创新教学方式,让课堂变得生动活泼,引导学生积极参与,从而减轻师生负担,...
【教育精品资料】这篇文档是关于2021-2022年自贡市绿盛实验学校在课堂教学改革过程中的学习与探索记录,主要涵盖了四川自贡地区多个区县的教改模式,并且详细描述了学校教师赴山东名校参观学习的考察报告。...
- 进程控制块(PCB):PCB是操作系统中最重要的数据结构,它记录了进程的基本信息,用于进程的创建、撤销、调度、同步和通信等管理操作。PCB包含进程标志符、处理机状态、进程调度信息、进程控制信息等。 以上内容...
Facebook在设计B端产品时,遵循了四个核心原则,这些原则旨在创造高效、用户导向且适应性强的企业级工具。下面是对这些原则的详细解释: 1. **帮助用户成长**:B端产品不仅要协助用户完成任务,还要促进他们的专业...
### UNIX系统概述与核心知识点解析 #### 一、UNIX系统简介 UNIX系统是一种多用户、多任务的操作系统,自1969年由AT&T贝尔实验室开发以来,便因其卓越的性能和灵活性而受到广泛欢迎。它不仅在科学研究、教育领域有着...
下面是调用一个模型(Module)的函数。这个函数的基本功能是指定一个模型(抽象化为类)的名称,然后它会在模型目录下面寻找这个类的脚本实例化以后返回。这样的做法有一点好处就是载入和实例化是自动的,你可以获得...
在实际管理中,管理者需要根据情境选择合适的决策模式。同时,笔记可能会介绍几种重要的领导理论,如特质理论、行为理论和权变理论,以及它们如何影响领导者的行为和团队动态。 此外,罗宾斯的管理学笔记可能会深入...
信息系统项目管理师3年经验摘记,个人经验喔