Дело с отсутствием базы компании, поддержка enum


Я использую сущности рамочного код первого ОСАГО 5 для текущего проекта. До сих пор нет поддержки enum в рамках субъекта, так это то, что я использую для того, чтобы избежать магических чисел или бросает валялись на протяжении всей моей код.

Упрощенный Пример:

Модель предметной области потребляемого код первого

public class Address
{
    // This would normally be an enum
    public int Type { get; set; }
}

Репозиторий

public class AddressRepository
{
    public Add(Address address)
    {
        // Compare using enum semantics
        if (address.Type == AddressType.Home)
            // Do something

        context.Add(address);
    }
}

Модели Представления

public class AddressVM
{
    // Using the AddressType class for the view model
    public AddressType Type { get; set; }     

    public AddressVM(Address address)
    {
        this.Type = address.Type;
    }
}

Замена Класса Enum

public interface IEnumClass
{
    List<string> Properties { get; }
}

public class AddressType : IEnumClass
{
    public static int Home { get { return 0; } }
    public static int Work { get { return 1; } }

    public List<string> Properties { get { return properties; } }

    private List<string> properties;
    private int id;

    public AddressType()
    {
        SetProperties();
    }
    public AddressType(int id)
    {
        this.id = id;
        SetProperties();
    }

    private void SetProperties()
    {
        properties = this.GetType().GetProperties(BindingFlags.Public|BindingFlags.Static)
            .Select(x => x.Name).ToList();
    }

    public static implicit operator AddressType(int id)
    {
        return new AddressType(id);
    }

    public static implicit operator String(AddressType addressType)
    {
        return addressType.properties[addressType.id];
    }

    public static implicit operator int(AddressType addressType)
    {
        return addressType.id;
    }
}

Моя Личная Оценка

Плюсы:

  • Позволяет мне создавать бизнес-правила, не используя магию чисел
  • Используется та же семантика/синтаксис перечисления для легкого рефакторинга вниз по дороге
  • Позволяет неявное преобразование в строку для представления модели
  • Мой выбор список фабрики классов могут легко быть сделаны, чтобы принять любой IEnumClass и создать выберите список для представления модели

Минусы:

  • Немного многословный
  • Насколько я могу судить, невозможно использовать хороший абстрактный универсальный класс, поскольку все фактические работы используется неявное приведение типов

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



5239
15
задан 4 марта 2011 в 05:03 Источник Поделиться
Комментарии
1 ответ

Я думаю, что самый большой недостаток вашего подхода в том, что вы добавляете сложности, но не становится главным преимуществом для вас нужно, что, чтобы избежать магических чисел. Этот код не мешает вам использовать магические цифры, так как он автоматически конвертирует из любого инт в таблицы addresstype, а она все равно выставляет свои ценности как инт. Поэтому я предложил бы одно из следующих двух подходов. Первый из них очень простой, но, кажется, дает те же преимущества, как ваш код. Вторая-это больше вдоль линий, что вы хотите, так что есть некоторые сложности, но имеет некоторые дополнительные преимущества.

Простое решение

Я думаю, что проще всего было бы просто иметь статический класс с константами, определенными в нем, например, так:

public static class AddressType
{
public const int Home = 1;
public const int Work = 2;
}

(Примечание: как и в любой перечислимый, 0 не должно быть допустимое значение)

Вы бы тогда хранить свои ценности как инт на ваши лица, но всегда сравниваю их от этих констант. Это даст вам тот же шаблон использования, как вы показали в вашем вопросе.

Более сложное решение

Кроме того, если вы хотите пойти с вашим подходом, вы должны ограничиться только позволит вам создавать таблицы addresstype с известными значениями, которые сделают невозможным использование магических чисел и сделать его более строгим, чем при использовании обычного инт.

Так например, что-то вроде следующего:

public class AddressType
{
public static readonly AddressType Home = new AddressType(1);
public static readonly AddressType Work = new AddressType(2);

private int value;

private AddressType(int value)
{
this.value = value;
}

public override bool Equals(object obj)
{
AddressType rhs = obj as AddressType;
return
rhs != null &&
this.value == rhs.value;
}

public override int GetHashCode()
{
return this.value.GetHashCode();
}
}

В вашей модели, вы будете использовать его так:

public class Address
{
public AddressType AddressType { get; set; }
}

Теперь назначение и сравнивая эти таблицы addresstype значения выглядит просто как перечисление, но явно мешает вам использовать магию чисел. Если вам действительно это нужно, вы можете также добавить переходы к/от инт, но только разрешу, если они являются известными величинами.

Вы могли бы использовать что-то вроде следующего, хотя если у вас больше чем 2 значения, вы, вероятно, хотите использовать словарь на карте от инт данным таблицы addresstype:

public static implicit operator AddressType(int value)
{
if (value == AddressType.Home.value)
{
return AddressType.Home;
}
else if (value == AddressType.Work.value)
{
return AddressType.Work;
}

throw new InvalidCastException();
}

5
ответ дан 5 марта 2011 в 01:03 Источник Поделиться