C# 这是正确的面向对象设计吗?对象的静态函数返回实例

C# 这是正确的面向对象设计吗?对象的静态函数返回实例,c#,oop,design-patterns,C#,Oop,Design Patterns,我有一个代表人的数据库表。我正在编写一个将使用这个类的Web服务,我不想每次都得到所有的人。这样做“正确”吗?有没有类似的设计模式 这是一个简化的示例,说明了我实际上在做什么,每个属性中的所有setter都将保存到数据库中 namespace Example { class Person { private int _id; private string _name; private int _age; publi

我有一个代表人的数据库表。我正在编写一个将使用这个类的Web服务,我不想每次都得到所有的人。这样做“正确”吗?有没有类似的设计模式

这是一个简化的示例,说明了我实际上在做什么,每个属性中的所有setter都将保存到数据库中

namespace Example
{
    class Person
    {
        private int _id;
        private string _name;
        private int _age;

        public int ID { get { return _id; } set { _id = value; } }
        public string Name { get { return _name; } set { _name = value; } }
        public int Age { get { return _age; } set { _age = value; } }

        private Person(int id)
        {
            _id = id;
            // Query database and set values
        }

        public static Person GetPersonByID(int id) {
            return new Person(id);
        }
    }
}

在这种情况下,我会放弃这种方法。它没有任何用户不能自己做的事情,而它的使用是不直观的。拥有构造函数是正常的操作行为

一般来说,如果此函数执行构造函数中无法执行的操作,则可以使用此模式

就我个人而言,我会删除person类中的所有逻辑。做人是全班的工作。一个人可以没有任何数据库。如果要从数据源加载person,请创建一个数据源类,并让其中一个方法返回person

class Person
{
    public int ID { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
}

class DataSource
{
    public void Save(Person p)
    {
       // save person to database
    }

    public Person LoadById(int id)
    {
       // load person from database
    }
}

在这种情况下,我会放弃这种方法。它没有任何用户不能自己做的事情,而它的使用是不直观的。拥有构造函数是正常的操作行为

一般来说,如果此函数执行构造函数中无法执行的操作,则可以使用此模式

就我个人而言,我会删除person类中的所有逻辑。做人是全班的工作。一个人可以没有任何数据库。如果要从数据源加载person,请创建一个数据源类,并让其中一个方法返回person

class Person
{
    public int ID { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
}

class DataSource
{
    public void Save(Person p)
    {
       // save person to database
    }

    public Person LoadById(int id)
    {
       // load person from database
    }
}

您已经展示了一种可行的方法,但它将管道与对象本身混合在一起,这对于传递对象和维护性来说并不好


另一种非常常见的方式是存储库模式。在这种情况下,您将拥有一个PersonRepository类,该类旨在获取\更新Person类的实例。您的存储库与数据库交互并提供Person的实例。靠近UI的代码不需要担心任何实体框架\数据访问逻辑。用户界面只需从存储库中请求Person对象并显示它们。这表明关注点之间有很好的分离,这可以保持代码干净,并有助于将来的维护。

您已经展示了一种可行的方法,但它将管道与对象本身混合在一起,这对传递对象和维护性来说不是很好


另一种非常常见的方式是存储库模式。在这种情况下,您将拥有一个PersonRepository类,该类旨在获取\更新Person类的实例。您的存储库与数据库交互并提供Person的实例。靠近UI的代码不需要担心任何实体框架\数据访问逻辑。用户界面只需从存储库中请求Person对象并显示它们。这显示了良好的关注点分离,保持代码干净并有助于将来的维护。

此模式称为活动记录。只需确保//查询数据库中的任何内容和设置值都可以由多个线程执行,而不会出现问题,因此,请确保您没有任何无法被多个线程、Sql连接、EF上下文等访问的共享资源。如果您使用相同的ID调用该方法两次,会发生什么情况?你可以创建不同的人,而不是共享同一个ID。通常,至少我从未见过,对象不会在每次设置属性时保存。当然,我不知道您的用例是什么,因为您以Person类为例。此模式称为active record。请确保//查询数据库和设置值中的任何内容都可以由多个线程执行而不会出现问题,因此,请确保您没有任何无法被多个线程、Sql连接、EF上下文等访问的共享资源。如果您使用相同的ID调用该方法两次,会发生什么情况?你可以创建不同的人,而不是共享同一个ID。通常,至少我从未见过,对象不会在每次设置属性时保存。当然,我不知道您的用例是什么,因为您以Person类为例。我同意,它使实体逻辑远离db逻辑和表示逻辑变得更加灵活我同意,它使实体逻辑远离db逻辑和表示逻辑变得更加灵活