处理DDD中的实体序列化



我有一个场景,其中Entity定义了从另一端创建的EntityRepresentationEntityRepresentation是一个值对象,它实现了一些在传输后应该在另一端执行的逻辑。最后,EntityRepresentationEntity包含相同的数据,但在第一种情况下,它被存储为Python基类型(在我的情况下是字符串(,事实上,EntityMapper对象用于在这两种类型之间进行映射,以便存储从EntityRepresentation映射的Entity

换句话说,EntityRepresentation包含与Entity相同的数据,但采用由Entity确定的可序列化格式。由于我试图坚持DDD,我会知道我所做的是否被认为是反模式的。我对这个设计有点怀疑,因为我觉得我只能使用Entity类,并且可以通过在两端使用一个方法来处理表示格式。事实是,该表示不应与Entity道具一起存储,因为它在未来可能会发生更改。

Entity提供一个方法来创建自己的可序列化表示,因为我的域对此施加了约束,这有多正确?

这是一个示例代码:

import json

class Entity:
def __init__(self, id: str, name: str, type: str):
self.id = id
self.name = name
self.type = type

class EntityRepresentation:
def __init__(self, data: str = None):
if data is None:
d = {
"id": "ID",
"name": "NAME",
"type": "TYPE"
}
self.data = json.dumps(d)
else:
self.data = data
def process(self):
# performs ops on self.data
return True

class EntityMapper:
def fromRepr(self, repr: EntityRepresentation) -> Entity:
return json.loads(repr.data, object_hook=lambda r: Entity(**r))
def toRepr(self, ent: Entity) -> EntityRepresentation:
return EntityRepresentation(json.dumps(ent.__dict__))

def main():
mapper = EntityMapper()
# the representation is created on the first end
e_repr = EntityRepresentation()
# serialization
e_repr_json = json.dumps(e_repr.data)
# the json is sent into a wire
# it is then received and deserialized on the other end
e_repr_rec: EntityRepresentation = json.loads(
json.loads(e_repr_json), object_hook=lambda d: EntityRepresentation(json.dumps(d)))
if e_repr_rec.process():
print(mapper.fromRepr(e_repr_rec))
return 0

if __name__ == '__main__':
main()

你的提议在我看来还可以,即使有点过头了。

EntityRepresentation和EntityMapper类几乎不耦合到Entity。所以序列化和反序列化作业可以是Entity方法或原始函数。

import json
from pprint import pprint
from typing import Any

class Entity:
def __init__(self, id: str, name: str, type: str):
self.id = id
self.name = name
self.type = type
def __repr__(self) -> str:
return f"Entity {id(self)} {repr(self.__dict__)}"
@classmethod
def from_dict(cls, data: dict) -> "Entity":
return cls(data["id"], data["name"], data["type"])
def to_dict(self) -> dict:
return {**self.__dict__, "__class__": "Entity"}

class EntityEncoder(json.JSONEncoder):
def default(self, o: Any) -> Any:
if isinstance(o, Entity):
return o.to_dict()
return super().default(o)

def entity_decoder(obj: dict):
if obj.get("__class__") == "Entity":
return Entity.from_dict(obj)
return obj

def main():
# serialization & deserialization
my_json = {
"hello": "world",
"my_entity": Entity("a", "b", "c"),
"a_dict": {"hello": "earth"},
}
encoded = json.dumps(my_json, cls=EntityEncoder)
decoded = json.loads(encoded, object_hook=entity_decoder)
print("ORIGINAL:")
pprint(my_json)
print("SERIALIZED:")
pprint(encoded)
print("DESERIALIZED:")
pprint(decoded)

if __name__ == "__main__":
main()

最新更新