设计可互换使用的轻量和完整的对象

本文关键字:对象 可互换 | 更新日期: 2023-09-27 18:12:40

我在一个使用类似于这样的接口和类结构的系统中工作:

interface ILw                // a lightweight interface definition
class Medium : ILw
class FullA : Medium         // full class definitions
class FullB : Medium
class LwA : ILw              // lightweight class definitions
class LwB : ILw
在系统中,我遇到的对象可能是完整的或轻量级的,因此具有期望使用ILw接口的功能。我在这种设计中遇到的问题是,需要在对象的完整版本和轻量级版本之间共享的数据和方法比ILw中定义的要多。所以我发现自己需要做这样的事情:
if (myvar is FullA)
{
   (myvar as FullA).MyFunction()
} 
else
{
   (myvar as LwA).MyFunction()
}

其中MyFunction()在每个FullALwA中分别实现,并且可以在相同的数据结构上工作。我想要消除这些代码重复。

在我的c++背景下,这似乎是一个典型的多重继承案例;也就是说,为需要的数据和方法定义一个类SharedA,并将其添加到FullALwA的父列表中。但是我需要一些指导来帮助我在c#和接口的世界中思考这个问题。是否有一个公认的模式来解决这个问题?

谢谢。

更新:

在到目前为止收到的评论的帮助下,我已经能够重构一个更好的设计:1)一个需要聚合共享数据的中间接口;2)一个用于处理这些数据的方法的扩展类。理想情况下,这些(数据和方法)将被连接到同一个构造中。我觉得我的伴侣在董事会上,我只是没有看到它。
public interface ILwBase { }
class Medium : ILwBase { }
public class LwDataA
{
    static private int _count = 0;
    public int id;
    public LwDataA() { id = ++_count; }
}
public interface ILwA : ILwBase 
{
   LwDataA ExtData { get; }
}
public static class ExtLwA
{
   public static void MyFunction(this ILwA o) 
   {
      Console.WriteLine("id = " + o.ExtData.id); 
   }
}
class LwA : ILwA
{
   private LwDataA _extData = new LwDataA();
   public LwDataA ExtData { get { return (_extData); } }
}
class FullA : Medium, ILwA
{
   private LwDataA _extData = new LwDataA();
   public LwDataA ExtData { get { return (_extData); } }
}
class Program
{
   static void Main()
   {
      ILwA a1 = new FullA();
      ILwA a2 = new LwA();
      a1.MyFunction();
      a2.MyFunction();
   }
}

这允许我只需要两行重复的代码之间的LwA和FullA。并且它消除了通过聚合属性(我之前的编辑)调用或围绕聚合实现包装器的需要。

希望这澄清了我想要实现的目标。这是最好的解决方案吗?

设计可互换使用的轻量和完整的对象

在我们的评论交流之后,你的问题现在被从不同的角度看待了。你不能直接得到多重继承会给你的东西。但是有很多方法可以让你非常接近。

变体1:欺骗需要MyFunction()的特殊类将其作为扩展方法接收。要做到这一点,你需要一个"微分器";在我的例子中,这是ILwA接口。注意,它必须定义另一个共性,而不是MyFunction()。getter(或setter)就可以了。这里的限制是MyFunction不能访问私有成员。

//instead of the lightweight interface (but use interface if it makes more sense)
abstract class LwBase 
abstract class HwBase : LwBase
public interface IADiff { int APropTrick { get; } }
// lightweight class definitions
class LwA : LwBase, IADiff
class LwB : LwBase
// full class definitions
class FullA : HwBase, IADiff
class FullB : HwBase
public static class AExtensions
{
    public static void MyFunction(this IADiff o)
    {
        // impl.
    }
}

变体2:使用提供MyFunction()实现的公共类并"重定向"到它:

abstract class LwBase 
abstract class HwBase : LwBase
public interface IADiff { int MyFunction(); }
public class AConcr : IADiff //implemenst Myfunction()
// lightweight class definitions
class LwA : LwBase, IADiff
{
    private AConcr a = new AConcr();
    public int MyFunction() { return a.MyFunction(); }
}
class LwB : LwBase
// full class definitions
class FullA : HwBase, IADiff
{
    private AConcr a = new AConcr();
    public int MyFunction() { return a.MyFunction(); }
}
class FullB : HwBase
变体3:我在研究你的问题时偶然发现了这篇文章。我不能很快地说这是否是一个可行的选择,但它确实提供了一些想法。

信用:我从这个SO线程大量借用,以及使用这个不错的网站作为参考。

要共享实现,您可以让它们都继承自abstract:

interface ILwBase                // a lightweight interface definition
interface ILwA : ILwBase
interface ILwB : ILwBase
class Intermediate : ILwBase
abstract class AbstractA : ILwA {
  void MyFunction() {...}
}
class LwA : AbstractA, Intermediate
class LwB : Intermediate 
class FullA : AbstractA
class FullB : ILwB

阅读更多关于抽象类的信息