You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

咨询Domain Mapper模型的通用结构是否符合行业常规

嘿,你选Stack Overflow提问这个问题完全没问题!Code Review更偏向于对已有代码做优化评审,而你问的是Data Mappers模式的通用结构这类设计模式相关的问题,在Stack Overflow会得到更多关注和专业回复的~

Data Mappers模式的通用核心结构

其实Data Mappers并没有一个绝对“刻板到不能改”的通用结构,但行业里有一套被广泛认可的核心框架,我给你拆解下:

  • 实体类(Entity):这是你的纯业务模型,只专注于业务逻辑,完全不碰数据持久化的细节——比如一个User类,只有$id、$name、$email这些属性,以及changeEmail()这类业务方法,连数据库连接字符串是什么它都不需要知道。
  • 数据映射器类(Data Mapper):这就是负责“搭桥”的角色,专门处理实体和数据源(数据库、API、文件啥的)之间的转换。它通常会有这些核心方法:
    • findById(int $id): ?Entity:根据ID从数据源捞数据,然后把数据转换成对应的实体对象
    • insert(Entity $entity): void:把新的实体对象的数据写入数据源
    • update(Entity $entity): void:更新数据源里对应实体的数据
    • delete(Entity $entity): void:从数据源删除对应实体的数据
  • 数据源连接类(可选但常用):比如一个DatabaseConnection类,专门负责和数据库建立连接、执行基础的SQL操作,映射器类会依赖这个类来完成数据读写,这样映射器不用自己处理连接细节,更符合单一职责原则。

给你举个简单的PHP例子,方便你理解:

// 实体类:纯业务模型,和数据操作完全无关
class User {
    private int $id;
    private string $name;
    private string $email;

    public function __construct(int $id, string $name, string $email) {
        $this->id = $id;
        $this->name = $name;
        $this->email = $email;
    }

    // 业务方法:只处理业务逻辑,比如修改邮箱时做格式校验
    public function changeEmail(string $newEmail): void {
        if (!filter_var($newEmail, FILTER_VALIDATE_EMAIL)) {
            throw new InvalidArgumentException("无效的邮箱格式");
        }
        $this->email = $newEmail;
    }

    // 仅提供getter,让映射器能获取实体数据用于持久化
    public function getId(): int { return $this->id; }
    public function getName(): string { return $this->name; }
    public function getEmail(): string { return $this->email; }
}

// 数据映射器类:专门处理User实体和数据库的交互
class UserMapper {
    private PDO $db;

    public function __construct(PDO $db) {
        $this->db = $db;
    }

    public function findById(int $id): ?User {
        $stmt = $this->db->prepare("SELECT id, name, email FROM users WHERE id = ?");
        $stmt->execute([$id]);
        $data = $stmt->fetch(PDO::FETCH_ASSOC);

        if (!$data) {
            return null;
        }

        return new User($data['id'], $data['name'], $data['email']);
    }

    public function update(User $user): void {
        $stmt = $this->db->prepare("UPDATE users SET name = ?, email = ? WHERE id = ?");
        $stmt->execute([$user->getName(), $user->getEmail(), $user->getId()]);
    }
}

当然,实际项目里你可能会扩展这个结构,比如加**数据传输对象(DTO)来在映射器和数据源之间传递数据,或者加仓库类(Repository)**来封装多个映射器的操作,但核心的“实体和数据操作完全分离”这个原则是不变的。

内容的提问来源于stack exchange,提问作者Matthew M

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 06:56:19