Хороший дизайн класса на примере - PullRequest
25 голосов
/ 25 мая 2011

Я пытаюсь найти лучший способ создать класс, свойства которого сохраняются в базе данных.Давайте возьмем базовый пример Person.Чтобы создать нового человека и поместить его в базу данных, я хочу, чтобы свойство DateOfBirth было необязательным (т. Е. NULLable в БД).

Вот мой пример кода:

namespace BusinessLayer
{
    class Person
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public DateTime DateOfBirth { get; set; }
    }
}

Я не уверен, должны ли поля быть публичными или нет.Должен ли я сделать это так:

class Program
{
    static void Main(string[] args)
    {
        Person person1 = new Person("Kate","Middleton",null);
    }
}

или вот так:

class Program
{
    static void Main(string[] args)
    {
        Person person1 = new Person();
        person1.FirstName = "Kate";
        person1.LastName = "Middleton";
    }
}

Мне также интересно, как мне поступить с необязательными свойствами класса.Как только поля заполнены, как мне сохранить их в БД?У меня есть класс DatabaseComponenet для сохранения информации.Как мне справиться с необязательным при сохранении в базу данных?

Итак, я бы сделал что-то вроде этого:

public int Save()
{
    int personId;
    personId = DatabaseComponent.InsertPerson(FirstName, LastName, DateOfBirth);
    return personId;
}

Спасибо за любую помощь!Также были бы полезны некоторые полезные ссылки на хороший дизайн класса.

Ответы [ 4 ]

19 голосов
/ 25 мая 2011

Во-первых, я бы назначил два отдельных публичных конструктора для Person:

namespace BusinessLayer
{
    class Person
    {
        public Person(string firstName, string lastName): this(firstName, lastName, DateTime.Now)
        {}

        public Person(string firstName, string lastName, DateTime birthDate)
        {
            FirstName = firstName;
            LastName = lastName;
            DateOfBirth = birthDate;
        }

        public string FirstName { get; set; }
        public string LastName { get; set; }
        public DateTime DateOfBirth { get; set; }
    }
}

это позволяет писать как

var p = new Person("Marilyin", "Manson");
var p2 = new Person("Alice", "Cooper", new DateTime(...));

и

var p = new Person { FirstName="Marilyn", LastName="Manson" };

Я не понимаю, почему вы должны ограничиться только одной формой.

Что касается DatabaseComponent, я настоятельно рекомендую написать метод, который позволит вам сохранить Person вместо подписи, которую вы неявно объявляете.

Это потому, что если однажды изменит способ определения Person, вам, вероятно, придется менять код в каждой точке, в которой вы вызываете метод Save(). Сохраняя только человека, вам нужно всего лишь изменить реализацию Save().

Кстати, вы не планируете использовать ORM?

11 голосов
/ 25 мая 2011

С инициализаторами класса C # 3.0 я больше не беспокоюсь о предоставлении конструктора, который позволяет мне инициализировать все свойства:

var person1 = new Person
{
    FirstName = "Kate";
    LastName = "Middleton";
};

Что касается метода Save, я обычно помещаю их в отдельный класс репозитория:

public int Save(Person person) 
{
    ...
}

и затем, когда мне нужно спасти человека, я делаю:

var person1 = new Person
{
    FirstName = "Kate";
    LastName = "Middleton";
};
var id = new PersonsRepository().Save(person1);
5 голосов
/ 25 мая 2011

Используйте конструкторы, только если некоторые поля обязательны , поскольку это эффективный способ убедиться, что эти поля указаны.

Я не уверен, должны ли поля быть открытыми или нет

Поля обычно означают переменные-члены, и они всегда должны быть закрытыми. Что касается свойств, я бы придерживался get / set для объектов базы данных.

Мне также интересно, как мне иметь дело с необязательными свойствами класса. Как только поля заполнены, как мне сохранить их в БД?

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

Взгляните на PetaPoco для облегченной альтернативы или nHibernate для более полной альтернативы.

1024 * Validation *

Один из распространенных способов убедиться, что обязательные поля правильно указаны и получены допустимые значения, - это использовать платформу проверки. В .net встроен один элемент Аннотации данных . Google это и посмотрите на некоторые примеры.

0 голосов
/ 25 мая 2011

Это следует проверить с помощью бизнес-правил.

Я имею в виду, что если вам нужна бизнес-модель с возможностью многократного использования, бизнес-объекты следует повторно использовать в других местах в разных областях, и это может означать, что тот же класс «А» может быть в состоянии «Х» в некоторых бизнесах, но в другой ситуации тот же класс «А» будет в состоянии «Y».

Существует хороший шаблон проектирования, позволяющий вам реализовать бизнес-валидаторы, называемые Спецификация :

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

Например:

someAInstance => someAInstance.Name != null && someAInstance.Age > 30

Другим способом является использование существующих библиотек проверки объектов, таких как NHibernate Validator, которые могут использоваться автономно без NHibernate и позволяют помещать атрибуты в свойства класса, такие как [NotNull], [NotNullNotEmpty] и более сложные правила, и вы можете либо используйте встроенные, либо вы можете создать свои собственные.

Подробнее читайте в этой статье (там вы найдете список готовых правил проверки) :

Обратите внимание, что одним из наиболее важных преимуществ NH Validator является то, что его можно использовать на любом уровне, не только на уровне данных или на уровне бизнеса, и, поскольку вы можете использовать его без NHibernate, вы получаете легкий и простой в использовании инструмент. использовать и многослойный объект валидатора.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...