DA03 Data source Layer

declair

Jihao Deng

Posted on August 19, 2020

DA03 Data source Layer

本篇主要讲数据层(Data source Layer),它有以下四个pattern:

  • Table Data Gateway
  • Row Data Gateway
  • Active Record
  • Mapper

Data source Layer的作用

为了让内存中运行的程序与数据库进行交互,其中一种方式是将SQL以字符串的方式存在程序中,再将它发送到数据库里,这样做会有很多问题:

  • 高耦合;
  • Developer需要同时掌握编写Domain Layer的语言和SQL语言;
  • 数据库也将以字符串的方式返回查询结果,这种结果需要进行处理,而这些事情并不该在Domain Layer中做。

为了解决这些问题,现在有四种pattern。

Table Data Gateway

An object that acts as a gateway to a database table. One instance handles all the rows in the table.

一个对象封装了对一个数据库表的访问

public class StudentGateway {
    public ResultSet findAll() {...}

    public ResultSet findById(int id) {...}

    public void addStudent(String firstName, String surname, ...) {...}

    public void deleteStudent(int id) {...}

    public void updateStudent(int id, String firstName, String surname, ...) {...}

    public ResultSet findBySurname(String surname) {...}
    ...
}
Enter fullscreen mode Exit fullscreen mode

Table Data Gateway的优缺点

Pros

  • 简单明了
  • 兼容Table Module

Cons

  • 与Domain Model不兼容,因为它不希望把对一张表的所有操作糅合在一起
  • Bad scalability,如果表改变,那么Gateway就需要做改变;如果有很多张表,那么也需要管理大量的Gateways

Row Data Gateway

An object that acts as a gateway to a single record in a data source.

一条记录对应一个对象

public class Student {
    private int id;
    private String firstName;
    private String surname;

    // getters and setters

    public void addStudent(String firstName, String surname, ...) {...}
    public void deleteStudent() {...}
    public void updateStudent(String firstName, String surname, ...) {...}

}
Enter fullscreen mode Exit fullscreen mode

对于查询操作,需要额外编写一个Finder类:

class StudentFinder {
    public List<Student> findAll() {...}
    public Student findById(int id) {...}
}
Enter fullscreen mode Exit fullscreen mode

Row Data Gateway的优缺点

Pros

  • 简单明了
  • 兼容Transaction Script

Cons

  • 与Domain Model不兼容
  • 修改数据库表需要同时修改大量代码

Active Record

An object that wraps a row in a database table or view, encapsulates the database access, and adds domain logic on that data.

与Row Data Gateway不同的是,Active Record的对象里还额外包含了domain logic方法。

public class Student {
    private int id;
    private String firstName;
    private String surname;

    // getters and setters

    public void addStudent(String firstName, String surname, ...) {...}
    public void deleteStudent() {...}
    public void updateStudent(String firstName, String surname, ...) {...}

    // the following methods implements domain logic
    public void getExemption() {...}
    public void addDependency() {...}
}
Enter fullscreen mode Exit fullscreen mode

与Row Data Gateway相同,对于查询操作,需要额外编写一个Finder类,或者在类中添加static finder方法。

Active Record的优缺点

Pros

  • High cohesion: 高内聚,因为将逻辑方法与一条记录放在了一个类中
  • 与transaction script兼容

Cons

  • 可重用性差
  • 修改数据库表需要同时修改大量代码

Data Mapper

A layer of Mappers that moves data between objects and a database while keeping them independent of each other and the mapper itself.

该pattern意在降低对象与数据库的依赖,mapper相当于一个个连接内存中的对象和数据库表的桥梁。

With Data Mapper the in-memory objects needn't know even that there's a database present; they need no SQL interface code, and certainly no knowledge of the database schema.

public class Student {
    private int id;
    private String firstName;
    private String surname;

    // getters and setters

    // the following methods implements domain logic
    public void getExemption() {...}
    public void addDependency() {...}
}

public class StudentMapper {
    public static List<Student> findAll() {...}
    public static Student findStudentById(int id) {...}
    public static void addStudent(String firstName, String surname, ...) {...}
    public static void deleteStudent() {...}
    public static void updateStudent(String firstName, String surname, ...) {...}
}
Enter fullscreen mode Exit fullscreen mode

Data Mapper的优缺点

Pros

  • 低耦合
  • 适合Domain Model,domain layer的代码以及数据库的可重用性高

Cons

  • 复杂,额外添加了一层layer,只适合在domain logic非常复杂的情况下使用(但实际上,我们一直都在用这种pattern写web项目)

选择合适的数据层pattern

  • Table data gateway: the domain is simple, and uses the table module pattern;
  • Row data gateway: the domain is simple, and uses the transcript script pattern and design-time type safety is desired. It should not be used if there is a high likelihood of the database schema changing.
  • Active Record: the domain logic is somewhat complicated. It should not be used if there is a high likelihood of the database schema changing.
  • Data Mapper: the domain logic is particularly complex, and should be used in conjunction with the domain model pattern. It should also be used if there is a good chance that either the data source layer is likely to change, or if the domain logic is likely to change without a change to the underlying data.
💖 💪 🙅 🚩
declair
Jihao Deng

Posted on August 19, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

DA09 Performance in EA
learning DA09 Performance in EA

November 15, 2020

DA03 Data source Layer
learning DA03 Data source Layer

August 19, 2020