Javascript 在基于REST的web应用程序中保留继承的概念
我们正在构建一个新的单页前端,以替换web应用程序中旧的静态html前端(使用一些jquery)。在这样做的过程中,我们遇到了一个关于从api返回的对象类型的问题 当从PHP后端将数据导出为JSON时,我们会包含一个额外的字段,在该字段中输入导出之前对象的类型。我们可以使用它来处理我们请求的资源的不同子类 然而,有时我们也希望区分父类。考虑下面的场景: 继承树:Javascript 在基于REST的web应用程序中保留继承的概念,javascript,rest,inheritance,Javascript,Rest,Inheritance,我们正在构建一个新的单页前端,以替换web应用程序中旧的静态html前端(使用一些jquery)。在这样做的过程中,我们遇到了一个关于从api返回的对象类型的问题 当从PHP后端将数据导出为JSON时,我们会包含一个额外的字段,在该字段中输入导出之前对象的类型。我们可以使用它来处理我们请求的资源的不同子类 然而,有时我们也希望区分父类。考虑下面的场景: 继承树: Animal Mammal Human Dog ... Reptile
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"
}
虽然我不认为这是一个特别好的解决方案,但它很容易实现和使用,并且看起来很健壮。
你认为这是一个好/好/坏的主意吗?你是如何解决这个问题的?我可以看到几种可能实现这一点的方法。您可以开发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;
}
?>
关于如何解决这个问题,我只花了两分钱。真的不确定这是否是一个合格的答案(甚至这个问题也可以是一个问题!!),但几年前我在一个时间经理身上使用了类似的过程;继承路径以类似的方式完成。我发现,与一些基本上会导致更多后续工作的替代方案相比,使用它非常简单,也更直观
为了扩展这种简单性,我还打破了OOP的常规规则,不仅允许父对象了解子对象,而且允许子对象了解父对象。它确实为代码增加了一点内容,但它是可行的,并且,再次使整个过程不那么痛苦。在我看来,引起您心痛的正是输出时对象的扁平化。也许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"}
}
]
如果您可以在输出时保留对象的结构,那么当您将复杂对象发送回服务器时,您的结构应该保持不变。有许多选项。这里有一个我没见过的地方提到: 将
\u type
设置为数组而不是字符串,第一项包含当前类和其余父类
{
"_type": ["Human","Mammal","Animal"],
"id": 10,
"food": "Ice Cream"
}
这应该很容易在PHP端实现:
$\u type=array\u键(类父项($this));
数组_unshift($_类型,get_类($this));
许多好的答案,这里是另一个你可能想考虑的选项
只将子类发送到JSON中的客户机,然后客户机执行查找,不管它的基类是什么。它将一些复杂性从服务器端转移到客户端,您可以保持JSON消息的干净。这并不能解决我的问题,因为我想获取(并使用)完整列表,但仍然需要知道对象具有哪些超类。我刚刚更新了我的帖子,您可能希望使用类似于上面PHP代码的东西。@ilikempizza我非常不喜欢您的更新方法。这需要类型和父级之间的硬编码关系,或者由数据库查找推断的关系。这可能不是一个优雅的解决方案。大卫,谢谢你的反馈。我需要弄清楚逻辑,但应该是类似于。。试试{$object=new$\u type;}catch(Exception$e){//Exception Handler}客户端是JavaScript,而不是PHP,我希望客户端逻辑尽可能轻(并且需要尽可能少的知识)an将使其难以使用(在所有元素上循环将需要更多的代码,甚至需要知道此结构具有多少级别)。@martijnve这告诉我的是,如果它是一个简单的列表,它首先就不能正确地保存关系。也许重构是合适的。我通常将整个复杂对象结构序列化到JSON负载中,保留顺序。不幸的是,我不知道这在php中有多困难,但我认为对于复杂对象有很好的JSON序列化程序。我担心的是,如果你是在一个“平面”列表上工作,那么这个结构已经被破坏了。这个结构是,而且应该是,一个列表。我的后端了解对象的类型及其继承。问题在于以一种不涉及任何硬编码的简单方式将信息传递给客户机。在PHP中,它只是一个动物数组,每当我需要知道列表中的某个动物是否是哺乳动物时,我都可以对其进行instanceOf测试。@martijnve如果不看到更多的后端结构,我不可能同意你的观点或不同意:)。这就是说,将一个对象展平,同时希望它了解其父类型,这似乎是危险的。您可能必须在数据库中实现一些引用查找表,以将对象类型映射到其父类型。这可能是定义关系的唯一方法,同时仍然具有“平坦”输出。我仍然支持保留继承结构的重构,但我认为两者都可以。啊,我理解。我认为这是最初的迭代,可以说它在转换中丢失了。您可以在对象上粘贴另一个名为“Class”的属性。这将表示父类型。不优雅,但它会工作。