2012-10-31 48 views
0

我有一个真正做作的例子,就是我的业务对象如何加载它们的数据。不过,我想阻止下面显示的情况。我知道这里有缺点,但它是如何(到目前为止)!我如何在不重构接口等的情况下实现这一目标?防止将继承的对象传递给共享函数

Public Class Car 

    Public Property Passengers As Integer 

    Public Shared Sub Fill(c As Car, r As SqlDataReader) 
    Passengers = r.GetInt32(0) 
    End Sub 

End Class 

Public Class UsedCar 
    Inherits Car 

    Public Property PreviousOwner As String 

    Public Shared Sub FillUsed(l As Limo, r As SqlDataReader) 
    Passengers = r.GetInt32(0) 
    PreviousOwner = r.GetString(1) 
    End Sub 

End Class 

Public Sub CreateVehicles() 

    Dim c As New Car() 
    Car.FillWithStuff(c, GetSqlReader(carId)) 

    Dim l As New UsedCar() 
    UsedCar.FillUsed(l, GetSqlReader(usedCarId)) 'Great 
    Car.Fill(l, GetSqlReader(usedCarId)) 'No! << Stop this at once! 
    UsedCar.Fill(l, GetSqlReader(usedCarId)) '<<< Even more wrong! 

End Sub 
+0

而'Limo.FillWithStuff'更糟...... – Tom

+0

我有种感觉你是对的。该死的Liskov和他的校长!也许我的蛮力方法不是最大的,所以构图看起来像是目前最好的选择...... – Tom

回答

1

有没有办法要求,除了抛出异常。例如:

Public Shared Sub FillWithStuff(c As Car) 
    If Not (TypeOf c Is Car) Then 
     Throw New Exception("Must be a Car") 
    End If 
    Passengers = 4 
End Sub 

但是,您提供的简单的例子并不能充分解释为什么,在你的情况,一辆豪华轿车是不是一个有效的车。如果实际上它不是一辆有效的汽车,那它就不应该继承汽车。很可能您的代码应该被重构,以便汽车和豪华轿车是两个不相关的类,它们共享相同的依赖性业务类以实现通用功能。

+0

对不起,这不是最好的例子tbh。有问题的实际方法会从SqlDataReader中填充对象。事实上,“豪华轿车”将等同于二手车,因此它将具有“原始所有者”财产。也许我应该改变我的例子... – Tom

+0

同意,需要重构。目前,我依靠传统...... – Tom

1

使构造函数为私有,并让您的各种Fill()方法实例化并返回一个全新的对象,或者您可以将Fill()代码移入构造函数本身。由于您的方法与数据库结果非常紧密相关,因此另一种选择是将构造函数标记为“朋友”,并将您的Fill()方法移至与数据层一起使用的单独模块。

的这里的目标是建立一个汽车唯一方法是使用一个定义的工厂方法是在一个位置,在编译时,适当的类型匹配起来检查