Как спроектировать мой класс - PullRequest
0 голосов
/ 10 октября 2009

У меня есть класс, который возвращает три свойства. Первое свойство зависит от некоторого параметра, второе зависит от первого свойства, а третье зависит от второго свойства.

Как лучше всего реализовать этот тип класса, есть ли подходящий шаблон проектирования для этого? Ниже я вставил две версии своего кода, которые обе работают, и мне интересно, какая из них лучше (или я слишком много усложняю)?

Первый:

class Initializer
{
    private string lastCode;
    private int lastPackage;
    private int lastBox;

    public Initializer(int machineNumber)
    {
        lastCode = GetLastCodeFromDatabase(machineNumber);
        lastPackage = GetLastPackageByLastCode(lastCode);
        lastBox = GetLastBoxByLastPackage(lastPackage);
    }

    public string LastCode
    {
        get { return lastCode; }
    }

    public int LastPackage
    {
        get { return lastPackage; }
    }

    public int LastBox
    {
        get { return lastBox; }
    }

    private string GetLastCodeFromDatabase(int machineNumber)
    {
        using (InitializerTableAdapter adapterGetLastCode = new InitializerTableAdapter())
        {
            return Convert.ToString(adapterGetLastCode.GetLastCodeByMachineNumber(machineNumber));
        }
    }

    private int GetLastPackageByLastCode(string lastCode)
    {
        using (InitializerTableAdapter adapterGetLastPackage = new InitializerTableAdapter())
        {
            return Convert.ToInt32(adapterGetLastPackage.GetLastPackageByLastCode(lastCode));
        }
    }

    private int GetLastBoxByLastPackage(int lastPackage)
    {
        using (InitializerTableAdapter adapterGetLastPackage = new InitializerTableAdapter())
        {
            return Convert.ToInt32(adapterGetLastPackage.GetLastBoxByPackageNumber(lastPackage));
        }
    }
}

Второе:

class Initializer
{
    public static string LastCode(int machineNumber)
    {
        return GetLastCodeFromDatabase(machineNumber);
    }

    public static int LastPackage(string lastCode)
    {
        return GetLastPackageByLastCode(lastCode);
    }

    public static int LastBox(int lastPackage)
    {
        return GetLastBoxByLastPackage(lastPackage);
    }

    private static string GetLastCodeFromDatabase(int machineNumber)
    {
        using (InitializerTableAdapter adapterGetLastCode = new InitializerTableAdapter())
        {
            return Convert.ToString(adapterGetLastCode.GetLastCodeByMachineNumber(machineNumber));
        }
    }

    private static int GetLastPackageByLastCode(string lastCode)
    {
        using (InitializerTableAdapter adapterGetLastPackage = new InitializerTableAdapter())
        {
            return Convert.ToInt32(adapterGetLastPackage.GetLastPackageByLastCode(lastCode));
        }
    }

    private static int GetLastBoxByLastPackage(int lastPackage)
    {
        using (InitializerTableAdapter adapterGetLastPackage = new InitializerTableAdapter())
        {
            return Convert.ToInt32(adapterGetLastPackage.GetLastBoxByPackageNumber(lastPackage));
        }
    }
}

Ответы [ 3 ]

2 голосов
/ 10 октября 2009

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

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

Если второе является лучшим соответствием, вам следует изучить внедрение зависимостей, чтобы можно было внедрить другой источник данных для тестирования (или для перехода от внутреннего SQL-кода к локальной базе данных и т. Д.).

1 голос
/ 10 октября 2009

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

Кроме того, мне интересно, почему у вас такой плоский взгляд на модель вашего домена. Мне кажется это чем-то необычным.

1 голос
/ 10 октября 2009

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

С другой стороны, если ваши свойства будут использоваться не очень часто, возможно, один или два раза, или значения, возвращаемые методами, будут варьироваться от одного вызова к другому, второй вариант будет лучшим. Если значение функции сильно меняется, вы все равно не сможете выполнить инициализацию и получить ожидаемые результаты.

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

...