【问题标题】:Feature envy, encapsulation, active record, separation of concerns? When its bad?特性羡慕、封装、活动记录、关注点分离?什么时候不好?
【发布时间】:2022-11-25 09:47:32
【问题描述】:

都说面向对象编程就是封装,数据隐藏。让我们举个例子:

class Rectangle
{
    private int a,b;

    public function __construct(int a, int b)
    {
        this.a = a;
        this.b = b;
    }

    int public function getA()
    {
        return a;
    }

    int public function getB()
    {
        return b;
    }
}

var r = new Rectangle(3, 4);
var area = r.getA() * r.getB();

这是一个糟糕的代码,所以让我们重新制作:

class Rectangle
{
    private int a,b;

    public function __construct(int a, int b)
    {
        this.a = a;
        this.b = b;
    }

    int public function getArea()
    {
        return a*b;
    }
}

r = new Rectangle(3, 4);
area = r.getArea();

更好的方法是,完成数据隐藏,并将 getArea 带到它所属的位置。 好的,Active Records 来了:

class Record
{
    private int ID;
    private string username;

    public function __constructor(int ID, string username)
    {
        this.ID = ID;
        this.username = username;
    }

    int public function getID()
    {
        return ID;
    }

    string public function getUsername()
    {
        return username;
    }
}

r = new Record(1, 'test');
dbEngine.save(r);

这又很糟糕,因为所有数据都是公开的。 (尽管 Doctrine 是这样工作的) 但如果我像 Propel 那样做:

class Record
{
    private int ID;
    private string username;

    public function __constructor(int ID, string username)
    {
        this.ID = ID;
        this.username = username;
    }

    public function save()
    {
        dbEngine.save([ID, username]);
    }
}

r = new Record(1, 'test');
r.save();

这也说不好,因为 Active Records 是反模式的。那什么时候好,什么时候坏?什么时候应该将“行为”(getArea,保存)引入对象内部 - 什么时候在外部行为?

【问题讨论】:

    标签: activerecord separation-of-concerns


    【解决方案1】:

    您可以为您的特定情况注入 dbEngine 依赖项,但这并不能解决您的问题。

    一般来说,使您的代码优秀的是它的易懂性,以及意图的变化与实现的变化之间的紧密联系。

    揭示私有内部结构的问题在于,您正在暴露与您的程序交互的程序可能依赖的内在价值观(并且以后很难更改)。记录基本上是一个结构/数据类——它代表一组值,这些值具有一些明确定义的含义。在不知道代码的其余部分的情况下,我不能说这个特定的类是否是这样的,但如果是这样的话,就可以把它变成一个结构(所有成员都是公共的,没有方法)。

    没有任何包罗万象的规则可以使代码变得“好”。这是一个不断犯错误或效率低下的过程,并分析哪些代码导致或更可能导致该问题。代码味道只是其他人大量试验和错误的结果,虽然在大多数情况下非常健壮,但有时可能会过时并在他们改进代码时应用于特定情况。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-20
      • 2010-10-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多