如何在OO中对此进行建模

时间:2008-12-09 19:58:40

标签: oop

我有一个类似于此的UI对话框:您必须从列表中选择一本书。 (可选)您可以从列表中选择发布者(另一个类),也可以输入publisher-name和字符串。

我认为这给了我3种类型作为对话框的输出。

  1. 与发布商级的书籍
  2. 使用publisher-string预订
  3. 你会如何在物体中建模?在我看来,拥有一个图书基础类,然后是发布者和出版商名称的两个子类是正确的选择。有没有其他选择,也许有利于提供更好模型的构图?


    我会尝试解释一下。 一本书不需要有出版商。 发布者对象与作为字符串输入的发布者名称不同。

    你必须 - 从现有名单中选择一本书

    您可以使用以下其中一项 - 从现有列表中选择发布者或
    - 您可以输入出版商名称或
    - 你不能填写关于出版商的任何内容

8 个答案:

答案 0 :(得分:5)

第二个是我的方法。

我会为Publisher提供一个名为Name的属性,以及描述发布者所需的任何其他属性。

然后我会有一个带有属性的书来描述它,以及一个类型为Publisher的属性。

如果用户以字符串形式输入新发布者,请创建一个新的Publisher对象。

如果用户未输入发布者,请将该属性保留为null。这将满足该书没有出版商的条件。或者,您可以让发布商名称为“No publisher”,但我认为这样做太过于避免空值。

答案 1 :(得分:2)

从OO的角度来看,在这种情况下,HAS-A关系比IS-A关系更好地解决了这个问题。一本书HAS-A出版商(1:1)和出版商HAS-它出版的书籍清单(1:很多)。创建一个Book类,其中包含对Publisher的引用和Publisher类,该类具有对Books的引用列表。此外,您可以使用发布者HAS-A字符串来查找特定发布者

答案 2 :(得分:2)

我必须在最后一段中不同意这一说法:

  

在我看来,拥有一个图书基础类,然后是出版商和出版商名称的两个子类是正确的选择。

子类用于表示“is-a-kind-of”关系。 (旧的厌倦刻板印象是Fruit类,Apple和Orange作为子类。)更现实的例子是具有Employee类的工资单系统,由HourlyEmployee和SalariedEmployee类专门化。在每种情况下,子类代表超类中的特定类别。

相比之下,出版商不是一本书。一个更好的模型是拥有一个Book类和一个Publisher类,它们之间有多对一的关系(一本书有一个发布者,但一个出版商可能会生成多本书)。

一本书有许多潜在的属性,例如标题,ISBN,出版商和作者;发布者的潜在属性包括商家名称和地址(可能是多个地址)和已发布的书籍列表。

根据您要模拟的内容,您可能还需要一个Author类,但这不在原始问题的范围内。

答案 3 :(得分:1)

我不会创建一个Publisher类来继承Book,因为 发布者不是一本书,它是关于一本书的元数据信息。 然而,圣经将继承书。

我的建议是在Book上创建一个Publisher属性。 此发布者可以是IPublishInformation类型, 字符串发布者可以使用NamedPublisher {string Name}类,实现IPublishInformation。

无论如何,这是我的想法!

答案 4 :(得分:1)

  

我会尝试解释一下。一本书   不需要有出版商。该   发布者对象与a不同   publisher-name作为字符串输入。

     

你必须    - 从现有名单中选择一本书

     

您可以执行以下操作之一    - 从现有列表中选择发布者或    - 您可以输入出版商名称或    - 你不能填写关于出版商的任何内容

仍然要求自定义结果对象。现在,您有三个字段:Book对象,Publisher对象和Publisher字符串。然后,您将其传递给可以智能处理它的代码。您可以添加方法来满足自定义处理需求。但最终它是THAT对话框的专门结果,不应该是书籍或出版商或任何其他对象的某个子字段。

如果这本书没什么,你知道你因为需要一本书而得到错误。您还有Publisher Object和Publisher_String的四种组合来处理。这对我来说,你需要一个专门处理结果的课程。

答案 5 :(得分:0)

我认为很难根据此对话框做出设计决策。例如,您是从一组现有书中挑选的吗?在这种情况下,如果用户输入不存在的发布者,该怎么办?在这种情况下,您可能根本不想返回任何Book类的实例,但会引发某种异常。

您案例中的所有图书都有发布商吗?如果是这样,那么我同意@Bob你可以创建一个Publisher类,并让Book类包含一个Publisher对象的实例。如果只有一些书籍有Publishers,那么你可以使用你描述的继承模型,但我会将选项2和3折叠成一个选项(再次使用Publisher对象),否则你最终会得到两个相同的实例作为不同类型的对象的书(用户以字符串形式输入发布者,以及从列表中选择一次)。

- 菲尔

答案 6 :(得分:0)

如果您假设图书可以有多个发布商。然后我将返回一个具有两个礼仪的BookSelectonResult。一个设置为Book,另一个设置为选定的Publisher。这个答案还假设你有一个书类,一个发布者类和一个集合类。

对话框的目的是返回用户选择的内容。这是一个独特的“事物”,所以值得拥有它自己的阶级。如果您所做的只是返回一本书或一个发布者,那么直接使用原始类就可以了。但是在这里,您在结果中有多种可能性,因此需要调用唯一的结果类。

另一个考虑因素是这个对话有多么微不足道?例如,选择文件名以打开书籍。文件名存在,你想要的是要存储在你系统中的书。选择书籍和出版商的结果相同。如果你有另一个对象来保存结果(如签出列表),那么我建议不要打扰任何特殊的方法或类。将对话框捆绑到Command对象中,只返回对话框类成员中的结果。然后将结果处理到最终存储的位置。

在我的CAM软件中,我经常使用操作配置选项的对话框而不是使用我精心设计的模型 - 视图 - 展示器架构。我可以逃避这一点的原因是因为当用户点击某个项目或执行某个操作时,UI控制器会执行一个Command对象,然后操作该模型。在我的设置中,所有内容都通过Command Object。因此,对于琐碎的对话框,我只是将它们与使用对话框的命令对象捆绑在一起,而不是创建整个MVP层。

最终这是一个判断电话。

答案 7 :(得分:0)

试试这个(C#):

Class Book
{
   public string Name;
   public List<Publisher> publishers = new List<Publishers>;

   Book()
   {
      // Load publishers array with relevant instances of Publisher class...
   }
}

Class Books
{
   private List<Book> books = new List<Book>;
   public Books()
   {
      // Load books array with all books...
   }

   public List<Book> GetBook (string publisher)
   {
      List<Book> retVal = new List<Book>;
      foreach (Book item in books)
      {
         if (item.Publisher.Name == publisher)
         {
            retVal.Add(item);
         }
      }
   }

   public List<Book> GetBook (Publisher publisher)
   {
      List<Book> retVal = new List<Book>;
      foreach (Book item in books)
      {
         if (item.Publisher.Name == publisher.Name)
         {
            retVal.Add(item);
         }
      }
   }
}

Class Publisher
{
   public string Name;
}