【问题标题】:Two classes, same methods, one object?两个类,相同的方法,一个对象?
【发布时间】:2014-04-02 17:22:24
【问题描述】:

我正在开发一个使用 Oracle 的“Siebel CRM”产品的 C# 项目。 Siebel 提供了两个名称空间和类,用于以编程方式连接到它的服务,具体取决于您是要连接到服务器还是连接到客户端会话:

SiebelBusObjectInterfaces.SiebelDataControl
TWSiebelLib.SiebelWebApplication

SiebelDataControl 公开了一种用于显式登录到基于服务器的资源的特定方法:

bool SiebelDataControl.Login(string connString, string userName, string passWord)

这两个类之间的所有其他方法都是相同的..

我目前正在维护我的应用程序的两个版本 - 一个用于每个不同的连接类。随着我构建的功能变得越来越具有包容性和复杂性,单独维护两个应用程序变得非常困难。我已将连接部分拆分为它自己的类,但在开发过程中我仍然需要在应用程序之间复制和粘贴代码。

理想情况下,我想要一个单一的 VS 解决方案,其中包含我的所有自定义代码的一个实例和一些确定要使用两个连接类中的哪一个的逻辑,由用户决定。

理论上,我想要这样的东西:

class SiebelAppWrapper {

    public Object m_SiebelAppInstance;
    private Boolean m_isConnected;
    private short m_conType;

    public static short SERVER_CON = 1;
    public static short CLIENT_CON = 2;

    public SiebelAppWrapper(short conType) {
        if (conType == SERVER_CON) {
            m_SiebelAppInstance = new SiebelDataControl();
          } else if conType == CLIENT_CON {
            m_SiebelAppInstance = new SiebelWebApplication();
        } 
        m_conType = conType;
    }
}

但是,出于显而易见的原因,编译器对此并不满意。

总的来说,我对 C# 和 .NET 开发还很陌生,所以我希望有一些方法可以让我在不复制所有依赖代码的情况下合并这两个类。

非常感谢您的任何帮助。

【问题讨论】:

  • 我不太了解,无法提交答案,但如果您使用的是 Visual C# 2010,您能否将 m_SiebelAppInstance 的类型设置为 dynamic?如msdn.microsoft.com/en-us/library/dd264736.aspx
  • @DanielRenshaw:您的建议在技术上没有任何问题,但我真的希望dynamic 不是所有问题的解决方案,jQuery-magic-dust-that -makes-problems-go-away 风格。看起来它可以解决问题,但您必须了解您要注册的内容。
  • @Jon 我在一定程度上同意。鉴于我们所知道的,我个人更喜欢您的解决方案,但我们并不了解 OP 案例的所有内容,它不一定是所有情况下的最佳解决方案。如果dynamic 可以工作,那么值得指出它是一种可能的解决方案,供那些从中受益最多的人使用。
  • @DanielRenshaw:当然,没有争论。我的观点是,在dynamic 中进行交换实际上是一个单词的更改,它神奇地使事情变得正常。人性就是这样,人们会这样做,继续前进,然后想知道为什么他们的程序在运行时会中断。更糟糕的是,“make it dynamic”策略的明显成功将导致 jQuery 效应:对于某些事情可能有一个很好且简单的经典解决方案,但是,嘿,动态的作品,所以谁在乎呢。
  • @All:是的,我知道“动态”如何提供帮助:我刚刚尝试过,它确实让我可以做我想做的事。正如其他人所指出的那样,我还可以看到它如何导致问题发生。非常感谢您的所有意见,因为这不仅有助于解决我的问题,还有助于我在学习 C# 的道路上遇到其他障碍时学习最佳实践方法。

标签: c#


【解决方案1】:

根据您的描述听起来一个可行的选择是:

  1. 创建一个接口ISiebelWhatever,描述您将要使用的两个类之间的所有通用功能。
  2. 派生两种类型,一种来自每个源类,并使这些新类型实现ISiebelWhatever
  3. 使用ISiebelWhatever 作为m_SiebelAppInstance 的类型。

当然,这仅在源类不是sealed 时才有效,并且对于签名不相同的方法无济于事。此外,通用接口方法有些明显,这就提出了一个问题:源库是否有可能已经这样做了?或者也许这两个类有一个共同的基础?你应该先检查一下。

如果有两个类之间没有共享但您需要使用的方法,您还必须决定一个共同的签名(在ISiebelWhatever 中声明)并通过适当的转发让您的两个子类实现它到他们现有的非共享方法。

【讨论】:

  • 如果这些对象在任何时候都没有传递到 Siebel API,那么即使类是密封的,也可以这样做。只需为每种类型创建一个包装器,其中每个类型都有一个封装的真实对象实例,并将所有接口方法委托给封装的实例。
  • @Jon:谢谢你。这听起来正是我想要实现的目标。我正在尝试在业余时间学习 C#,因此需要先将接口作为我的下一个研究主题,然后才能真正尝试。
  • 简单说明一下,Oracle 确实已经提供了一个接口 - ISiebelCommonApp。太棒了,谢谢大家的帮助。
【解决方案2】:

如果您有很多共同的方法,为什么不使用继承或接口?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-10-27
    • 1970-01-01
    • 2013-09-13
    • 2017-11-05
    • 2011-01-30
    • 1970-01-01
    • 2013-01-21
    • 2021-03-05
    相关资源
    最近更新 更多