я работаю в системе, которая использует структуру интерфейса и класса, подобную этой:конструкция для сменного использования легких и полных объектов
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() осуществляется отдельно в каждом Fulla и LwA и может работать на одинаковых структур данных. Я хочу устранить это дублирование кода.
С моим фоном C++ это типичный случай для множественного наследования; то есть определить класс SharedA для данных и методов, которые необходимы и добавить в родительский список FullA и LwA. Но мне нужно руководство, чтобы помочь продумать это в мире C# и интерфейсов. Есть ли принятый шаблон для решения этой проблемы?
спасибо.
UPDATE:
С помощью полученных комментариев до сих пор, я был в состоянии реорганизовать для лучшего дизайна с 1) промежуточный интерфейс, требующий агрегат для общих данных и 2) расширение класс для методов работы с этими данными. В идеале эти (данные и методы) будут объединены в одну и ту же конструкцию. Я чувствую, что мат-в-1 находится на доске, и я просто не вижу его.
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. И он устраняет необходимость вызова свойства aggregate (мое предыдущее редактирование) или реализации оберток вокруг совокупности.
Надеюсь, это разъясняет, чего я пытаюсь достичь. Это лучшее решение?
Если вам нужно обработать Fulla и LWA по-разному, они могут ** действительно ** можно сказать быть закодированным в один и тот же интерфейс? Может быть, ваш интерфейс нарушен дизайном и должен быть лучше/более полным? – Patashu
@Patashu Много раз мне все равно, работаю ли я с «полным» объектом. То, что мне нужно сделать в этих случаях, - это работа с небольшим подмножеством данных и методов, которые являются общими между ними. – jltrem
Если интерфейс не делает этого для вас (определите все методы, которые являются общими между двумя), ваш интерфейс сломан. – Patashu