设计模式:创建型模式

这篇具有很好参考价值的文章主要介绍了设计模式:创建型模式。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

抽象工厂 abstract factory

例子

考虑一个多风格的界面应用,要求可以切换不同风格类型的组件(窗口,滚动条,按钮等)
设计模式:创建型模式,设计模式,设计模式

风格/组件 pm风格 motif风格
滚动条 pmScrollBar motifScrollBar
窗口 pmWindow MotifWindow

WidgetFactory: 抽象工厂,用于创建滚动条和窗口。

MotifWidgetFactory: 继承抽象工厂(WidgetFactory),用于给Motif类型创建滚动条和窗口。
他依赖于MotifWindow和MotifScrollBar

PMWidgetFactory: 继承抽象工厂(WidgetFactory),用于给PM类型创建滚动条和窗口。
他依赖于PMWindow和PMScrollBar

Client: 客户端,用来操作软件或者系统

结构

设计模式:创建型模式,设计模式,设计模式
设计模式:创建型模式,设计模式,设计模式

builder 模式

例子

支持多种格式的富文本阅读器(RTF),比如tex文本,ASCII, WIDGET
设计模式:创建型模式,设计模式,设计模式
客户端解析文本时,先选择builder,然后根据文本流不同类型,转换不同成不同的格式
比如:tex格式支持复杂的数学公式,只有texbuilder有这个分支

结构

设计模式:创建型模式,设计模式,设计模式

  1. Builder (TextConverter) 建造者
    specifies an abstract interface for creating parts of a Product object. (为了创建一个对象或者对象的部分而指定一个抽象接口)
  2. ConcreteBuilder (ASCIIConverter, TeXConverter, TextWidgetConverter) 具体建造者
    constructs and assembles parts of the product by implementing the Builder interface. (通过实现建造接口来构建一个产品或者产品的部分)
    defines and keeps track of the representation it creates. (定义并跟踪所创建的表现方式)
    provides an interface for retrieving the product (e.g., GetASCIIText, GetTextWidget). (提供一个获取产品的接口)
  3. Director (RTFReader) 指挥者
    constructs an object using the Builder interface. (用建造接口创建一个对象)
  4. Product (ASCIIText, TeXText, TextWidget) 产品
    represents the complex object under construction. (表示一个正在构建的复杂对象)ConcreteBuilder builds the product’s internal representation and defines the process by which it’s assembled. (具体的建造者构建产品的内部展示,并定义了产品的组装过程)
    includes classes that define the constituent parts (包含构成产品的部件), including interfaces for assembling the parts into the final result. (包含将部件组成最终结果的接口)
    设计模式:创建型模式,设计模式,设计模式

factory method 工厂方法

未完待续

对比

背景:设计一个迷宫,仅考虑迷宫的构成:由一系列房间,墙,门组成。房间知道邻居是谁:房间,墙或者门。门连接两个房间。忽略所有和游戏者相关的操作:移动,显示等。

定义方向:enum Direction {North,South, East, West}

迷宫组件公共抽象类 MapSite
设计模式:创建型模式,设计模式,设计模式

不使用设计模式

Class MapSite
{
    public:
        virtual void Enter()=0;
};

class Room : public MapSite { 
	public : 
		Room (int roomNo) 
		MapSite* GetSide (Direction) const; 
		void SetSide (Direction, Mapsite*); 
		virtual void Enter() 
	private: 
		MapSite* _sides[4] ; 
		int _roomNumber; 
};

class Wall : public MapSite { 
	public : 
		Wall();
		virtual void Enter( ) ;
};
class Door public Mapsite { 
	public : 
		Door (Room* = 0, Room* = 0) ; 
		virtual void Enter ( ) 
		Room* OtherSideFrom (Room* ) ;
	
	private :
		Room* _room1;
		Room* _room2;
		bool _isOpen ; 
} ;

class Maze 
{
	Public:
		Maze ; 
		void AddRoom (Room* ) ; 
		Room* RoomNo ( int) const ; 
	private: 
//…
};


//创建迷宫 
Maze *MazeGame()
{
	Maze* aMaze =new Maze;
	Room *r1 = new Room(1);
	Room *r2 = new Room(2);
	Door theDoor = new Door(r1,r2);
	aMaze ->AddRoom(r1);
	aMaze ->AddRoom(r2);
	r1->SetSide(North, new Wall);
	r1->SetSide(South, theDoor );
	r1->SetSide(East,  new Wall);
	r1->SetSide(West, new Wall);
	r2 ->SetSide(North, new Wall);
	r2 ->SetSide(South,  new Wall);
	r2 ->SetSide(East,  new Wall);
	r2 ->SetSide(West, theDoor );
	return aMaze;
}

抽象工厂


 class MazeFactory ( 
public
	MazeFactory ( ) ; 
	virtual Maze* MakeMaze() const 
	{return new Maze; }
	virtual Wall* MakeWall() const 
	{return new Wall; }
	virtual Room* MakeRoom(int n) const 
	{return new Room(n)} )
	virtual Door* MakeDoor ( Room* r1, Room* r2)  const
	{return new Door (rl, r2); }
}

 class BombedMazeFactory  : public MazeFactory( 
public
	BombedMazeFactory ( ) ; 
	virtual Maze* MakeMaze() const 
	{return new Maze; }
	virtual Wall* MakeWall() const 
	{return new BombedWall; }
	virtual Room* MakeRoom(int n) const 
	{return new BombedRoom(n)} )
	virtual Door* MakeDoor ( Room* r1, Room* r2)  const
	{return new BombedDoor (rl, r2); }
}


Maze *MazeGame:: CreateMaze(MazeFactory & factory)
{
	Maze* aMaze =factory. MakeMaze() ;
	Room *r1 = factory. MakeRoom(1) ;
	Room *r2 =factory. MakeRoom(2) ;
	Door theDoor = factory.MakeDoor(r1,r2);
	aMaze ->AddRoom(r1);
	aMaze ->AddRoom(r2);
	r1->SetSide(North, factory.MakeWall() );
	r1->SetSide(South, theDoor );
	r1->SetSide(East,   factory.MakeWall() );
	r1->SetSide(West,  factory.MakeWall() );
	r2 ->SetSide(North,  factory.MakeWall() );
	r2 ->SetSide(South,   factory.MakeWall() );
	r2 ->SetSide(East,   factory.MakeWall() );
	r2 ->SetSide(West, theDoor );
	return aMaze;
}


builder

Builder 模式

class MazeBuilder { 
	public: 
		virtual void BuildMaze (){}
		virtual void BuildRoom (int room) { } 
		virtual void BuildDoor (int roomFrom. int roomTo ) { } 
		virtual Maze* GetMaze () { return 0 ; } 
	protectedMazeBuiIder();
};

该 接 口 可 以 创 建 : 1 ) 迷 宫 。 2 ) 有 一 个 特 定 房 间 号 的 房 间 。 3 ) 在 有 号 码 的 房 间 之 间 的 门 。
GetMaze 操 作 返 回 这 个 迷 宫 给 客 户 。 MazeBu11der 的 子 类 将 重 定 义 这 些 操 作 , 返 回 它 们 所 创 建
的 迷 宫 。

不定义为纯虚函数,是为了方便派生类只重定义它们感兴趣的接口

用 MazeBuilder 接 口 , 我 们 可 以 改 变 createMaze 成 员 函 数 , 以 生 成 器 作 为 它 的 参 数 。

Maze* MazeGame ::CreateMaze (MazeBuilder & builder)
 { 
	builder.BuildMaze(); 
	builder.BuildRoom(1); 
	builder.BuildRoom(2); 
	builder.BuildDoor(1,2) ;
	return builder.GetMaze()}

