Как обрабатывать свойства с динамическими значениями по умолчанию - PullRequest
0 голосов
/ 24 февраля 2009

У меня часто бывает такая ситуация при создании простых объектов данных. У меня есть свойство с именем Label, которое должно иметь значение по умолчанию на основе имени объекта. Поэтому, если метка не установлена, тогда используется Имя, в противном случае используйте метку набора. Простой пример в C #

public class FooBat {
    public string Name { get; set; }
    public string Label {
        get {
            if (_label == null) return Name;
            return _label;
        }
        set { _label = value; }
    }
}

Теперь проблема в том, что если вы хотите отредактировать этот объект, вы не можете просто привязать его к свойству Label, или вы получите значение по умолчанию, и оно будет выглядеть так, как будто там есть значение, а на самом деле его нет. Поэтому я в итоге создаю другое свойство только для чтения, которое выполняет значения по умолчанию, и я использую это все экземпляры, кроме случаев, когда базовый объект редактируется. Это приводит ко многим дополнительным свойствам со странными именами, такими как LabelWithDefault. Другая альтернатива, которую я попробовал, - заставить Label обрабатывать значения по умолчанию и создать новое свойство с именем RealLabel, которое используется для редактирования базового объекта. Это так же плохо.

Я думал о переносе кода по умолчанию куда-то еще, но я не нашел подходящего места для него ни в одной "нормальной" модели, которая много раз не копирует код по умолчанию.

То, что я начал делать сейчас, - это инициализировать поле «Метка», когда поле «Имя» установлено (а поле «Метка» - нет), а затем обработать поле «Метка» как обычное поле. Это работает, но теперь код по умолчанию привязан к неправильному свойству. Почему Имя должно знать, что поле Label заботится об этом? Так что это тоже не "правильно".

Есть ли у кого-нибудь лучшие способы решения этой проблемы?

<Ч />

Я думаю, что есть небольшая путаница в том, что я прошу. По сути, мне нужны два разных представления для одного и того же объекта для двух разных целей. Во-первых, это редактирование самого объекта, где я хочу, чтобы неустановленные поля отображались как пустые (неустановленные). Второй - для всех других случаев (в том числе, когда объект является значением поля другого объекта), где я хочу показать каждое поле с его динамически определяемым значением по умолчанию. Простая установка значения по умолчанию в первый раз не поможет, потому что если (в данном случае) поле Имя изменяется, то поле Метка также должно меняться , пока поле Метка не будет установлено .

<Ч />

Ответы становятся ближе, но я все еще думаю, что они слишком нацелены на пример, который я привел. Я пытался привести конкретный пример для разъяснительных целей, но на самом деле это больше вопрос передового опыта. Пример, который я привел, был C # и для строкового свойства, но у меня та же проблема с большинством языков и систем, которые я использую, которые имеют каркасы, в которых доступ к данным и их отображение обрабатываются для вас, а также для типов данных, отличных от строк. Изменение объекта, который запрашивается из источника данных, возможно, но часто сложно, и знание того, когда внести изменение (используйте подкласс в этом случае, но не в этом), особенно сложно.

Ответы [ 3 ]

1 голос
/ 24 февраля 2009
public class FooBat {
    public string Name { get; set; }    
    public string Label {
        get {
             if (_label == null) 
                 _label = Name;
             return _label;        
            }        
        set { _label = value; }    
   }
}

По поводу вашего обновления: Вы можете подкласс вашего объекта. Базовый класс вернул бы ноль, если поле не было установлено, а подкласс вернул бы ваше значение по умолчанию. Таким образом, если вам нужно запросить, было ли установлено значение, вы бы преобразовали в базовый класс.

0 голосов
/ 24 февраля 2009

Я часто использую Nameable интерфейс (с getName()). Прежде чем я начну, я предлагаю, чтобы вы вообще не хотели этого делать. Это должен быть домен вашей логики отображения, а не объекты вашего домена. Обычно это код, потребляющий FooBat, который может принять это решение лучше, чем сам объект. Это в сторону ...

public interface Label{
    string getLabel();
    boolean isDefault(); //or isValued() or use instanceof expressions
}

public interface Nameable{
    string getName();
}

public class FooBat implements Nameable {
    public string Name { get; set; }
    public Label Label {
        get {
            if (_label == null) {
                _label = new DefaultLabel(this);
            }
            return _label;
        }
        set { _label = value; }
    }
}

public class DefaultLabel implements Label{
    public DefaultCharSequence(Nameable named){
        this.named = named;
    }

    public string getLabel(){
        return named.getName();
    }

    public boolean isDefault(){ return true; }
 }

 public class StringLabel implements Label {
     ...
 }

Все сводится к возвращению лучшего класса для вашего объекта метки.

0 голосов
/ 24 февраля 2009

Удалены предыдущие ответы / обновления для краткости.

<ч /> Обновление 2: Я должен сказать, что лучший способ - отслеживать, установлено ли свойство с помощью bool IsPropertySet. Получатель для свойства проверит это значение, чтобы увидеть, должно ли оно возвращать свое собственное значение или значение по умолчанию. И установщик для свойства установит IsPropertySet в соответствии с установленным значением (true, если значение не равно нулю, false, если оно есть). Код, использующий класс, может затем посмотреть на значение IsPropertySet, чтобы определить, получает ли оно заданное значение или значение по умолчанию при вызове метода получения свойства.

public class FooBat {
   public string Name { get; set; }
   public bool IsLabelSet { get; set; }
   public string Label {
      get {
         if (IsLabelSet)
            return _label;
         else
            return Name;
      }
      set {
         IsLabelSet = value != null;
         _label = value;
      }
   }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...