帮助看似两个概念的矛盾 - oop和n层开发

The*_*oot 10 oop n-tier-architecture

不是新手在这里,但仍然从结构化编程过渡.我正在尝试将自包含对象的概念与n层编程协调起来.在我看来,你可以有一个或另一个,但不是两个.

请告诉我这里的n-tier-architecture错误.说我想和一群人一起工作.我使用FN,LN,BDay等在实体层中创建一个'Person'类.我将使用此Person类在我的所有层中表示一个人-UI,Business和DataAccess.但我通常不能将任何有用的方法放入'人'中,因为那时我将越过层边界.

所以我最终创建了一个UiPersonClass,一个BusinessPersonClass和一个DataAccessPersonClass,每个都有一个'Person'类成员.然后我最终为每个层类创建一个构造函数,接受一个'Person'类参数(来自其他层)并将其设置为this.Person.我用this.Person作为参数新建了一个相邻的PersonClass层.等等

这感觉真的错了,但你还应该怎么做呢?

如果我是用一层而已,我可以与填充UI控件的方法,处理信息"人"类,并从数据库中保存和检索数据,都在一个地方,都在一个"对象".

Lil*_*sey 6

我在第一次学习面向对象编程时遇到的一个问题是,用于说明概念的示例是如此基本,以至于没有任何意义.

当有更容易和更简单的方法来编写解决方案时,为什么还要增加一堆看似不必要的复杂性?为什么代码接口似乎没有添加任何东西,只有更多的编程工作和混乱?为什么在我所做的只是将未更改的值传递给链时创建多个图层?

当我开始做更复杂的事情时,很多事情开始变得有意义了.在这里给出的情况下,数据似乎不会随着从一层传递到下一层而改变.因此,拥有多个层似乎没有意义.但是,想象一下更常见的情况,即数据存储在数据库中的方式与UI中显示的方式不匹配.

那么你给出的例子并不那么简单.

我发现以这种方式思考是有帮助的:BusinessLayer在数据库中的数据和UI中的数据之间进行转换.

我通常在数据库中的数据与在DataLayer中创建的对象之间基本上是一对一的对应关系,并且来回传递给BusinessLayer.

传回的数据与从BusinessLayer传递到UI的数据与UI中显示的内容之间基本上是一对一的对应关系.

那些对象通常非常不同.

BusinessLayer是翻译发生的地方.这是从数据库中检索数据以显示在UI中,还是收集在UI中输入的数据并将其存储在数据库中.

当事情开始变得复杂时,事实证明以这种方式做事情要容易得多.特别是在对应用程序进行更改时


sTo*_*rov 5

在我看来,关于在层之间共享Person类的第一个概念是正确的.你可以将它抽象一点,比如添加一个接口IPerson,这样任何代表Person的对象都会实现这个接口.

至于层中的分离,我认为你不应该有一个BusinessPersonClass和一个DataAccessPersonClass.相反,我认为你应该针对以下内容:你的业务层将在IPerson类型上运行:它不关心对象是Person类型还是Salesman类型,它只是知道它需要一个IPerson类型的对象.此外,业务层是所有业务规则(自然地) - 验证等的地方.我认为这些业务规则不应该是Person对象的一部分.事实上,Person对象应该只关注一个人的原子操作和属性 - 换句话说,它不应该包含任何业务或数据访问逻辑.

数据访问层也是如此 - 它在IPerson上运行,返回IPerson(s),修改IPerson(s).数据访问层仅涉及CRUD操作,或者它如何从/向数据源添加,获取,更新,删除IPerson.

现在有了UI,我觉得它有点不同了.通常你会实现你的ViewModel(UIModels)和一些简单的验证规则(不涉及业务逻辑,但输入的有效性).我可以在这里想到两种方法:

1)关于Person的每个UI视图模型都实现了IPerson.通过这种方式,您可以确保层的一致性,并且可以轻松处理这些数据.

2)每个UI视图模型都包含IPerson类型的属性(如上所述).在我看来,这也是一个很好的方法,因为它使UI和业务层之间的通信更容易.

总之,这是我的想法:

UI层 以某种方式引用IPerson.实现基本验证规则 - 输入的有效性(输入的电子邮件确实是电子邮件).然后,UI将此IPerson对象传递给业务层,以用于业务规则和操作.

业务层 获取IPerson对象,使用业务规则对其进行验证(此电子邮件是否已存在于系统中).执行更多业务层操作,可能是,并调用数据访问层,例如,创建实体.在此示例中,业务层将调用Create函数并将其传递给IPerson类型的对象.

数据访问层 对原子实体的CRUD操作 - IPerson,IProduct等.

希望这可以帮助.


min*_*das 5

我认为你的错误是你假设Person应该能够自己做所有事情(知道如何加载自己,如何在屏幕上呈现自己等等).如果你采取这种想法的激进路线,你将最终Person包含屏幕驱动程序(因为它需要知道如何在屏幕上呈现自己!).

由于您已经定义了层(持久性,渲染等),因此您应该考虑这些层的职责.例如,您可以在屏幕上GraphicsSystem接受Person并呈现它.或者PersonDAO负责Person从数据库中检索.或者PersonPrintService知道如何打印,等等.

一般来说,在建模数据对象(例如Person)时,您应该专注于跨层传输的数据而不是功能本身.

你采用的方法(BusinessPersonClass,DataAccessPersonClass等)称为装饰模式.应用它的情况有所不同,但对我来说,这个模式的最好的例子是Java的OutputStream类,它可以被包装BufferedOutputStream然后再包装FileOutputStream,等等.

我不知道什么逻辑BusinessPerson增加了,Person但对我而言,如果有一些人是"商人",你最好做出BusinessPerson 延伸 Person.

我无法进一步发表评论,因为我不知道你的问题所在.