Oop 如何决定何时提取公共属性?
假设我们有两种类型的请求,InvoiceRequest和QuoteRequest。您希望对象模型(类)和数据库模型是什么样的?以下哪一项更有意义Oop 如何决定何时提取公共属性?,oop,design-patterns,database-design,database-schema,software-design,Oop,Design Patterns,Database Design,Database Schema,Software Design,假设我们有两种类型的请求,InvoiceRequest和QuoteRequest。您希望对象模型(类)和数据库模型是什么样的?以下哪一项更有意义 InvoiceRequest: - id - amount - discount - date - invoiceSpecificFieldHere QuoteRequest: - id - amount - discount - date - quoteSpecificFieldHere. 还是这一条更有意义 Reques
InvoiceRequest:
- id
- amount
- discount
- date
- invoiceSpecificFieldHere
QuoteRequest:
- id
- amount
- discount
- date
- quoteSpecificFieldHere.
还是这一条更有意义
RequestData:
- amount
- discount
- date
InvoiceRequest:
- id
- requestData: <RequestData>
- invoiceSpecificProperty
QuoteRequest:
- id
- requestData: <RequestData>
- quoteSpecificProperty.
RequestData:
-数量
-折扣
-日期
发票申请:
-身份证
-请求数据:
-发票专用属性
报价要求:
-身份证
-请求数据:
-quoteSpecificProperty。
我并不是故意使用继承来表示第三个选项
这个问题背后的问题是:;如果我们使用design 2,我们可以减少冗余,但是它有一些地方感觉不对劲。我认为折扣应该与quoteSpecificProperty处于同一水平。把它放在requestData对象中并不能正确地建模。第二种方法更有意义,因为当你设计你的对象和它们所拥有的字段时,你正在对真实的单词进行抽象,它是如何看待的,以及其中有什么行为。你在这里处理一个叫做
数据库规范化或简单的规范化是组织关系数据库的列(属性)和表(关系)以减少数据冗余和提高数据完整性的过程。
这种关系并不总是与世界上的现实完美匹配,但你必须从现实世界中抽象出来,并将数据视为相互关联的数据。我将与你分享我本周收集的一些信息 也许坚实的原则会帮助你做出决定
SOLID =(Single responsibility principle,Open/closed principle,
Liskov substitution principle,Interface segregation principle,
Dependency inversion principle or Dependency injection principle.
好吧,这不仅仅是属性抽象。让我们看一些例子:
S
根据维基百科,单一责任原则意味着
- 一个类别只有一个理由可以改变其 实施李>
- 类对其他类的依赖性应很少李>
- 类应是从其运行的特定层抽象出来的
They shall be open for extension;
But closed for modification.
关于修改,请想一想,在您有义务这样做的bug情况下,第二个模型中的修改对于公共字段来说是最容易的
第一个模型
第二个模型公共字段
QuoteRequest:
-身份证
-请求数据:
-quoteSpecificProperty。
L
根据“Barbara Liskovs替换原理”,如果TChild
是TParent
的一个子类型,则TParent
类型的对象可以替换为TChild
类型的对象,而不改变该程序的任何期望属性(正确性、执行的任务等)。
我的意思是,TParent
的对象
,TParent
的实例,而不是TParent
类
当您想要使用接口实现这个示例时,这是一个值得思考的有趣话题。还包括:
I
界面分离原理
D
依赖倒置原理
另一种形式的解耦是反转软件设计的高级别和低级别之间的依赖关系:
-高级模块不应依赖于低级模块。二者都
应该依靠抽象;
-抽象不应该依赖于细节。细节应视情况而定
基于抽象
要了解更多有关固体原理的信息,请阅读
在resume中,观察对象模型的三个特征:
- 僵化——很难改变某些东西,因为每一次改变都会影响到你 系统的许多其他部分李>
- 脆弱性——当你做出改变时,系统中意外的部分 中断李>
- 不可移动–很难在另一个应用程序中重用,因为它不能 从当前应用程序中分离
特别感谢A.Bouchez,source我的印象是,您将面向对象建模和关系数据建模的概念混合在一起。这是因为从关系数据建模的角度来看,您的第二个解决方案是不正确的 由于我不知道您在模型实现方面的确切需求,我将尝试针对不同的情况提出解决方案 如果您想使用纯面向对象模型,并用面向对象语言实现,那么显然应该定义一个超类请求,其中包含两个子类InvoiceRequest和QuoteRequest,它们都具有特定的属性 如果您想在纯关系模型中使用关系数据库实现您的情况,您应该定义三个表:
Requests:
- id (Primary Key)
- amount
- discount
- date
InvoiceRequests:
- id (Primary Key) (Foreign Key for Requests)
- invoiceSpecificProperty
QuoteRequests:
- id (Primary Key) (Foreign Key for Requests)
- quoteSpecificProperty.
最后,如果您想使用对象关系映射,您应该设计一个超类请求,其中包含两个子类InvoiceRequest和QuoteRequest,它们都具有特定的属性,然后您可以将其映射到一个关系数据库中,并使用类似于前一个模型的模型
当然,在关系建模中还有另一种可能性,即拥有一个具有所有属性的表请求,包括quote-specific和invoice-specific,以及一个用于区分哪种请求是当前请求的属性。invoice和quote是两个完全不同的东西,即使它们看起来相似。最好将它们分开,因为对其中一个的更改可能会对另一个产生不必要的副作用。谢谢您的回答,有两种抽象:对象模型和数据库模式。数据库模式不必与对象模型相同。但是,即使我们关注数据库模式,我仍然认为在这种情况下规范化是没有意义的。冗余在这种情况下,我们仍然需要为每个TaxRequest创建一个新的RequestData行,基本上我们创建的是一对一的关系。我认为数据完整性也是一样的,因为每一行RequestData都将
QuoteRequest:
- id
- requestData: <RequestData>
- quoteSpecificProperty.
Requests:
- id (Primary Key)
- amount
- discount
- date
InvoiceRequests:
- id (Primary Key) (Foreign Key for Requests)
- invoiceSpecificProperty
QuoteRequests:
- id (Primary Key) (Foreign Key for Requests)
- quoteSpecificProperty.