将 这 个 createMaze 版 本 与 原 来 的 相 比 , 注 意 生 成 器 是 如 何 隐 藏 迷 宫 的 内 部 表 示 的 一 一 一 即 定
义 房 间 、 门 和 墙 壁 的 那 些 类 . 一 一 以 及 这 些 部 件 是 如 何 组 装 成 最 终 的 迷 宫 的 。 有 人 可 能 猜 测 到
有 一 些 类 是 用 来 表 示 房 间 和 门 的 , 但 没 有 迹 象 显 示 哪 个 类 是 用 来 表 示 墻 壁 的 。 这 就 使 得 改 变
一 个 迷 宫 的 表 示 方 式 要 容 易 一 些 , 因 为 所 有 MazeBuiIder 的 客 户 都 不 需 要 被 改 变 。

MazeBuilder自己并不创建迷宫,子 类 做 实 际 工 作:
子 类 StandardMazeBuilder :一 个 创 建 简 单 迷 宫 的 实 现 。 它 将 它 正 在 创 建 的 迷 宫 放 在 变 量 _currentMaze 中 。

class StandardMazeBuiIder : public MazeBuilder
{ 
	Public:
		StandardMazeBuilder(){ _currentMaze=0}; 
		virtual void BuildMaze (){  _currentMaze = new Maze;}
		virtual void BuildRoom (int room) { } 
		virtual void BuildDoor (int roomFrom. int roomTo ) { } 
		virtual Maze* GetMaze ()return _currentMaze; } 
	Private:
		Direction CommonWall( room*, Room*);
		 Maze* _currentMaze;
}

//创造一个都是墙的房间
void StandardMazeBuilder :: BuildRoom (int n) 
{
	if (! _currentMaze—>RoomNo (n)) 
	{ 
		Room room =new Room(n);
		 _currentMaze->AddRoom(room); 
		room->SetSide (North, new  Wall); 
		room->SetSide(South, new Wall); 
		room->SetSide(East, new Wall);  
		room->SetSide(West, nev Wall);
	}
}

//建造一扇两个房间之间的门,其中CommonWall找到两个房间相邻的墙壁
Void StandardMazeBuilder::BuildDoor(int n1, int n2)
{
	Room* r1 =  _currentMaze->RoomNo(n1);
	Room* r2 =  _currentMaze->RoomNo(n2);
	Door *d = new Door(r1,r2);
	r1->SetSide(CommonWall(r1,r2) , d);
	r1->SetSide(CommonWall(r2,r1) , d);
}
现在客户可以创建迷宫了
Maze* maze; 
MazeGame game; 
StandardMazeBuiIder builder ; 
game. CreateMaze (builder) 
Maze= builder.GetMaze(); 

我 们 本 可 以 将 所 有 的 standardMazeBuiIderN 作 放 在 Maze 中 并 让 每 一 个 Maze 创 建 它 自 身 。
但 将 Maze 变 得 小 一 些 使 得 它 能 更 容 易 被 理 解 和 修 改 , 而 且 standardMazeBuiIder 易 于 从 Maze 中
分 离 。 更 重 要 的 是 , 将 两 者 分 离 使 得 你 可 以 有 多 种 MazeB 回 der , 每 一 种 使 用 不 同 的 房 间 、 墙
壁 和 门 的 类 。

对比

抽象工厂模式强调的是创造不同系列的产品,所以每个产品都有一个抽象类,比如window。而builder模式中,可能无法抽取公共产品抽象类,它更强调产品的构建方式,所以void StandardMazeBuilder :: BuildRoom (int n) 中直接定义了房间是怎么构建的,而在抽象工厂模式这个过程不在MazeFactory 里面而在Maze *MazeGame:: CreateMaze(MazeFactory & factory)函数里,也就是说MazeFactory 只负责创建不同类型的产品,客户负责组装;Builder 则自己组装想要的产品,客户直接拿文章来源地址https://www.toymoban.com/news/detail-601079.html

