作为一名软件架构师,经常使用抽象来隐藏实现细节,为使用者创建API接口。抽象还允许在项目的后期阶段更改实现方式,当然,它也使代码更加易于测试。抽象的另一个好处是它能够解耦正在编写的代码,这是一件好事。但是,正如所有的优点一样,过度使用抽象也可能导致问题。
在与客户讨论架构时,曾经说过一句话:“过度的抽象会害了。”意思是,由于可以抽象一切,需要有“感觉”来判断何时使用这种方法是合适的。
在客户的代码中,存在一层又一层的抽象,这些抽象提供的细节更少或者与它们试图抽象的接口完全相同。在这种情况下,更倾向于遵循KISS原则(Keep It Simple, Stupid),去掉一些不必要的抽象。现在,解决方案更清晰、更易于阅读,且没有多余的抽象。
客户的例子表明,尽管抽象是一种很好的实践,但应该了解何时应用它们。例如,抽象基础设施是一个很好的实践。可以看看Enterprise Library或Spring.NET的代码,看看如何利用抽象。另一方面,为数据传输对象(DTO)创建一个抽象其属性的接口,是倾向于避免的。原因是DTOs旨在作为数据持有者,没有行为。如果抽象了属性,什么也得不到,因为在大多数情况下,实现将只是一个getter和一个setter,没有更多。这两个例子准确地展示了所说的,应该了解何时应用抽象。
以下是一个简单的代码示例,展示了如何避免不必要的抽象:
public class User {
private string name;
private int age;
public string Name {
get { return name; }
set { name = value; }
}
public int Age {
get { return age; }
set { age = value; }
}
}