通过实例进行良好的课堂设计

本文关键字:课堂 实例 | 更新日期: 2023-09-27 17:57:42

我正在努力找出设计一个将其属性持久化在数据库中的类的最佳方法。让我们举一个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";
    }
}

我还想知道应该如何处理类的可选属性。填充完字段后,如何将它们保存到数据库中?我有一个DatabaseComponentet类来保存信息。保存到数据库时,如何处理可选项?

那么,我能做这样的事情吗:

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

谢谢你的帮助!一些关于良好类设计的有用URL也将受到赞赏。

通过实例进行良好的课堂设计

首先,我为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吗?

有了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);

只有当某些字段是强制字段时才使用构造函数,因为这是确保指定这些字段的有效方法。

我不确定这些字段是否应该公开

字段通常意味着成员变量,并且这些变量应该始终是私有的。至于属性,我会坚持使用数据库对象的get/set。

我还想知道应该如何处理类的可选属性。填充完字段后,如何将它们保存到数据库中?

将内容保存到数据库则完全不同。我不会尝试发明我自己的图层,而是使用现有的图层。有一整套不同的ORM:从非常简单到功能非常完整。

看看PetaPoco的轻量级替代品,或者看看nHibernate的功能更完整的替代品。

验证

确保强制字段被正确指定并获得有效值的一种常见方法是使用验证框架。net中内置了一个名为DataAnnotations的函数。谷歌一下,看看一些例子。

这应该通过使用业务规则进行检查。

我的意思是,如果你想要一个非常可重复使用的业务模型,那么业务对象应该在不同区域的其他地方重复使用,这可能意味着在某些业务中,同一类"a"在状态"X"下可以,但在另一种情况下,同一类别"a",在状态"Y"下也可以。

有一个很好的设计模式允许您实现称为规范的业务验证器:

  • http://en.wikipedia.org/wiki/Specification_pattern

这可以通过多种方式实现,但最紧凑的方式之一是使用lambda表达式构建规则。

例如:

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

另一种方法是使用现有的对象验证库,如NHibernate Validator,它可以在没有NHibernat的情况下独立使用,并允许您将属性放在类的属性中,如[NotNull][NotNullNotEmpty]和更复杂的规则,您可以使用内置的,也可以构建自己的。

阅读本文了解更多信息(在那里你会发现开箱即用的验证规则列表):

  • http://nhforge.org/wikis/validator/nhibernate-validator-1-0-0-documentation.aspx

请注意,NH验证器最重要的优点之一是它可以在任何层使用,而不仅仅是数据层或业务层。由于您可以在没有NHibernate的情况下使用它,因此您拥有了一个轻量级、易于使用和多层的对象验证器。