层次结构和设计模式问题
我正在为系统建模文档类。文档可以是以下两种类型之一:输入或输出。
如果类型为in,则文档有发件人。发件人可以是以下两种类型之一:个人或公司。
如果类型是out,则文档有接收者。接收者可以是以下三种类型之一:个人、公司、部门。
我不确定使用具有枚举的属性来表示文档类型是否更好,或者使用具有文档基类和每种文档类型的两个类的层次结构是否更好。
对于发送者和接收者,我不确定层次结构是否是一个好的选择,因为这三种类型没有任何共同点(个人、公司、部门)以及如何避免无效的发送者。
如果您能给我一些关于如何建模文档类的建议,或者如果 你可以告诉我一些我应该使用的设计模式。
提前致谢。
in 和 out 之间只有一些区别,除了发送者和接收者之外,其他字段相同。此外,行为是相同的,但有一些变化。
发送者和接收者没有任何行为,他们唯一要做的就是包含正确的对象,例如发送者可以包含个人或公司,但不能包含部门,因为部门不是有效的发送者。此外,如果发件人包含个人,则它不能包含公司,因为只接受一个发件人。
主要问题是当我收到文档并且必须读取该数据时如何读取发送者或接收者。例如,如果我必须读取发件人并且我使用发件人类型的枚举,则我必须执行这样的代码 if sender==person 读取 person 并将其分配给其他人,其他人读取公司并将其分配给公司。如果我使用继承,我如何避免使用强制转换,或者如何知道发送者是没有那么多代码或强制转换的个人或公司。再次感谢。
I'm modeling a document class for a system. The document can be one of two types: in or out.
If the type is in, the document has a sender. The sender can be one of two types: person or company.
If the type is out, the document has a receiver. The receiver can be one of three types: person, company, department.
I'm not sure if it would be better to use a property with an enumeration for the type of document or to use hierarchy with a document base class and two classes for each type of document.
For the sender and receiver I'm not sure if hierarchy would be a good option because the three types don't have anything in common (person, company, department) and how to avoid an invalid sender.
It would be good if you can give me some advice about how to model the document class or if
you can tell me about some design patterns that I should use.
Thanks in advance.
There are only a few differences between in and out, the same fields with the exception of sender and receiver. Also, the behavior is the same with a little changes.
There are no behavior for sender and receiver, the only they have to do is contain the correct object, for example sender can contain a person or a company but no a department because departments are not valid senders. Also, if sender contains a person, it can't contain a company because only one sender is accepted.
The main problem is how to read the sender o receiver when I get the document and I have to read that data. For example, if I have to read the sender and I use a enumeration with the kind of sender I have to do code like this if sender==person read person and assign it to a person else read a company and assign to a company. If I use inheritance how I avoid to use cast or how I know if the sender is a person or company without so much code or cast. Thanks again.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
如果您使用的语言允许对象实现接口,那么这将是处理复杂类型关系的好方法。
ISender 可以由个人和公司实施。 IReceiver 可以由个人、公司和部门来实现。
这样,即使这三种类型没有任何共同点,文档也可以保存对接收者的引用。
对于这两种类型的文档,这在很大程度上取决于它们之间共享多少功能。如果没有,那么建立关系根本没有意义。如果它们共享很多功能,那么可能值得包含一个抽象基类来实现它。如果它们完全(或几乎)相同,那么带有输入/输出标志的单个类可能是一个好主意。
If you are using a language that allows objects to implement interfaces, then that would be a good way to deal with the complex type relationships.
ISender could be implemented by Person and Company. IReceiver could be implemented by Person, Company, and Department.
This way the documents could hold a reference to a receiver, even though the three types don't have anything in common.
For the two types of documents, it depends a lot on how much functionality will be shared between them. If it is none, then there is no point in having a relationship at all. If they share a lot of functionality, then it may be worthwhile to include an abstract base class to implement it. If they are completely (or almost) the same, then a single class with an in/out flag might be a good idea.
就我个人而言,我并不认为将文档类建模为层次结构有什么特别的优势,因为输入和输出文档之间的差异非常小。
特别是考虑到如果
即使它是隐式的,它也有一个接收者(你)。我们的文档也是如此。
因此,据我从您提供的信息中得知,我会使用枚举来区分文档(输入和输出)和类型(个人、公司、部门)。
尽可能遵循接吻原则。
无论如何,您还必须考虑要对文档执行的操作类型以及必须存储的附加数据。
如果您发现输入和输出文档在您的应用程序不断增长时可能会增加它们的差异,那么引入层次结构可能是一个好主意。
(即使在这种情况下,我也会将类型分开,使用一些类似枚举的结构来存储它们)
编辑:
关于您的评论:也许有。我不知道你打算使用哪种语言。但是,例如,对于 Java,每个实体(个人、公司……)都可以是一个实现
接口(例如接口调用实体)。然后使用泛型,您可以实例化您的类,强制泛型类型成为接口实体的实现。
像这样的东西:
Personally I don't see particularly advantages in modelling as a hierarchy the document class, because the are very little differences between in and out documents.
Especially considering that if
Even if it is implicitly it has also a receiver ( you). And the same is for out document.
So, as far as I can know from the information you gave, I'd use enum for distinguish both Document(in and out) and types (person, company, department).
Try to follow kiss principle whenever possible.
Anyway you have also to take in considerations the type of operations you are going to do with the documents and the what additional data the have to store.
If you see that in and out documents could increase their differences while your application will grow, so introduce a hierarchy may be a good idea.
(Even in this case I will keep types separated, using some enum like structure to store them)
EDIT:
Regarding your comment: maybe there are. I don't know which language are you planning to use. But, for example, with Java every entity (person, company..) could be a class implementing
an interface (for example an interface call Entity). Then using generics you can instantiate your class forcing the generic type to be an implementation of interface entity.
Something like:
基本上可以归结为这一点。如果有 if 语句
在多个地方重复,那么最好使用某种多态解决方案(想想抽象类或接口)。发送者和接收者类型也是如此。
但是,您不需要在顶部进行子类化。您可以通过多态性将不同行为附加到单个文档类。假设传入和传出文档的打印行为不同。然后创建 IPrinter 接口并在两个类中实现它,如下所示。
每当决定要传入文档时(可能是在创建文档时),您都可以分配 IncomingPrinter。如果有多种类型的行为需要像这样分配,通常会使用工厂模式。通过这种方式,您可以将 if(doc.IsIncoming()) 语句本地化到一处。不在代码中的不同位置重复决策的好处有很多。
Basically it boils down to this. If there's going to be if statements like
repeated more than a couple of places you'd be better of with some kind of a polymorphic solution (think abstract class or interface). Same thing with the sender and receiver types.
However, you don't need to subclass at the top. You can have a single document class with different behavior attached to it through polymorphism. Assume that printing behavior is different for incoming and outgoing documents. Then you create IPrinter interface and implement it in two classes as follows.
Whenever it is decided that a document is going to be incoming (maybe when it is being created), you assign the IncomingPrinter. If there are multiple types of behavior that needs to be assigned like this usually a factory pattern is used. This way you localize the if(doc.IsIncoming()) statements to one place. Benefits of not repeating a decision at different places in the code is many.
我在这里非常反对等级制度。发送者和接收者显然是具有某些行为并携带某些数据的概念。我将专注于这些职责并创建实体发送者和接收者。稍后,如果需要,可以创建这些的子类,例如 CompanySender。如果您的整个系统与发送者和接收者无关(我认为不是),那么基本上不要用发送者逻辑污染公司实体。
I am quite against hierarchies here. Sender and reciever are clearly concepts that has some behaviour and carries some data. I would focus on these responsibilities and create entities Sender and Reciever. Later, if neccesary make subclasses of these like CompanySender. Basically dont polute Company entity with sender logic if your whole system isnt about senders and recievers (i kind of assume that it is not).
对于输入与输出文档的建模,最佳设计取决于您通常处理文档的方式。
如果您通常在编译时知道文档是否是输入/输出类型,并且除了发送者与接收者之外,还有很多共享属性和行为,那么层次结构会很好(因为您有接受 InDocument 或 InDocument 的方法)或 OutDocument 可能会在编译时解析,甚至运行时解析,具体取决于您的语言)。
另一方面,如果您的文档全部混合在一起并且您主要在运行时处理它们,那么另一个解决方案(我将很快介绍)可能会更干净。我怀疑对于发送者和接收者类型来说,这几乎肯定是正确的,这几乎肯定不保证层次结构(尽管,根据您的语言,您可能需要使用接口标记以便模拟我即将介绍的功能解决方案)。在这些情况下你想要的是一种“带有数据的枚举”。在像 F# 这样的对象函数语言中,您可以结合记录类型和判别式联合来对此进行良好的建模:
For modeling in vs. out documents, the best design is dependent on how you will typically be processing documents.
If you usually know at compile time whether a document is an in / out kind and other than sender vs. receiver there is a lot of shared properties and behavior, then a hierarchy would be nice (since you'd have methods which accept either InDocument or OutDocument which may be resolved at compile time, or even runtime depending on your language).
If on the other hand your documents are all mixed up and you are mostly processing them at runtime, then another solution (which I'll present shortly) may be cleaner. I suspect this is almost certainly true in regards to the sender and receiver kinds, which almost certainly don't warrant a hierarchy (though, depending on your language, you might need to use an interface marker in order to emulate the functional solution I am about to present). What you want in these cases is a kind of "enum with data". In an object-functional language like F#, you can combine record types and discriminant unions to model this well: