让我们假设我负责开发一个Scrabble游戏,因为客户的主要要求之一是能够在以后尝试不同的游戏方式和模式。我已经制作了一个足够灵活的设计来支持这些变化。剩下的唯一问题是暴露给客户端的内容(对象的访问修饰符),以及如何组织它(如何在命名空间/包中公开我的对象)。
我应该如何定义这样的东西,使客户端可以轻松使用我的标准实现(标准的Scrabble游戏,但能够进行他想要的所有修改?我猜我需要的是一种框架,在他可以继续工作。
我在非严格的分层系统中组织了我的类/接口:
包含可能在整个系统中使用的基本数据类型。系统中的任何人都可以访问此程序包及其成员。所有成员都是公开的。
包含我定义的所有接口,这些接口可能有助于创建客户端的新Scrabble实现。还包含游戏中使用的值类型,如Piece。所有成员都是公开的。
包含在Implementations.StandardScrabble包中实现标准Scrabble游戏所需的所有类/代码。如果客户决定实现游戏的其他变体,他可以在Implementations.XYZ中创建它们。 这些类都受到包保护,并且包外部唯一可用的是游戏外观。使用域和数据类型包。
包含我已实现的UI类,以便客户端和程序用户都可以运行游戏(我的实现)。可以访问所有其他图层。
我组织事物的方式有几个缺点,最明显的是如果客户想要创建自己的游戏版本,他必须基本上自己实现几乎所有东西(我在域中共享接口,但他几乎不能做任何事情)。我觉得我应该将所有的实现类传递给Domain,然后只有一个Façade在Implementations命名空间中构建我的标准Scrabble?
你会怎么做?是否有关于如何构建这种程序(基本上是框架)的推荐阅读?
由于
答案 0 :(得分:2)
对于算法和策略,我将定义接口和默认实现,并提供由您自己的实现扩展的抽象超类,以便所有样板代码都在抽象超类中。另外我会允许客户端继承你的impl。只要制作一个以上的impl,你就会看到放在哪里。
但最重要的是:为您的客户提供代码。如果他需要了解放置代码的位置,他也应该能够看到你编码的内容。无需隐藏东西。
答案 1 :(得分:2)
我认为你试图给客户太多的自由。这必须使你难以处理的事情。根据您所描述的内容,似乎客户端几乎可以修改游戏的所有部分 - 模型,逻辑,UI ......我认为最好限制应用程序中的可修改区域,但是通过常规来暴露一些区域{ {1}}接口集。这将使用户更容易 - 他只需要了解插件的工作方式,而不是整个应用程序的逻辑。如果需要,可以为插件定义区域 - UI插件,游戏模式插件等。许多制作应用程序和游戏以这种方式工作(回想起暗黑破坏神II以及它拥有的令人惊奇的各种插件!)。
答案 2 :(得分:2)
无论你想出什么设计,我都会尽可能地隐藏尽可能多的实现。一旦你暴露了一个实现,你就无法收回它(除非你准备好与你的客户群发生火焰战争)。您可以随时根据需要提供默认实现。
通常,我首先只提供精简的界面。然后,在提供抽象类之前,我可能会提供实用程序类(例如Factories
,Builders
等。)
我建议您在设计面向对象的代码时阅读Josh Bloch撰写的 Effective Java ,了解有用的一般做法。
答案 3 :(得分:0)
MVC / Compund Pattern
您可以发布早期版本的软件包。 稍后您可以根据用户要求进行升级。
如果您明智地使用MVC或其他复合模式,我相信您也可以轻松升级您的包。