4

处理方法依赖于执行的属性的最佳方法是什么?

假设您有一个具有 2 个属性的类和一个对这 2 个属性执行某些操作的方法。实例化类,设置属性,然后执行方法会更好(不带参数);还是实例化类,然后执行方法,传入将设置属性的参数?

例如:

class Person ...
    string Name ...
    string Address ...
    void Save() {
        Database.SavePerson(this.Name, this.Address);
    }

- - 或者 - -

class Person ...
        string Name ...
        string Address ...
        void Save(string name, string address) {
            this.Name = name;
            this.Address = address;
            Database.SavePerson(this.Name, this.Address);
        }

在第一个示例中,如果在调用 Save 方法之前尚未设置 Name 和 Address,则会出现错误。因此,您似乎必须验证这些属性是否已在方法中设置。

第二个示例强制用户提供执行该方法所需的数据。但是,这似乎有点多余,因为传入的参数已经是对象的属性。

有没有“最好”的方法来做到这一点?

提前致谢。

4

5 回答 5

2

那么首先我会考虑让实体对其自身的持久性负责是否是您想要的设计。

如果不是,那么一个Person实体将公开属性,而另一种类型将负责保存该Person实体(例如,如果使用类似 Repository 模式的东西,就会出现这种情况)。

如果实体负责持久化自身(如果您使用丰富的域模型,例如与 CSLA 等框架一起使用的模型),那么您将只有一个无参数Save方法,并且如果需要属性,那么某种形式的验证框架会捕捉到任何缺失的需求。

于 2012-10-18T20:15:53.557 回答
2

就个人而言,我两者都不会。您拥有的第一个示例类似于 Active Record,而第二个示例对我来说根本没有意义,如果函数接受参数,那么拥有字段/属性有什么意义?

您的两种方法的问题是Person该类公开了您可能不想要的数据库逻辑。

我要做的是使用存储库模式:

public class Person
{
    public string Name { get; set; }
    public string Address { get; set; }
}

public class PersonRepository()
{
    public void Add(Person person)
    {
        // do some database stuff
    }
}

// ...

Person person = new Person() { Name = "Jim", Address = "123 Fake Street" };

PersonRepository personRepository = new PersonRepository();
personRepository.Add(person);
于 2012-10-18T20:19:06.630 回答
0

我想到了什么——你用这种方法打破了单一责任原则。因为您做了三件事 - 持久化实体、重命名人员和更改其地址。这从方法的名称中不清楚。这是副作用。

因此,为了告知开发人员您的方法的真正作用,您应该将其重命名为SaveAndRenameAndRelocate. 名字不是很好?同意。

因此,我创建了无参数方法来将实体保存在当前状态。

public void Save()
{
   // code, which should be somewhere in repository
}

如果您需要重命名人员 - 通过 Name 属性进行。如果您需要更改地址 - 通过地址属性进行。如果不允许保存没有姓名和/或地址的人 - 通过构造函数初始化这些属性:

public Person(string name, string address)
{
   // null-check goes here
   Name = name;
   Address = address;
}

顺便说一句,让实体保持自身并不是一个好主意:)

于 2012-10-18T20:28:19.607 回答
0

如果参数可以以某种方式推断/解析,或者如果它们永远不会改变,则只让方法无参数。

否则,它会变成一个可怕的泄漏抽象,您需要了解该方法的工作原理才能使用它。

于 2012-10-18T20:13:31.857 回答
0

要么你有一个实例方法,它会自动使用它自己的不带参数的属性,要么你有一个静态方法,它接受传递给它的任何参数

public class Person
{
    public string Name { get; set; }
    public string Address { get; set; }

    public void Save()
    {
        Database.SavePerson(Name, Address);
    }

    public static void Save(string name, string address)
    {
        Database.SavePerson(name, address);
    }
}

对象的一般概念是每个对象都对自己的数据负责。但是,一个类可以有一个可以全局使用的静态方法,并且不绑定到任何对象实例。静态方法不能访问实例成员。


但基本问题是是否应该在Person类中包含保存方法。相反,我会将Database.SavePerson方法的参数列表更改为

public static void SavePerson(Person person) { ... }

并像这样使用它

var p = new Person { Name = "John", Address = "Wall Street, NY" };
Database.SavePerson(p);
于 2012-10-18T20:21:27.120 回答