3

我们正在构建一个新的单页前端来替换我们网络应用程序的旧静态 html 前端(带有一些 jquery)。这样做时,我们遇到了一个关于我们从 api 返回的对象类型的问题。

当从我们的 PHP 后端将数据导出为 JSON 时,我们包含一个额外的字段,我们在其中放置对象在导出之前的类型。我们可以使用它来处理我们请求的资源的不同子类。

然而,有时我们也想区分父类。考虑以下场景:

继承树:

Animal
    Mammal
        Human
        Dog
        ...
    Reptile
        Crocodile
        Snake
        ...

获取/动物/

[
    {"_type": "Human", "id": 1, "food": "Ice Cream"},
    {"_type": "Human", "id": 2, "food": "Steak"},
    {"_type": "Human", "id": 3, "food": "Peanut Butter"},
    {"_type": "Dog", "id": 4, "food": "Horse Poop"}
    {"_type": "Crocodile", "id": 5, "food": "Humans"}
]

当我有某个 UI 想要显示所有动物但例如突出显示所有哺乳动物时,我遇到了问题,因为我失去了哪些动物是哺乳动物的知识。

我们提出的最简单的解决方案是在从后端导出对象时包含继承链。可能是这样的:

{
    "_type": "Human",
    "id": 10,
    "food": "Ice Cream",
    "_parentClasses": "Animal.Mammal.Human"
}

虽然我不认为这是一个特别好的解决方案,但它很容易实现和使用,而且看起来很健壮。

您认为这是一个好/好的/坏主意吗?您是如何解决这个问题的?

4

5 回答 5

1

在我看来,导致你心痛的正是你的输出对象变平。也许 GET/Animals 应该返回类似于以下的内容:

[
    {"Mammals": {   
        {"_type": "Human", "id": 1, "food": "Ice Cream"},
        {"_type": "Human", "id": 2, "food": "Steak"},
        {"_type": "Human", "id": 3, "food": "Peanut Butter"},
        {"_type": "Dog", "id": 4, "food": "Horse Poop"}
    },
    {"Reptiles": {
        {"_type": "Crocodile", "id": 5, "food": "Humans"}
    }
]

如果您可以在输出时保留对象的结构,那么当您将该复杂对象发送回服务器时,您的结构应该保持不变。

于 2013-03-20T14:15:08.937 回答
1

有很多选择。这是我没见过的一个:

使您_type的数组而不是字符串,第一项包含当前类和其余父类。

{
    "_type": ["Human","Mammal","Animal"],
    "id": 10,
    "food": "Ice Cream"
}

这应该很容易在 PHP 端实现:

$_type = array_keys(class_parents($this));
array_unshift($_type, get_class($this));
于 2013-03-20T14:21:42.857 回答
1

许多好的答案,这是您可能想要考虑的另一种选择。

您只需将子类以 JSON 格式发送给客户端,然后客户端会查找其基类是什么。它将一些复杂性从服务器端转移到客户端,并保持 JSON 消息干净。

于 2013-03-26T13:12:12.310 回答
0

我可以看到几种可能实现这一目标的方法。您可以开发您的 REST 服务器以接受 URI,例如:

/animals/mammal/humans 
/animals/mammal/dog
/animals/reptile/crocodile

或者,只需返回上面所述的对象类型。根据类型构建对象。

<?php
    $object = null;     

    switch($_type){
      case 'human':
          $object = new Human();
      break;

      case 'dog':
          $object = new Dog();
      break;

      case 'crocodile':
        $object = new Crocodile();
      break;
    }
?>

关于如何解决这个问题的两分钱。

于 2013-03-20T14:10:05.270 回答
0

不确定这是否真的可以作为答案(或者甚至该问题可以作为问题!),但几年前我在时间管理器上使用了类似的过程;继承路径以类似的方式完成。我发现它比一些基本上会导致更多工作的替代方案更容易和更直观。

为了简单起见,我还打破了 OOP 的正常规则,不仅允许父母认识孩子,而且让孩子认识父母。它确实为代码增加了一点,但它是可行的,并且再次使整个过程不那么痛苦。

于 2013-03-20T14:11:28.027 回答