Подтвердить что ты не робот

Хороший дизайн класса на примере

Я пытаюсь разработать лучший способ разработки класса, который сохраняет свои свойства в базе данных. Возьмем базовый пример a 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;
}

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

4b9b3361

Ответ 1

Во-первых, я поставил бы два отдельных публичных конструктора в 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(). Сохраняя только Person, вам нужно только изменить реализацию Save().

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

Ответ 2

С инициализаторами класса С# 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);

Ответ 3

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

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

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

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

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

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

Validation

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

Ответ 4

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

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

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

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

Например:

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

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

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

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