1

I will try to explain the problem as clearly as possible. I am not sure if what I need is possible but expect that there must be some solution to this. I wont be able to put in actual code here but will add whatever is needed to explain the problem.

Initially we had two separate classes as defined below.

Imports QMember48

Public Class Member48

 Public Function ProcessInfo(reqctx as Member48.RequestContext, memid as String)
 'Code here
 End Function

 Public Function UpdateInfo(partner as Member48.Partner, memid as String)
 'Code here
 End Function

 'Other methods and functions come here

End Class

Imports QMember50

Public Class Member50

 Public Function ProcessInfo(reqctx as Member50.RequestContext, memid as String)
 'Code here
 End Function

 Public Function UpdateInfo(partner as Member50.Partner, memid as String)
 'Code here
 End Function

 'Other methods and functions come here

End Class

Basically these two classes have common methods and functions but the references are different.

We next decided to create a factory pattern to get the objects of these classes based on some input parameter.

Our current implementation of code is like this:

'Base class definition
Imports QMember48

Public MustInherit Class Member
 Public MustOverride Function ProcessInfo(reqctx as Member48.RequestContext, memid as String)
 Public MustOverride Function UpdateInfo(partner as Member48.Partner, memid as String)
End Class

'Factory
Public Module MemFactory

 Function GetMember(val as string) as Member
  'Do some processing here
  If val = "500" return new Member50() else return new Member48()
 End Function

End Module

The problem is that the base class refers to Member48 and when the factory generates an object for Member50, the reference to Member48 still remains. This needs to be corrected somehow in the base class. If an object of Member50 is needed, there should not be any reference to Member48. But again how do we define the base class without any hardcoded import of Member48/50 ?

Is there any way to resolve this issue? If more details are needed, I can add later.

Thanks.

4

2 回答 2

0

RequestContext为and创建一个基类或接口Partner,并让Member48.RequestContext/Member50.RequestContextMember48.Partner/Member50.Partner实现这些接口:

Public Interface IRequestContext
End Interface

Public Interface IPartner
End Interface

Class Member48RequestContext
    Implements IRequestContext
End Class

Class Member48Partner
    Implements IPartner
End Class

Class Member50RequestContext
    Implements IRequestContext
End Class

Class Member50Partner
    Implements IPartner
End Class

IRequestContest现在您可以创建一个接受 an和 an的基类IPartner

Public MustInherit Class Member
    Public MustOverride Function ProcessInfo(reqctx as IRequestContext, memid as String)
    Public MustOverride Function UpdateInfo(partner as IPartner, memid as String)
End Class

你的具体成员类的实现看起来像

Public Class Member50
    Inherits Member

    Public Overrides Function ProcessInfo(reqctx as IRequestContext, memid as String)
    End Function

    Public Overrides Function UpdateInfo(partner as IPartner, memid as String)
    End Function

End Class

如果需要,还可以使用泛型创建另一个子类:

Public MustInherit Class Member(Of TRequest As IRequestContext, TPartner As IPartner) 
    Inherits Member

    Public Overrides Function ProcessInfo(reqctx as IRequestContext, memid as String)
        Return ProcessInfo(DirectCast(reqctx, TRequest), memid)
    End Function

    Public Overrides Function UpdateInfo(partner as IPartner, memid as String)
        Return UpdateInfo(DirectCast(partner, TPartner), memid)
    End Function

    Public Overloads MustOverride Function ProcessInfo(reqctx as TRequest, memid as String)
    Public Overloads MustOverride Function UpdateInfo(partner as TPartner, memid as String)
End Class

和一个实现:

Public Class Member48
    Inherits Member(Of Member48RequestContext, Member48Partner) 

    Public Overrides Function ProcessInfo(reqctx as Member48RequestContext, memid as String)
    End Function

    Public Overrides Function UpdateInfo(partner as Member48Partner, memid as String)
    End Function

End Class

请注意如何Member48只接受一个Member48RequestContext,而不是任何IRequestContextlike Member50。如果您想要这种额外的安全性,这取决于您。

您的工厂方法保持不变:

Function GetMember(val as string) as Member
    'Do some processing here
    If val = "500" Then
        Return New Member50()
    Else 
        Return New Member48()
    End If      
End Function

但是,您的工厂仍然需要同时 Member50引用and Member48,因为它创建了具体的类。

另一种方法是使用像StructureMap这样的 DI 容器,它能够自动扫描所有程序集以查找所有实现的类型,为每个类型Member(Of TRequest As IRequestContext, TPartner As IPartner)分配一个键,并返回正确的实例,例如,Member50如果要求指定键,例如 500 .但是这种配置的完整示例将超出此问题/答案的范围。

于 2013-09-10T08:55:23.333 回答
0

问题是两者Members都没有任何共同的方法。可能有两个具有相同名称的方法,但这些方法具有不同的签名。您既不能将 a 传递Member48.RequestContext给 a Member50,也不能将 a 传递Member50.RequestContext给 a Member48。这就是为什么不能在这里合理地应用继承。两个成员的公共基类将为空。

您可以使用通用基类,如下所示:

MustInherit Class Member(Of TRequest, TPartner)
    Public MustOverride Function ProcessInfo(reqctx As TRequest, memid As String)
    Public MustOverride Function UpdateInfo(partner As TPartner, memid As String)
End Class

Class Member48
    Inherits Member(Of QMember48.RequestContext, QMember48.Partner)
    '...
End Class

Class Member50
    Inherits Member(Of QMember50.RequestContext, QMember50.Partner)
    '...
End Class

然而,这个基类并没有给你任何工厂的优势。工厂将不得不返回一个无类型的Member,你将失去通用实现的任何优势。

另一种方法是尝试统一RequestContextsPartners。如果成员只依赖普通成员,这可以很容易地通过一个接口来完成。如果没有公共成员,您甚至可以使用空接口(作为请求类型的提示)并执行以下操作:

MustInherit Class Member
    Public MustOverride Function ProcessInfo(reqctx As IRequestContext, memid As String)
    '...
End Class

具体Member将负责检查正确的类型,如果传递了错误的类型,可能会抛出异常。

最后一种方法是不使用任何基类,让工厂返回一个Object(或者可能是一个空的基类)。这可能是最干净的解决方案,因为它不会在没有的地方引入任何人工继承。当然,每次访问对象时都必须进行类型检查,但这与大多数其他方法相同。

最后,对于您的问题,没有一个很好的解决方案。也许你可以修改你的架构,看看是否有更智能的结构,或者你是否真的需要Members上面列出的。

于 2013-09-10T08:54:10.997 回答