Nodejs 后端分层你们用的贫血模型还是充血模型?

Nodejs 后端分层你们用的贫血模型还是充血模型?

类似这篇文章说的:贫血模型与充血模型的对比

目前觉得类似Java SSH的贫血模型比较简单,但是没写过RoR和Python/django,不知道什么感觉。

9 回复

Node.js 后端分层:贫血模型 vs 充血模型

在 Node.js 后端开发中,选择使用贫血模型(Anemic Domain Model)还是充血模型(Rich Domain Model)是一个常见的设计决策。这两种模型各有优缺点,适用于不同的场景。下面我们通过一些简单的代码示例来比较这两种模型。

贫血模型 (Anemic Domain Model)

贫血模型是一种经典的面向对象设计模式,其中业务逻辑被放在服务层,而不是实体类中。这种方式的优点是简单直观,易于理解和实现。但是,它也缺乏封装性,业务逻辑分散在多个地方,不利于维护。

示例代码

// 用户实体
class User {
    constructor(id, name) {
        this.id = id;
        this.name = name;
    }
}

// 用户服务
class UserService {
    constructor(userRepository) {
        this.userRepository = userRepository;
    }

    async createUser(name) {
        const user = new User(Date.now(), name);
        return await this.userRepository.save(user);
    }

    async findUserById(id) {
        return await this.userRepository.findById(id);
    }
}

// 用户仓库
class UserRepository {
    async save(user) {
        // 假设这里使用数据库操作
        console.log(`Saving user ${user.name}`);
        return user;
    }

    async findById(id) {
        // 假设这里使用数据库查询
        return new User(id, 'John Doe');
    }
}

充血模型 (Rich Domain Model)

充血模型将业务逻辑直接放在实体类中,使这些类变得更加智能。这种方式的优点是封装性强,业务逻辑集中管理,易于维护。但实现起来相对复杂,需要更多的设计和测试工作。

示例代码

// 用户实体
class User {
    constructor(id, name) {
        this.id = id;
        this.name = name;
    }

    async save() {
        // 假设这里使用数据库操作
        console.log(`Saving user ${this.name}`);
    }

    static async findById(id) {
        // 假设这里使用数据库查询
        return new User(id, 'John Doe');
    }
}

// 用户服务
class UserService {
    constructor() {}

    async createUser(name) {
        const user = new User(Date.now(), name);
        await user.save();
        return user;
    }

    async findUserById(id) {
        return User.findById(id);
    }
}

总结

  • 贫血模型:适合简单项目或团队对 OOP 模式不熟悉的场景。
  • 充血模型:适合复杂的业务逻辑,需要更好的封装性和可维护性的项目。

选择哪种模型取决于项目的具体需求和个人偏好。希望上述示例能够帮助你更好地理解这两种模型的设计理念和实现方式。


用的是大姨妈模型

作为单线程的NODEJS,要尽量拒绝一切分层,单刀直入,获取最大的效率

这文章不错 ,貌似开发到现在都是采用的贫血模型的。

 **贫血模型**:
       是指领域对象里只有get和set方法,或者包含少量的CRUD方法,所有的业务逻辑都不包含在内而是放在Business Logic层。

      优点是系统的层次结构清楚,各层之间单向依赖,Client->(Business Facade)->Business Logic->Data Access(ADO.NET)。当然Business Logic是依赖Domain Object的。似乎现在流行的架构就是这样,当然层次还可以细分。

      该模型的缺点是不够面向对象,领域对象只是作为保存状态或者传递状态使用,所以就说只有数据没有行为的对象不是真正的对象。在Business Logic里面处理所有的业务逻辑,在POEAA(企业应用架构模式)一书中被称为Transaction Script模式。 

    **充血模型:**
         层次结构和上面的差不多,不过大多业务逻辑和持久化放在Domain Object里面,Business Logic只是简单封装部分业务逻辑以及控制事务、权限等,这样层次结构就变成Client->(Business Facade)->Business Logic->Domain Object->Data Access。

       它的优点是面向对象,Business Logic符合单一职责,不像在贫血模型里面那样包含所有的业务逻辑太过沉重。

       缺点是如何划分业务逻辑,什么样的逻辑应该放在Domain Object中,什么样的业务逻辑应该放在Business Logic中,这是很含糊的。即使划分好了业务逻辑,由于分散在Business Logic和Domain Object层中,不能更好的分模块开发。熟悉业务逻辑的开发人员需要渗透到Domain Logic中去,而在Domian Logic又包含了持久化,对于开发者来说这十分混乱。  其次,因为Business Logic要控制事务并且为上层提供一个统一的服务调用入口点,它就必须把在Domain Logic里实现的业务逻辑全部重新包装一遍,完全属于重复劳动。

受公司影响,都是充血的模型

实际上,我觉得mongoose已经把一些简单的模型行为都定义好了,什么增删改都有了,简单的应用够用了

一直贫血,从未充血过, 曾经努力地往面向领域转型,但随着系统地不断膨胀,最终又回到了贫血模型

在Node.js后端开发中,你可以选择使用贫血模型(Anemic Domain Model)或充血模型(Rich Domain Model)来组织业务逻辑。这两种模型各有优缺点。

贫血模型(Anemic Domain Model)

贫血模型将领域对象视为简单的数据容器,所有的业务逻辑都在服务层处理。这种方式的优点是简单直观,易于理解,适用于简单的应用。

示例代码:

// domain model
class User {
    constructor(name, email) {
        this.name = name;
        this.email = email;
    }
}

// service layer
class UserService {
    constructor() {
        this.users = [];
    }

    createUser(name, email) {
        const user = new User(name, email);
        this.users.push(user);
        return user;
    }

    getUsers() {
        return this.users;
    }
}

const userService = new UserService();
userService.createUser('Alice', 'alice@example.com');
console.log(userService.getUsers());

充血模型(Rich Domain Model)

充血模型将业务逻辑放在领域对象内部,使得这些对象更加智能。这种方法更符合面向对象的设计原则,适用于复杂的业务场景。

示例代码:

// rich domain model
class User {
    constructor(name, email) {
        this.name = name;
        this.email = email;
    }

    static create(name, email) {
        return new User(name, email);
    }

    getName() {
        return this.name;
    }

    getEmail() {
        return this.email;
    }
}

// repository to manage data access
class UserRepository {
    constructor() {
        this.users = [];
    }

    save(user) {
        this.users.push(user);
    }

    findAll() {
        return this.users;
    }
}

const userRepository = new UserRepository();
const user = User.create('Alice', 'alice@example.com');
userRepository.save(user);
console.log(userRepository.findAll());

总结

  • 贫血模型:适合简单的应用场景,业务逻辑集中在服务层。
  • 充血模型:适合复杂的应用场景,业务逻辑分散在各个领域对象中。

选择哪种模型取决于你的具体需求和项目规模。对于简单的应用,贫血模型可能更合适;而对于复杂的应用,充血模型更能体现其优势。

回到顶部