到了这里,关于设计模式:创建型模式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 设计模式-创建型模式-抽象工厂模式

    抽象工厂模式(Abstract Factory Pattern):提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。抽象工厂模式又称为Kit模式,它是一种对象创建型模式。 由于工厂方法模式中的每个工厂只生产一类产品,可能会导致系统中存在大量的工厂类,势必会增加系

    2024年02月22日
    浏览(53)
  • [设计模式]创建型模式-简单工厂模式

    简单工厂模式又称为静态工厂模式,属于创建型模式,但不属于GOF23设计模式。由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类。 简单工厂适用场景:工厂类负责创建的对象比较少;客户

    2024年02月20日
    浏览(45)
  • 设计模式-创建型模式-工厂方法模式

    工厂方法模式(Factory Method Pattern):定义一个用于创建对象的接口,让子类决定将哪一个类实例化。工厂方法模式让一个类的实例化延迟到其子类。工厂方法模式又简称为工厂模式(Factory Pattern),又可称作虚拟构造器模式(Virtual Constructor Pattern)或多态工厂模式(Polymorp

    2024年02月22日
    浏览(45)
  • [设计模式]创建型模式-抽象工厂模式

    抽象工厂模式是一种创建型设计模式,它提供了一种创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。抽象工厂模式将一组具有共同主题的单个工厂封装起来,它提供接口用于创建相关或依赖对象的家族,而不需要指定具体的类。 抽象工厂模式包含以下几个

    2024年03月08日
    浏览(41)
  • 设计模式—创建型模式之原型模式

    原型模式(Prototype Pattern)用于创建重复的对象,同时又能保证性能。 本体给外部提供一个克隆体进行使用。 比如我们做一个SjdwzMybatis,用来操作数据库,从数据库里面查出很多记录,其中很多记录改变很少。每次查数据库,把所有数据都封装一个对象,然后返回。假设有很

    2024年02月08日
    浏览(39)
  • 设计模式-创建型模式-单例模式

    创建型模式(Creational Pattern)关注对象的创建过程,是一类最常用的设计模式,每个创建型模式都通过采用不同的解决方案来回答3个问题:创建什么(What),由谁创建(Who)和何时创建(When)。 单例模式有3个要点:①某个类只能有一个实例;②它必须自行创建这个实例;

    2024年02月22日
    浏览(40)
  • [设计模式]创建型模式-单例模式

    单例模式是最简单的一种模式。在Go中,单例模式指的是全局只有一个实例,并且它负责创建自己的对象。单例模式有减少内存和系统资源开销、防止多个实例产生冲突等优点。 因为单例模式保证了实例的全局唯一性,并且只被初始化一次,所以比较适合全局共享一个实例,

    2024年02月19日
    浏览(40)
  • 设计模式(2) - 创建型模式

    创建型模式指的是 创建对象 或是 获取实例 的方式。 平时写一些简单的代码可能会直接用 new 创建出一个对象,但是实际在阅读一些功能比较多、规模比较庞大的工程时,可能会发现有多个类继承于同一个基类的情况,它们拥有同样的接口但是实现了不同的功能。它们可能是

    2024年02月07日
    浏览(32)
  • 设计模式-创建型模式之建造者模式

    无论是在现实世界中还是在软件系统中,都存在一些复杂的对象,它们拥有多个组成部分,如汽车,它包括车轮、方向盘、发送机等各种部件。而对于大多数用户而言,无须知道这些部件的装配细节,也几乎不会使用单独某个部件,而是使用一辆完整的汽车,可以通过建造者

    2023年04月20日
    浏览(38)
  • 学习笔记-设计模式-创建型模式-工厂模式

    工厂模式是一种创建者设计模式,细分之下可以分成三类 简单工厂模式 , 工厂方法模式 和 抽象工厂模式 。 简单工厂模式 最简单的工厂模式,它采用静态方法的方式来决定应该应该生产什么商品。 它的优点在于 将创建实例的工作与使用实例的工作分开,使用者不必关心类

    2024年02月10日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包