我们正在构建一个新的单页面前端来替换我们的web-app的旧静态html前端(带有一些jquery)。在这样做时,我们遇到了一个关于我们从api返回的对象类型的问题。
当我们从PHP后端导出数据作为JSON时,我们包含一个额外的字段,我们在导出之前放置对象所具有的类型。我们可以使用它来处理我们请求的资源的不同子类。
然而,有时我们也想区分父类。请考虑以下情形:
继承树:
Animal
Mammal
Human
Dog
...
Reptile
Crocodile
Snake
...
GET / animals /
[
{"_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"
}
虽然我认为这不是一个特别好的解决方案,但它很容易实现和使用,而且看起来很健壮。
你认为这是一个好/好/坏主意,你是如何解决这个问题的?
答案 0 :(得分: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"}
}
]
如果您可以在输出中保留对象的结构,当您将该复杂对象发送回服务器时,您的结构应保持不变。
答案 1 :(得分:1)
有很多选择。这是我没见过的一个:
使_type
数组而不是字符串,第一项包含当前类和其余父类。
{
"_type": ["Human","Mammal","Animal"],
"id": 10,
"food": "Ice Cream"
}
这应该很容易在PHP方面实现:
$_type = array_keys(class_parents($this));
array_unshift($_type, get_class($this));
答案 2 :(得分:1)
许多好的答案,这是您可能想要考虑的另一种选择。
您只能使用JSON将子类发送到客户端,然后客户端会对其基类进行查找。它将一些复杂性从服务器端移动到客户端,并使您的JSON消息保持清洁。
答案 3 :(得分: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;
}
?>
关于我如何解决这个问题只是我的两分钱。
答案 4 :(得分:0)
不确定这是否有资格作为答案,真的(或者甚至该问题属于问题!!),但几年前我在时间管理器上使用了类似的过程;以类似的方式完成继承路径。我发现使用它非常简单,更直观,而且一些替代方案基本上会导致更多的工作。
为了扩展简单性,我还打破了OOP的正常规则,不仅允许父母知道孩子,还让孩子知道父母。它确实为代码添加了一点但它可行,并且再次使整个过程不那么痛苦。