【问题标题】:Prevent Massive Shadowing Of Methods [closed]防止方法的大规模阴影[关闭]
【发布时间】:2011-01-23 13:02:20
【问题描述】:

我在一个项目中,几乎是我第一次自己做所有的架构,我遇到了一个令人沮丧的情况。从启发式的角度来看,我的表单架构似乎是正确的,但我认为它的实现并不正确。

我的架构是这样的:

基类:OrderForm

儿童班:PurchaseOrderInvoiceCredit

PurchaseOrder 的子类:StockingOrder

从架构上讲(对我而言)这是有道理的,因为所有子类都是 OrderForms(“is a”),而 Stocking Order“是”采购订单,只是一种特殊的类型。

问题

在编写我的 StockingOrder 类时,我注意到我必须 Shadow 使用 PurchaseOrder 中的大部分(如果不是全部)方法,因为它们在概念上做同样的事情但需要略有不同实现功能。当然,这对我来说很臭,但我不知道如何解决它。我究竟做错了什么?或者这是正常的吗?(!)

谢谢...

【问题讨论】:

  • 您能否更具体地了解“略有不同的实现”?也许继承结构还不错,可能是需要解耦或重构的问题。
  • 例如,如果我有一个名为GetForms() 的方法,我需要它从数据库中获取正确的表单,即获取 StockingOrders 而不是 PurchaseOrders。两者都获取表单(并从技术上获取 PurchaseOrders)但数据库不知道...
  • 我建议您查看Strategy Pattern。这将允许您为每个订单类型提供您正在执行的方法的“剧本”。这将帮助您简化逻辑中的差异。

标签: asp.net vb.net inheritance architecture


【解决方案1】:

听起来您可能需要在 PurchaseOrder 中使用一些虚拟方法。可能类似于以下内容:

public abstract class OrderForm
{
    //orderform members
}

public class PurchaseOrder: OrderForm
{
    public void DoSomething()
    {
        //some logic that can be reused by child classes
        DoSomethingElse();
    }

    protected virtual void DoSomethingElse()
    {
        //specialized logic
    }
}

public class StockingOrder: PurchaseOrder
{
    protected override void DoSomethingElse()
    {
        //specialized logic that makes StockingOrder different than PurchaseOrder
    }
}

这应该有助于重用更多代码,因为您可以将在 PurchaseOrder DoSomethingMethod 中编写的类似逻辑分组,同时将专用逻辑(在 PurchaseOrder 和 StockingOrder 之间不同)保留在虚拟 DoSomethingElse 方法中。

【讨论】:

  • 我刚刚看到您标记了您的问题 VB.NET。希望这仍然可以提供帮助。
  • 我也懂 C#,所以这很好。我明白你在做什么,但这也是一种气味,不是吗?也许我真的不知道什么是气味,什么不是?
  • 谢谢你,(我相信)这就是我需要的! :)
  • 另外:感谢您向我展示了正确(并且可以说是更好)的方式来看待可重用方法的创建!这让事情变得更容易:)
  • 另外:您对这些“专业逻辑”方法有某种命名约定吗?例如,如果我有一个名为FillForm() 的方法,你会怎么称呼一个在该方法中调用了一些特殊逻辑的方法?谢谢!
【解决方案2】:

正如 mdearing06 建议的那样,您应该使用虚拟方法(或只是可覆盖的方法)并覆盖它们。 使用 Shadowing 更改您自己代码的功能在某种程度上是一种不好的做法。阴影用于不常见的场景,即:当您从其他人编写的类继承并且您必须更改其某些功能,但无法查看/编辑代码本身时。

考虑一个事实,Shadowing 很像 Overloading(只是它隐藏了基本实现),并且与 Overriding 完全不同。 仅当您通过其类显式引用对象时才会调用遮蔽方法;否则,将调用原始方法(与覆盖不同,该方法是基于被引用对象的 content - 而不是 representation - 调用的)。

以下是表示如何影响阴影方法调用的示例:

Class BaseClass
    Public Sub MyMethod()
        Trace.WriteLine("The original method")
    End Sub
End Class
Class ShadowClass
    Inherits BaseClass
    Shadows Sub MyMethod()
        Trace.WriteLine("The shadowing method")
    End Sub
End Class
Class Tester
    Public Shared Sub TestClasses()
        Dim myObj As Object = New ShadowClass
        Dim var0 As BaseClass = myObj
        var0.MyMethod()
        Dim var1 As ShadowClass = myObj
        var1.MyMethod()
    End Sub
End Class

运行 Tester.TestClasses 后,trace 将显示:“原始方法”,然后是“阴影方法”。

现在,如果我们改用以下代码:

Class BaseClass
    Public Overridable Sub MyMethod()
        Trace.WriteLine("The original method")
    End Sub
End Class
Class OverridingClass
    Inherits BaseClass
    Overrides Sub MyMethod()
        Trace.WriteLine("The overriding method")
    End Sub
End Class
Class Tester
    Public Shared Sub TestClasses()
        Dim myObj As Object = New OverridingClass
        Dim var0 As BaseClass = myObj
        var0.MyMethod()
        Dim var1 As OverridingClass = myObj
        var1.MyMethod()
    End Sub
End Class

跟踪输出将显示“覆盖方法”,然后显示“覆盖方法”。

总而言之,我想说覆盖是“正常”的方式,而阴影是一种异常情况。

【讨论】:

  • 我明白你在说什么,但我不知道我会遇到你上面描述的场景......我的问题基本上是,当你继承一个类时,你会花很多时间覆盖这些方法?那不是违背了传承的目的吗?我的意思是一些(希望是大多数)东西可以重用,但总会有很多(如果不是全部)方法需要重写,因为你的专用对象由于细微的差异而无法在功能上执行其父对象的功能......对吧..?
  • @Jason,功能应该被分成更小的块,只有行为不同的部分应该被覆盖。如果这个划分正确,覆盖方法应该简单明了,不应该让你更努力,而是更容易!如果整个实现不同,则应使用接口或抽象类。在某种程度上,我认为您将 OOD 的力量与弱点混淆了。此讨论超出了 SO 问题的范围,应在可以分析和评论您的特定场景的论坛上继续讨论。
【解决方案3】:

另一种选择是使用接口;设置代码契约,允许您对定义的接口进行编程,而不必担心底层的实现。

这还允许您定义多个专注于特定任务的接口,这使您的代码更易于维护和灵活。

然后,对于常用方法,将它们放在您的实现可以利用的帮助器类中。

查看这些以获取更多参考:)

http://www.developer.com/lang/other/article.php/939411/Implementing-Interfaces-in-VB-NET.htm

http://blogs.msdn.com/trobbins/archive/2004/08/26/221241.aspx

【讨论】:

  • 感谢您的链接...尽管StockingOrder 继承了PurchaseOrder,但接口并不能解决问题,这将实现任何接口。我仍然必须覆盖/隐藏声明的方法:\对吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-20
  • 2013-02-20
  • 1970-01-01
相关资源
最近更新 更多