Копиклонирование (клоникопирование?)
От: Артем1 Россия  
Дата: 01.02.11 21:11
Оценка:
Здравствуйте.

Посоветуйте, как бы вы решали такую проблему.

Есть сущность (с наследниками)

public interface IClonable<T> where T:... 
{
    T Clone();
}

public class CostInfo: ..., IClonable<CostInfo>
{
  ...
    protected virtual CostInfo newInstance()
    {
        return new CostInfo(...);
    }
    
    public CostInfo Clone()
    {
         var ci = newInstance();
         //set props
         return ci;
    }
}

public class OtherCostInfo: ..., IClonable<OtherCostInfo>
{
  ...
    protected override OtherCostInfo newInstance()
    {
        return new OtherCostInfo(...);
    }
    
    public new OtherCostInfo Clone()
    {
         var ci = (OtherCostInfo)base.Clone();
         //set OtherCostInfo specific props
         return ci;
    }
}


Так уж вышло, что эти сущности хранятся в другой сущности. Причем коллекция может содержать в некоторых случаях CostInfo, в других OtherCostInfo (либо либо, вместе не хранятся).

public class SomeCostHolder
{
    public IList<CostInfo> Costs { get { ... } }
}


Потребовался функционал для копирования SomeCostHolder. Среди прочего кода появился хелпер:

   //псевдокод
public void CopyCollection<T>(IList<T> source, IList<T> target, ...) where T: IClonable<T>
{
   source.ForEach(si => target.Add(si.Clone()));
}


И тут выяснилось, что бывают ситуации, когда при копировании надо конвертировать CostInfo в OtherCostInfo, т.к. другой SomeCostHolder, в который копируются данные, не ожидает у себя в коллекции CostInfo. Проблема у меня тут в том, что метод Clone специально добавлен в DomainModel, что-бы быть поближе к копируемым данным и не забывать его обновлять при изменении модели. А теперь ситуация вынуждает превратить копирование (клонирование) в конвертирование. Для задачи достаточно скопировать только то, что может быть скопировано (от общих предков). Специальная логика конвертации не требуется. При этом не хочется вводит связность в модель (разные наследники знают друг о друге) и не хочется тащить все это вовне в отдельный класс (будем забывать обновлять его). Вводить m:m конвертеров по кол-ву возможных сочетаний как то тоже гм.
Свое решение приводить не буду (пока), хочется посмотреть на возможные подходы.

зы: а то три года времени не было толком на форуме посидеть, а тут как почитал, сколько копий сломано в Anemic vs Rich, так сразу сомнения появляются в квалификации
ззы: высказывания по типу SomeCostHolder криво спроектирован тоже принимаются, но с примером, как надо было спроектировать
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.