实现派生类接口方法的抽象基类

问题描述:

我有以下类和接口。我想基本上冻结IOld接口(这将被弃用)并强制用户使用INew接口,该接口将包含与IOld相同的方法。然而,INew方法Meth3与IOld Meth2具有相同的功能,但具有不同的返回类型,为了更好地区分它们,我认为这种设计是合适的。我的问题是,这是否被认为是良好的编码习惯?实现派生类接口方法的抽象基类

注意:IOld和INew住在单独的程序集中。 NewClass无法以任何方式引用IOld,因为它将作为客户端将通过INew接口连接到的可远程(MarshalByRef)对象公开。我不希望引用IOld程序集的新客户端。

public interface IOld 
{ 
    void Meth1(); 
    double Meth2(int input); 
} 

public interface INew 
{ 
    void Meth1(); 
    float Meth3(int input); 
} 

public abstract class BaseClass 
{ 
    public virtual void Meth1() 
    { 
    } 

    public virtual double Meth2(int input) 
    { 
     throw new NotImplementedException(); 
    } 
} 

public class OldClass 
: 
    BaseClass, 
    IOld 
{ 
    public override double Meth2(int input) 
    { 
     return 0; 
    } 
} 

public class NewClass 
: 
    BaseClass, 
    INew 
{ 
    public float Meth3(int input) 
    { 
     return 0; 
    } 
} 

我想尝试这样的事:

public class OldClass : BaseClass, IOld 
{ 
    public override double Meth2(int input) 
    { 
     return 0.0; 
    } 
} 

public class NewClass : OldClass, INew // now implements IOld and INew using the Method2() from OldClass 
{ 
    [Obsolete("This method is deprecated . Use Method3() instead.")] 
    public override double Meth2(int input) 
    { 
     return base.Meth2(input); 
    } 
    public float Meth3(int input) 
    { 
     return return 0.0f; 
    } 
} 

它被认为更好的做法是标记为过时,通知他们需要更新其代码的开发人员比通过杀死打破它的方法旧方法。

+0

+1 - 把一个小编辑的*,以及 - SOZ! :-) – 2012-02-23 15:44:37

+0

感谢您的观点;是的,我会将界面标记为已过时,但要指出基本设计;我应该做的一点是NewClass无法以任何方式引用IOld,因为它将作为可远程对象公开,而通过INew接口拾取它的客户端无法引入IOld程序集。我相应地更新了我的问题。 – Jeb 2012-02-23 15:53:02

坐下来,建立一个坚实的基础你的金字塔。你设置的方式,抽象基类和接口是完成相同概念的竞争方法。你这样做主要是为了方便旧版本与新版本,但是当你这样做时,你会得到一个相当时髦的依赖关系图。

用你写的东西,你唯一的问题是具有相同签名的方法。如果不是这个问题,你可以很容易地扩展旧的界面,而不是最终的问题。如果这种方法在新的变化,是一个重构变化(可接受)或完全不同的结果?换句话说,老客户可以叫新的吗?如果是这样,则不需要在不同的接口上使用该方法。

确保您弃用这些方法,以便用户知道他们将丢失旧方法。还要确保它被记录在案。

+0

谢谢你的观点;不,老客户不能拨打新电话。我应该做的一点是NewClass无法以任何方式引用IOld,因为它将作为可远程对象公开,而通过INew接口拾取它的客户端无法引入IOld程序集。 – Jeb 2012-02-23 15:58:33

+0

您是否使用源代码管理?有能力分支?我问,因为这听起来像老客户将继续使用旧的代码,直到代码更新,新的将始终创新。如果这是真的,你分支代码,并保持旧的维护分支和新的当前分支。维护分支仅适用于错误修复。最后一步是确保你已经完成了版本管理,并简单地给出一个客户端版本1的DLL和另一个版本2.唯一的问题是如果一个客户端需要一段时间。如果没有,那么它只是软件改变的一部分。 – 2012-02-23 16:11:59

+0

不幸的是,我们不能要求客户重新编译他们的代码(这将会像往常一样花费他们的代价!),除非是最后的手段,所以我们需要向后兼容IOld。但是,我们不会支持IOld,并且将对INew进行任何错误修复,我们会建议他们重新编译。旧客户端将继续使用旧的接口/新客户端,而不是彼此之间的任何可见性,除了在服务器上,它通过2 apis来处理来自远程客户端的远程调用。 – Jeb 2012-02-23 16:20:16

我宁愿添加一点点不同名称的新方法,而不是创建新界面。

所以旧的接口将是例如:

public interface IOld 
{ 
    void Meth1(); 
    [Obsolete("Use Meth22 instead.")] 
    double Meth2(int input); 
    float Meth22(int input); 
} 
+0

谢谢 - 我在我的问题结尾处添加了一个注释,意思是我没有继续使用IOld接口。 – Jeb 2012-02-23 15:55:39