设计模式之美:Type Object(类型对象)
2014-04-25 15:15
881 查看
索引
意图
结构
参与者
适用性
效果
相关模式
实现
实现方式(一):Type Object 的经典介绍。
实现方式(二):Type Object 在游戏设计中的使用。
[b]意图[/b]
允许在运行时动态灵活的创建新的 "类",而这些类的实例代表着一种不同的对象类型。
Allow the flexible creation of new “classes” by creating a single class, each instance of which represents a different type of object.
[b]结构[/b]
Type Object 模式包含两个具体类。一个用于描述对象,另一个用于描述类型。每个对象都包含一个指向其类型的指针。
[b]参与者[/b]
TypeClass
是 TypeObject 的种类。
每个种类都会有一个单独的类。
TypeObject
是 TypeClass 的实例。
代表着一种对象。定义一种对象所包含的属性和行为。
[b]适用性[/b]
当以下情况成立时可以使用 Type Object 模式:
类的实例需要根据它们的通用属性或者行为进行分组。
类需要为每个分组定义一个子类来实现该分组的通用属性和行为。
类需要大量的子类或者多种变化的子类甚至无法预期子类的变化。
你需要有能力在运行时创建一些无法在设计阶段预测的新的分组。
你需要有能力在类已经被实例化的条件下更改一个对象的子类。
[b]效果[/b]
运行时创建新的类型对象。
避免子类膨胀。
客户程序无需了解实例与类型的分离。
可以动态的更改类型。
[b]相关模式[/b]
Type Object 模式有些类似于 Strategy 和 State 模式。这三种模式都是通过将对象内部的一些行为代理到外部的对象中。Stategy 和 State 通常是纯行为的代理,而 Type Object 则包含更多个共享数据状态。State 可以被频繁的更改,Type Object 则很少被改变。Strategy 通常仅包含一个职责,Type Object 则通常包含多个职责。
Type Object 的实现与 Bridge 模式中的 Abstraction 和 Implementor 的关系很像。区别在于,客户程序可以与 Type Object 直接协作,而不会直接与 Implementor 进行交互。
Type Object 有点像 Flyweight 一样处理它的对象。两个对象使用相同的 Type Object 可能看起来是使用的各自的实例,但实际是共享的对象。
Type Object 可以解决多个对象共享数据和行为的问题。类似的问题也可以用 Prototype 模式来解决。
[b]实现[/b]
实现方式(一):Type Object 的经典介绍。
TypeClass - Movie
TypeObject - Star Wars, The Terminator, Independence Day
Class - Videotape
Object - John's Star Wars, Sue's Star Wars
实现方式(二):Type Object 在游戏设计中的使用。
想象我们正在制作在一个虚拟角色扮演游戏。我们的任务是设计一些邪恶的怪兽(Monster)来试图杀掉我们的英雄(Hero)。怪兽有着一些不同的属性,例如生命值(Health)、攻击力(Attacks)、图像、声音等,但以举例为目的我们仅考虑前两个属性。
游戏中的每个怪兽都有自己的生命值。生命值从满血开始,每次怪兽被创伤,生命值减少。怪兽会有一个用于描述攻击的字符串,当怪兽攻击英雄时,这个字符串会被显示到用户屏幕上。
游戏设计师告诉我们,怪兽会有不同的品种(Breed),例如:猛龙(Dragon)和巨魔(Troll)。每个怪兽品种都描述了一种怪兽,在一个场景下会有多个同一种的怪兽遍布在地牢(Dungeon)中。
怪兽的品种(Breed)决定的怪兽的起始生命值,比如猛龙(Dragon)的生命值会比巨魔(Troll)的高,以使猛龙更难被杀掉。同时,同一个品种的怪兽的攻击字符串也是相同的。
通过典型的 OO 设计,我们能得到下面这段代码:
这段代码浅显易懂,使用继承的方式设计类的层级结构。一个 Dragon 是一个 Monster,满足了 "is a" 的关系。每一个怪物的品种都会用一个子类来实现。
如果游戏中有成百上千的怪物种类,则类的继承关系变得庞大。同时也意味着,增加新的怪物品种就需要增加新的子类代码。
这是可以工作的,但并不是唯一的选择。我们可以尝试另外一种架构。
因为变化较多的部分是品种(Breed)的属性配置,包括生命值和攻击字符串。
所以我们可以将品种(Breed)抽取成单独的类,每个怪物类(Monster)包含一个品种类(Breed)。
Breed 类用于定义 Monster 的 "type"。每一个 Breed 的实例描述着一种 Monster 对象的概念上的 "type"。
Type Object 在这里的优势在于,我们可以定义新的类型的怪物,而不用修改代码。并且可以在运行时动态生成新的对象和修改对象的属性。
The Type Object Pattern
《设计模式之美》为 Dennis Gao 发布于博客园的系列文章,任何未经作者本人同意的人为或爬虫转载均为耍流氓。
意图
结构
参与者
适用性
效果
相关模式
实现
实现方式(一):Type Object 的经典介绍。
实现方式(二):Type Object 在游戏设计中的使用。
[b]意图[/b]
允许在运行时动态灵活的创建新的 "类",而这些类的实例代表着一种不同的对象类型。
Allow the flexible creation of new “classes” by creating a single class, each instance of which represents a different type of object.
[b]结构[/b]
Type Object 模式包含两个具体类。一个用于描述对象,另一个用于描述类型。每个对象都包含一个指向其类型的指针。
[b]参与者[/b]
TypeClass
是 TypeObject 的种类。
每个种类都会有一个单独的类。
TypeObject
是 TypeClass 的实例。
代表着一种对象。定义一种对象所包含的属性和行为。
[b]适用性[/b]
当以下情况成立时可以使用 Type Object 模式:
类的实例需要根据它们的通用属性或者行为进行分组。
类需要为每个分组定义一个子类来实现该分组的通用属性和行为。
类需要大量的子类或者多种变化的子类甚至无法预期子类的变化。
你需要有能力在运行时创建一些无法在设计阶段预测的新的分组。
你需要有能力在类已经被实例化的条件下更改一个对象的子类。
[b]效果[/b]
运行时创建新的类型对象。
避免子类膨胀。
客户程序无需了解实例与类型的分离。
可以动态的更改类型。
[b]相关模式[/b]
Type Object 模式有些类似于 Strategy 和 State 模式。这三种模式都是通过将对象内部的一些行为代理到外部的对象中。Stategy 和 State 通常是纯行为的代理,而 Type Object 则包含更多个共享数据状态。State 可以被频繁的更改,Type Object 则很少被改变。Strategy 通常仅包含一个职责,Type Object 则通常包含多个职责。
Type Object 的实现与 Bridge 模式中的 Abstraction 和 Implementor 的关系很像。区别在于,客户程序可以与 Type Object 直接协作,而不会直接与 Implementor 进行交互。
Type Object 有点像 Flyweight 一样处理它的对象。两个对象使用相同的 Type Object 可能看起来是使用的各自的实例,但实际是共享的对象。
Type Object 可以解决多个对象共享数据和行为的问题。类似的问题也可以用 Prototype 模式来解决。
[b]实现[/b]
实现方式(一):Type Object 的经典介绍。
TypeClass - Movie
TypeObject - Star Wars, The Terminator, Independence Day
Class - Videotape
Object - John's Star Wars, Sue's Star Wars
namespace TypeObjectPattern.Implementation1 { public class Movie { public string Title { get; set; } public float RentalPrice { get; set; } } public class Videotape { public Videotape(Movie movie) { this.Movie = movie; } public Movie Movie { get; private set; } public Customer Renter { get; private set; } public bool IsRented { get; private set; } public void RentTo(Customer customer) { IsRented = true; Renter = customer; Renter.ChargeForRental(this.Movie.RentalPrice); } } public class Customer { public string Name { get; set; } public void ChargeForRental(float rental) { // pay money } } public class Client { public void TestCase1() { Customer john = new Customer() { Name = "John" }; Customer sue = new Customer() { Name = "Sue" }; Movie starWars = new Movie() { Title = "Star Wars", RentalPrice = 100, }; Movie terminator = new Movie() { Title = "The Terminator", RentalPrice = 200, }; Videotape starWarsVideotapeForJohn = new Videotape(starWars); starWarsVideotapeForJohn.RentTo(john); Videotape starWarsVideotapeForSue = new Videotape(starWars); starWarsVideotapeForSue.RentTo(john); Videotape terminatorVideotapeForJohn = new Videotape(terminator); terminatorVideotapeForJohn.RentTo(john); } } }
实现方式(二):Type Object 在游戏设计中的使用。
想象我们正在制作在一个虚拟角色扮演游戏。我们的任务是设计一些邪恶的怪兽(Monster)来试图杀掉我们的英雄(Hero)。怪兽有着一些不同的属性,例如生命值(Health)、攻击力(Attacks)、图像、声音等,但以举例为目的我们仅考虑前两个属性。
游戏中的每个怪兽都有自己的生命值。生命值从满血开始,每次怪兽被创伤,生命值减少。怪兽会有一个用于描述攻击的字符串,当怪兽攻击英雄时,这个字符串会被显示到用户屏幕上。
游戏设计师告诉我们,怪兽会有不同的品种(Breed),例如:猛龙(Dragon)和巨魔(Troll)。每个怪兽品种都描述了一种怪兽,在一个场景下会有多个同一种的怪兽遍布在地牢(Dungeon)中。
怪兽的品种(Breed)决定的怪兽的起始生命值,比如猛龙(Dragon)的生命值会比巨魔(Troll)的高,以使猛龙更难被杀掉。同时,同一个品种的怪兽的攻击字符串也是相同的。
通过典型的 OO 设计,我们能得到下面这段代码:
namespace TypeObjectPattern.Implementation2 { public abstract class Monster { public Monster(int startingHealth) { Health = startingHealth; } public int Health { get; private set; } public abstract string AttackString { get; } } public class Dragon : Monster { public Dragon() : base(500) { } public override string AttackString { get { return "The dragon breathes fire!"; } } } public class Troll : Monster { public Troll() : base(300) { } public override string AttackString { get { return "The troll clubs you!"; } } } public class Client { public void TestCase2() { Monster dragon = new Dragon(); Monster troll = new Troll(); } } }
这段代码浅显易懂,使用继承的方式设计类的层级结构。一个 Dragon 是一个 Monster,满足了 "is a" 的关系。每一个怪物的品种都会用一个子类来实现。
如果游戏中有成百上千的怪物种类,则类的继承关系变得庞大。同时也意味着,增加新的怪物品种就需要增加新的子类代码。
这是可以工作的,但并不是唯一的选择。我们可以尝试另外一种架构。
因为变化较多的部分是品种(Breed)的属性配置,包括生命值和攻击字符串。
所以我们可以将品种(Breed)抽取成单独的类,每个怪物类(Monster)包含一个品种类(Breed)。
Breed 类用于定义 Monster 的 "type"。每一个 Breed 的实例描述着一种 Monster 对象的概念上的 "type"。
namespace TypeObjectPattern.Implementation3 { public class Breed { public int Health { get; set; } public string AttackString { get; set; } } public class Monster { private Breed _breed; public Monster(Breed breed) { _breed = breed; } public int Health { get { return _breed.Health; } } public string AttackString { get { return _breed.AttackString; } } } public class Client { public void TestCase3() { Breed dragonBreed = new Breed() { Health = 500, AttackString = "The dragon breathes fire!", }; Breed trollBreed = new Breed() { Health = 300, AttackString = "The troll clubs you!", }; Monster dragon = new Monster(dragonBreed); Monster breed = new Monster(trollBreed); } } }
Type Object 在这里的优势在于,我们可以定义新的类型的怪物,而不用修改代码。并且可以在运行时动态生成新的对象和修改对象的属性。
参考资料
Type Object - Game Programming PatternsThe Type Object Pattern
《设计模式之美》为 Dennis Gao 发布于博客园的系列文章,任何未经作者本人同意的人为或爬虫转载均为耍流氓。
相关文章推荐
- 一。对象管理第一次初始化(ObInitSystem) + 类型对象的创建(ObCreateObjectType)
- immutable Object 不可变对象设计模式
- php设计模式中的类型安全 指--只接受特定的对象 ---以避免发生错误
- 【转】Oracle Object type 对象类型详解
- 【初学设计模式】Object Adapter (对象适配器)
- Design Patterns - Elements of Reusable Object-Oriented Software 设计模式-可复用的面向对象软件元素。【笔记】
- 对象、接口-设计模式主要分三个类型:创建型、结构型和行为型。-by小雨
- Type Object——类型对象
- 【设计模式】传输对象模式(Transfer Object Pattern)
- 设计模式 一 值对象模式(The Value Object Pattern)
- 【CDP-云设计模式】第6章,3.直接对象上传模式(Direct Object Upload Pattern)
- 设计模式- 主动对象(Active Object)
- 设计模式- 主动对象(Active Object)
- Oracle Object type 对象类型
- js判断对象类型 typeof与Object.prototype.toString.call方法的区别
- JavaScript-对象类型object type
- SAP Business One 对象类型大全 (Object Type)
- 设计模式【空对象模式NullObjectPattern】
- 设计模式之美:Role Object(角色对象)
- 设计模式学习—传输对象模式(Transfer Object Design Pattern)