我会尽可能清楚地解释问题。我不确定我的需求是否可能,但我希望必须有一些解决方案。我不能在这里输入实际代码,但会添加解释问题所需的一切。
最初我们有两个不同的类,如下所示。
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
基本上这两个类有共同的方法和功能,但引用不同。
我们接下来决定创建一个工厂模式,以根据一些输入参数获取这些类的对象。
我们当前的代码实现是这样的:
'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
问题是基类引用了Member48,当工厂为Member50生成对象时,对Member48的引用仍然存在。这需要在基类中以某种方式进行纠正。如果需要Member50的对象,则不应该提及Member48。但是,我们如何在没有任何硬编码导入Member48 / 50的情况下定义基类?
有什么办法可以解决这个问题吗?如果需要更多细节,我可以稍后再添加。
感谢。
答案 0 :(得分:0)
问题是两个Members
都没有任何共同的方法。可能有两个具有相同名称的方法,但这些方法具有不同的签名。您既不能将Member48.RequestContext
传递给Member50
,也不能将Member50.RequestContext
传递给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
,你将失去通用实现的任何优势。
另一种方法是尝试统一RequestContexts
和Partners
。如果成员只依赖于普通成员,那么可以通过界面轻松完成。如果没有通用成员,您甚至可以使用空接口(作为所请求类型的提示)并执行以下操作:
MustInherit Class Member
Public MustOverride Function ProcessInfo(reqctx As IRequestContext, memid As String)
'...
End Class
具体的Member
将负责检查正确的类型,并且如果传递了错误的类型,则可能抛出异常。
最后一种方法是不使用任何基类,让工厂返回Object
(或者可能是空基类)。这可能是最干净的解决方案,因为它没有引入任何人工继承。当然,每次访问对象时都必须进行类型检查,但这与大多数其他方法相同。
最后,对你的问题没有一个很好的解决方案。也许你可以修改你的架构,看看是否有更智能的结构,或者你是否真的需要上面列出的Members
。
答案 1 :(得分:0)
为RequestContext
和Partner
创建基类或接口,让Member48.RequestContext
/ Member50.RequestContext
和Member48.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
和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
,而不是IRequestContext
之类的任何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
但是,您的工厂仍然需要 {/ em> Member50
和Member48
的引用,因为它会创建具体的类。
另一种方法是使用像StructureMap这样的DI容器,它能够自动扫描所有实现Member(Of TRequest As IRequestContext, TPartner As IPartner)
的所有类型的程序集,为每个程序集分配一个密钥,并返回正确的例如,例如如果要求提供指定密钥,请Member50
,例如500.但是,这种配置的完整例子将超出这个问题/答案的范围。