工厂应该住在哪个项目?

时间:2015-08-10 19:52:47

标签: c# domain-driven-design factory-pattern

我有一个名为var subtotal = 0; if (quantity == 6) { $('#bottle-image').replaceWith('<div id="bottle-image"> <img src="https://nmhfiles.com/images/nsn/650SSO2_FPOF/Soothanol-6Bottles.jpg" alt="Soothanol" width="150" /></div>'); subtotal = 149.85; } else if (quantity == 3) { $('#bottle-image').replaceWith('<div id="bottle-image"> <img src="https://nmhfiles.com/images/nsn/650SSO2_FPOF/Soothanol-3Bottles.jpg" alt="Soothanol" width="150" /></div>'); subtotal = 99.90; } else if (quantity == 1) { $('#bottle-image').replaceWith('<div id="bottle-image"> <img src="https://nmhfiles.com/images/nsn/650SSO2_FPOF/Soothanol-1Bottle.jpg" alt="Soothanol" width="150" /></div>'); subtotal = 49.95; } 的项目的解决方案。这个项目包含一些基本类,然后是我的域对象被抽象的所有接口。接口如MudEngine.CoreIWorld

示例域接口

IRealm

我还有一个名为public interface IWorld : IGameComponent, ICloneableComponent<IWorld> { /// <summary> /// Gets how many hours it takes to complete one full day in this world. /// </summary> int HoursPerDay { get; } /// <summary> /// Gets or sets the game day to real hour ratio. /// </summary> double GameDayToRealHourRatio { get; set; } /// <summary> /// Adds a collection of realms to world, initializing them as they are added. /// </summary> /// <param name="realms">The realms.</param> /// <returns> /// Returns an awaitable Task /// </returns> IRealm[] GetRealmsInWorld(); /// <summary> /// Initializes and then adds the given realm to this world instance. /// </summary> /// <param name="realm">The realm to add.</param> /// <returns>Returns an awaitable Task</returns> Task AddRealmToWorld(IRealm realm); /// <summary> /// Creates and initializes a new instance of a realm. /// </summary> /// <param name="name">The name of the realm.</param> /// <param name="owner">The world that owns this realm.</param> /// <returns>Returns an initialized instance of IRealm</returns> Task<IRealm> CreateRealm(string name, IWorld owner); /// <summary> /// Adds a collection of realms to world, initializing them as they are added. /// </summary> /// <param name="realms">The realms.</param> /// <returns>Returns an awaitable Task</returns> Task AddRealmsToWorld(IEnumerable<IRealm> realms); /// <summary> /// Removes the given realm from this world instance, deleting the realm in the process. /// If it must be reused, you may clone the realm and add the clone to another world. /// </summary> /// <param name="realm">The realm to remove.</param> /// <returns>Returns an awaitable Task</returns> Task RemoveRealmFromWorld(IRealm realm); /// <summary> /// Removes a collection of realms from this world instance. /// If any of the realms don't exist in the world, they will be ignored. /// The realms will be deleted during the process. /// If they must be reused, you may clone the realm and add the clone to another world. /// </summary> /// <param name="realms">The realms collection.</param> /// <returns>Returns an awaitable Task</returns> Task RemoveRealmsFromWorld(IEnumerable<IRealm> realms); } 的项目,它是所有接口的默认实现。

MudEngine.Mud项目包含我工厂的接口。像MudEngine.CoreIWorldFactory这样的工厂。 IWorld接口有一个创建方法,它使用给定的IRealmFactory来创建领域并返回它们。

示例工厂界面

IRealmFactory

当我在IWorld界面上调用/// <summary> /// Provides methods for creating an instance of an IRealm implementation /// </summary> public interface IRealmFactory { /// <summary> /// Creates and initializes a new instance of a realm. /// </summary> /// <param name="name">The name of the realm.</param> /// <param name="owner">The world that owns this realm.</param> /// <returns>Returns an initialized instance of IRealm</returns> Task<IRealm> CreateRealm(string name, IWorld owner); /// <summary> /// Creates and initializes a new instance of a realm. /// </summary> /// <param name="name">The name of the realm.</param> /// <param name="owner">The world that owns this realm.</param> /// <param name="timeZoneOffset">The time zone offset to apply to the realm.</param> /// <returns>Returns an initialized instance of IRealm</returns> Task<IRealm> CreateRealm(string name, IWorld owner, ITimeOfDay timeZoneOffset); /// <summary> /// Creates and initializes a new instance of a realm. /// All of the children zones will be initialized prior to being added to the realm. /// </summary> /// <param name="name">The name of the realm.</param> /// <param name="owner">The world that owns this realm.</param> /// <param name="zones">A collection of zones that will be initialized and added to the realm.</param> /// <returns>Returns an initialized instance of IRealm</returns> Task<IRealm> CreateRealm(string name, IWorld owner, IEnumerable<IZone> zones); /// <summary> /// Creates and initializes a new instance of a realm. /// All of the children zones will be initialized prior to being added to the realm. /// </summary> /// <param name="name">The name of the realm.</param> /// <param name="owner">The world that owns this realm.</param> /// <param name="timeZoneOffset">The time zone offset to apply to the realm.</param> /// <param name="zones">A collection of zones that will be initialized and added to the realm.</param> /// <returns>Returns an initialized instance of IRealm</returns> Task<IRealm> CreateRealm(string name, IWorld owner, ITimeOfDay timeZoneOffset, IEnumerable<IZone> zones); } 时,实现使用IRealmFactory来创建它。工厂通过IWorld实现的构造函数传递。

我现在的问题是,工厂实施应该在哪里?包含域接口实现的同一项目是否通常为工厂提供实现,或者消耗层(例如表示/单元测试项目)是否负责实现工厂并使用它们?

目的是根据您正在构建的基于文本的游戏的类型,可以换出这些组件。所以我倾向于实现具有自己工厂的接口的每个包。我关心的是DI设置。进一步在分层(服务器/客户端应用程序)中的IoC容器需要知道它应该使用每个包中的哪个工厂,而不是仅使用在IoC容器所属的消耗层中定义的工厂。 / p>

有没有关于此的行业标准指南?

1 个答案:

答案 0 :(得分:0)

您似乎正在尝试使用抽象的子域构建域模型(我猜您可以将它们称为子域,因为它们是完整的游戏系统),即用户可以在运行时动态选择子域,从而触发一些子域不可知行为,然后用它做一些特定于子域​​的东西一段时间,并在它们完成时跳转到另一个。

虽然根据我的经验,你很少在“正常”的商业项目中遇到这个问题,但这就是我要做的事情:

  • 为通用的World和Realm管理创建一个总体有界上下文。将IWorldIRealmFactory放在那里。

  • 为每个游戏系统子域创建一个单独的Bounded Context。它们可以是整个项目,也可以只是命名空间。在这些中编写IRealmFactory的实现。

  • 我认为使用Container.Resolve(...)时的少数几个实例之一可能是合法的。在IoC配置中创建命名注册,并随时解析其中一个注册,以连接对应于一个游戏系统的对象子图。