不解析,使用解析对象

  • 时间:
  • 浏览:
  • 来源:互联网

将面向对象的后端与外部系统集成的传统方式是通过数据传输对象 ,这些对象在外出之前先序列化为JSON,然后在返回时反序列化。 这种方法很流行,而且是错误的。 序列化部分应该由打印机代替,我在前面已经解释过。 这是我对反序列化的看法,应该通过猜测对象来完成。

米歇尔·贡德里(Michel Gondry)的《科学》(La science desrêves)(2006年)

假设有一个后端入口点,应该在库中注册一本新书,并以JSON格式到达:

{
  "title": "Object Thinking",
  "isbn: "0735619654",
  "author: "David West"
}

此外,还有一个类Library的对象,它希望将Book类型的对象赋予其方法register()

class Library {
  public void register(Book book) {
    // Create a new record in the database
  }
}

还可以说,类型Book有一个简单的方法isbn()

interface Book {
  String isbn();
}

现在,这里是HTTP入口点(我正在使用Takes和Cactoos ),该入口点接受POST multipart/form-data请求并将书注册到库中:

public class TkUpload implements Take {
  private final Library library;
  @Override
  public Response act(Request req) {
    String body = new RqPrint(
      new RqMtSmart(new RqMtBase(req)).single("book")
    ).printBody();
    JsonObject json = Json.createReader(
      new InputStreamOf(body)
    ).readObject();
    Book book = new BookDTO();
    book.setIsbn(json.getString("isbn"));
    library.register(book);
  }
}

这有什么问题? 好吧,几件事。

首先,它不可重用。 如果在其他地方需要类似的东西,则必须再次编写此HTTP处理和JSON解析。

其次,错误处理和验证也不可重复使用。 如果将其添加到上述方法中,则必须将其复制到各处。 当然,DTO可以封装它,但这不是DTO通常的用途。

第三,以上代码具有相当的程序性,并且具有大量的时间耦合 。

更好的设计是将此解析隐藏在新类JsonBook

class JsonBook implements Book {
  private final String json;
  JsonBook(String body) {
    this.json = body;
  }
  @Override
  public String isbn() {
    return Json.createReader(
      new InputStreamOf(body)
    ).readObject().getString("isbn");
  }
}

然后,RESTful入口点将如下所示:

public class TkUpload implements Take {
  private final Library library;
  @Override
  public Response act(Request req) {
    library.register(
      new JsonBook(
        new RqPrint(
          new RqMtSmart(new RqMtBase(req)).single("book")
        ).printBody()
      )
    );
  }
}

那不是更优雅吗?

下面是一些例子,从我的项目: RqUser从zerocracy /农场和RqUser从yegor256 / jare 。

从上面的示例可以看到,有时我们不能使用implements因为Java中的某些原语不是接口而是final类: String是一个“完美”的示例。 这就是为什么我必须这样做:

class RqUser implements Scalar<String> {
  @Override
  public String value() {
    // Parsing happens here and returns String
  }
}

但是除此之外,这些示例完美地说明了上面建议的“解析对象”的原理。

翻译自: https://www.javacodegeeks.com/2018/03/dont-parse-use-parsing-objects.html

本文链接http://hi.ngui.cc/a/11490.html