2010-10-21 70 views
1

我有一个函数可以返回给定期间的订单。我创建了一个Period对象,可以确保在指定日期范围时,开始日期为< =到结束日期。同样,如果处理一个月的时间段,则该时间段的开始日期和结束日期应分别为该月的第一天和最后一天。OOP/OOD耦合问题

我的问题是这样的:

我认为,在面向对象的设计原则,联轴器是坏的。我是否通过让Order类在其方法之一中使用Period类作为参数来引入Order和Period类之间的耦合?

我的猜测是肯定的,但这样做的好处是,即一旦定义了对象,就不必每次将句点作为参数传递给不同的方法时都执行相同的参数验证检查Orders类。

此外,Microsoft是否不经常将一种类型的非内在对象传递给其他对象?
避免耦合听起来像避免重复使用我,这是面向对象应该促进。这听起来像是相互竞争的目标。

有人可以澄清。

Public Class Order 

    Public Shared Function GetOrders(ByVal customerId As Integer, 
            ByVal forPeriod As Period) As Orders 

     **'Should the param object MonthPeriod be replaced with 2 date params? 
     'Would I be "reducing coupling" by doing so, a good thing.** 

    End Function 

End Class 

Public Class Period 

    Property FromDate As Date 
    Property ToDate As Date 

    Public Sub New(ByVal fromDate As Date, ByVal toDate As Date) 

     If fromDate > ToDate Then 
      Throw New ArgumentException("fromDate must be less than Or equal toDate") 
     End If 

     _FromDate = fromDate 
     _ToDate = toDate 

    End Sub 

End Class 

Public Class MonthPeriod : Inherits Period 


    Public Sub New(ByVal fromDate As Date, ByVal toDate As Date) 

     MyBase.New(fromdate, toDate) 

     If fromDate.Date <> New Date(fromDate.Year, fromDate.Month, 1) Then 
      Throw New ArgumentException("fromDate must be the first day of the month") 
     End If 

     If toDate.Date <> New Date(toDate.Year, toDate.Month, Date.DaysInMonth(toDate.Year, toDate.Month)) Then 
      Throw New ArgumentException("fromDate must be the last day of the month") 
     End If 

    End Sub 

End Class 

回答

1

.Net中的所有东西都是一个对象,然而对象很少存在于隔离中,因此会存在一定程度的耦合班是。你需要问的问题是紧密耦合,有些耦合或松散耦合的类。紧密耦合的类会形成一个脆弱的架构,因为这些变化可能会在整个模型或系统中产生连锁反应。随着时间的推移,课程的维护会变得越来越困难。让你的课程更松散耦合倾向于缓解其中的一些问题。在东西是否是松耦合还是没有(从here)方面:

耦合是指 直接知识一类具有 另一个程度。这并不意味着将 解释为封装而对 解释为非封装。它不是一个 引用一个类的知识 另一个类的属性或 的实现,而是知识 其他类本身。强 当依赖类 包含直接指向提供 所需行为的 具体类的指针时发生耦合。依赖关系 无法替换,或者其 “签名”已更改,无需对相关类进行更改 。松散 当依赖的 类包含仅指向 接口的指针时,会发生耦合,然后该接口可能由 类实现,该类由一个或多个具体的 类实现。

在你的例子中,你介绍了Order类和Period类之间的一些耦合。您可能需要将两个相关日期传递给Order方法,并且您选择创建一个Period类来完成此操作。为什么?因为你有两个日期;从日期到现在;并且您想验证您的代码中的一个且仅有一个点的到期日期晚于。这是DRY principle的应用;这是一件好事。的DRY原则的应用,而相关的,从代码复用(从here)不同:

一些特性,这使得 软件更容易重复使用的是 模块化,松耦合,高 凝聚力,信息隐藏和 关注点分离。

松耦合只是使代码重用的几个特征之一。代码重用在某种程度上可以让你在你的代码的其他地方使用Period类,而不仅仅是Order类。如果您要添加一个接口来抽象使用Period类,那么这会让您的Order类和Period类更加松散地耦合,但这不会消除代码重用的能力(您可以在别处使用Period类在你的代码中)。

+0

优秀的答案。谢谢 – ChadD 2010-10-22 02:08:47

+0

Definetly同意...优秀的答案。谢谢(我多次阅读这些内容,但是当你看到如此精细的评论时(为什么/何时/细节),那么在你的代码中应该选择哪种方式。谢谢史蒂夫。 – ramnz 2012-11-20 17:03:55

1

松耦合和重用确实是竞争的概念。在设计软件时,你必须不断平衡两者的使用。

+0

好的,根据你的回答,我想我理解了这些概念。 – ChadD 2010-10-21 19:59:00

1

系统中的服务(如GetOrders)可以依赖小而易于创建的Value对象(如Period)。这可以让您的服务对象根据您所在的域进行交谈,而不是始终使用基本类型。

因此,我想说在这种情况下将Period传入GetOrders是正确的。它提高了抽象级别。 GetOrders对所有Period类感兴趣,所以你不会不必要地限制GetOrders知道的概念范围(它只是以不同的形式)。如果Period是一个包含一堆其他东西的更大的类,那么耦合将是一个更大的问题。

第二个因素,使得这个好,是创建一个Period对象很容易。如果它需要你创建一系列其他对象,那么耦合将是一个问题。这就是为什么你没有你的价值对象发送电子邮件并将自己保存到数据库等。

1

应该避免不必要的耦合,但在你的场景中,Period只是用来定义一个值类型,它聚集了一些关于你的域的概念,所以它一点都不差。如果它超出了数值类型的使用范围,则需要使用像依赖注入(DI)和控制反转(IoC)这样的技术来解耦它们。

就测量设计而言,涉及到依赖关系时,您必须超越类级别,但更多的是在名称空间或程序集级别。就你而言,如果Period存在于相同的命名空间或程序集中,那么你的包中的类型之间仍然有很好的关系凝聚力。在上面的场景中,您的命名空间的传出和传入耦合仍然保持不变/较低。