2013-05-09 81 views
0

我在使用類似這樣的接口和類結構的系統工作重量輕,全對象:設計可互換使用

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中定義的數據和方法。所以,我覺得自己需要做這樣的事情:

if (myvar is FullA) 
{ 
    (myvar as FullA).MyFunction() 
} 
else 
{ 
    (myvar as LwA).MyFunction() 
} 

其中MyFunction的()分別在每個阿芙拉實現輕骨料,並且可以在相同的數據結構的工作。我想消除這種代碼重複。

我的C++背景似乎是多繼承的典型案例;即爲需要的數據和方法定義類別SharedA,並將其添加到父列表FullALwA。但我需要一些指導來幫助在C#和界面世界中思考這個問題。有沒有可以接受的模式來解決這個問題?

謝謝。

UPDATE:

隨着意見的幫助下收到到目前爲止,我已經能夠重構與1更好的設計)的中間接口需要共享數據的彙總和2)延伸類的方法來處理這些數據。理想情況下,這些(數據和方法)將被加入到相同的構造中。我覺得板子裏有mate-in,我只是看不到它。

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之間重複代碼所需的東西。它消除了通過聚合屬性(我以前的編輯)調用或實現聚合包裝的需要。

希望這澄清了我想要實現的。這是最好的解決方案嗎?

+0

如果需要治療阿芙拉和輕骨料不同,可他們真正** **被稱被編碼到相同的接口?也許你的界面被設計打破了,需要做得更好/更全面? – Patashu 2013-05-09 01:36:10

+0

@Patashu很多時候我不在乎我是否在使用「完整」對象。在這些情況下,我需要做的是在兩者之間共同使用的一小部分數據和方法。 – jltrem 2013-05-09 01:39:41

+0

如果接口沒有爲你做(定義所有在這兩者之間通用的方法),那麼你的接口是壞的。 – Patashu 2013-05-09 01:41:13

回答

2

按照我們的評論交流,您現在的問題與原始帖子不同。你不能直接擁有多重繼承會給你的東西。但有很多方法可以讓你變得非常接近。

變體1:欺騙你需要MyFunction()的特殊課程作爲擴展方法接收它。要做到這一點,你需要一個「差異化者」;在我的例子中是ILwA接口。請注意,它必須定義另一個通用性,而不是MyFunction()。一個吸氣(或一個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:我偶然在this article因爲我是研究你的問題。我不能很快地說這是否是一個可行的選擇,但它肯定提供了一些想法。

積分:我從this SO thread大量借用,以及使用this nice site作爲參考。

+0

你在哪裏定義MyFunction()?如果我在一個抽象類中定義它,那麼我仍然不確定如何解決由於Intermediate類而導致的多重繼承問題。 – jltrem 2013-05-09 02:58:31

+0

您正在說明'哪裏MyFunction()在每個FullA和LwA'中分別實現,因此您可以在ILwA中定義MyFunction,並且需要LwA和FullA來實現它。我已經更新了我的答案。 – 2013-05-09 03:03:43

+0

是的,這就是我現在的代碼... MyFunction()在FullA和LwA中的實現方式相同。但如果可能的話,我試圖擺脫重複。 – jltrem 2013-05-09 03:08:31

1

要共享的實現,你可以讓他們無論從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 

瞭解更多關於Abstract Classes (on MSDN)

+0

抽象類解決了共享實現的問題。但剩下的問題是使用中間類:'類LwA:AbstractA,Intermediate'不會編譯,因爲它是多重繼承。 – jltrem 2013-05-09 02:51:14

+0

哦,對不起,我在想''Intermediate'也是一個界面。我的錯。 – CodingWithSpike 2013-05-09 12:47:03

+0

是的,從* I *開始混淆。應該稱之爲中等。 – jltrem 2013-05-09 13:05:35