@ablestack/rdo 中文文档教程

发布于 4年前 浏览 23 项目主页 更新于 3年前

@ablestack/rdo

Summary

这是来自 reactive-domain-objects 库的包。

Overview

reactive-domain-objects 库智能地将任何 JSON 数据源与丰富的可观察域模型同步,提供从有状态对象的命令式编程模型到可观察对象、数据流和反应式用户界面的反应式编程模型

一个主要用例是将 GraphQL 客户端库(例如 ApolloGraphQL)连接到响应式客户端库(例如 React) 与 Observables(例如 MobX)。

请参阅下面的库介绍,以及完整技术/使用文档所有功能、配置选项和其他使用示例的详细说明。

The Problems Being Solved

正在解决的问题主要围绕在 TypeScript/JavaScript 客户端应用程序中消费和使用 JSON 数据:

  • 封装问题:大多数现代状态管理框架都依赖于纯 JavaScript 对象树。 这使得(数据、逻辑和行为的)封装变得困难,进而使管理大型代码库或复杂业务领域的复杂性变得更具挑战性

  • 非规范化困难:当直接使用纯 JavaScript 树时任何非平凡的复杂性、非规范化(和相应的规范化)通常都是有效的图遍历所必需的。 这增加了额外的复杂性和维护要求

  • 外部数据同步:许多客户端 UI 框架(例如 React)依赖于状态数据的引用相等性。 从外部数据源(包括 REST 和 GraphQL)返回的结果永远不会引用相等,即使它们的结构和值实际上相同。 大量记忆代码,或性能不佳

Key Features

  • Automatic synchronization of Reactive Domain Object Graphs with an external data-source
  • Automatic Change tracking, of external data-sources, with Reactive Domain Object Nodes only being updated only where changes are detected. When combined with Observable properties, this is a very powerful feature that reduces or eliminates the need for memoization code in dependent UI code
  • Convention, Configuration, or Code options for specifying the construction of Reactive Domain Object Graphs
  • Automatic Creation of Observable Domain Model Objects, (base on configuration settings)
  • Emits Node Change Events, which can be subscribed to via the GraphSynchronizer object
  • Rdo Synchronization Lifecycle Hooks, which can be implemented via interfaces
  • Performance Optimized, with sub 0.3 millisecond synchronizations for a medium sized graph (as measured on a 2015 quad-core laptop. Performanc test available for local performance verification)
  • One way data flow paradigm: Actions --> External Data Source --> State
  • Custom Collection Types, to support easy graph traversal, and reduce the need for denormalization of data

Installation

    // npm
    npm i @ablestack/rdo, @ablestack/rdo-apollo-mobx-connector --save

    // yarn
    yarn add @ablestack/rdo, @ablestack/rdo-apollo-mobx-connector

Abridge Usage Example

// DEFINE REACTIVE DOMAIN GRAPH
class FooSimpleDomainGraph {
  public bar = new BarRDO(); //*1
}

export class BarRDO {
  public id: string = '';
  public name: string = '';
}

// INSTANTIATE DOMAIN RDO AND GRAPH SYNCHRONIZER
const fooSimpleRDO = new FooDomainGraphSimple();
const graphSynchronizer = new GraphSynchronizer(/* Config Options Here */);

// SYNC
graphSynchronizer.smartSync({ rootRdo: fooSimpleRDO, rootSourceNode: { bar: { id: 'bar-1', name: 'Original Name' } } });

// Make any changes to the source data

// RESYNC
graphSynchronizer.smartSync({ rootRdo: fooSimpleRDO, rootSourceNode: { bar: { id: 'bar-1', name: 'New Name' } } });

Full Documentation

  • See Full Documentation for a detailed description of all the functionality, configuration options, and additional usage examples.

Definitions

Reactive Domain Object

的结果 响应域对象 (RDO) 是满足以下条件的任何对象:

  1. Contains state, and optionally behavior and logic, relating a discrete entity in a program domain
  2. Internal state is automatically synchronized with changes in an external data-source
  3. Action methods are provided for all acceptable state mutations
  4. Follows a one-way data-flow paradigm, from: Action-Method --> External Data Source --> Internal-State (though synchronization)
  5. Observable Public Properties (optional but recommended)
  6. Child nodes exposed as Maps for efficient graph traversal (optional but recommended)

Notes

Known Issues & Limitations

  • Source & Target Structural Similarity. While field names can be adjusted, by configuration, the overall 'shape' and nesting structure of the graph must match between the source and target graphs. This library does not, yet, have the capability of automatically manipulating the shape of a graph during the synchronization process
  • Array and Set collections types in RDOs are more processing intensive. It is suggested that they are avoided for collections that may contain a large number of elements (100+)

Disclaimers

此代码最初是为在单个商业项目中使用而开发的。 它被共享以防对其他人有用,并作为对开发社区和已经存在的优秀工具和库的贡献。

Refinements and Enhancements Needed

  • Open to suggestions
  • Find a clever way to provide a default mechanism to instantiate Domain Objects without the need for user configuration to provide these. Will probably require some kind of TypeScript reflection, as in 'empty domain collection' scenarios, an instance will not be available, and nor will type runtime type information
  • Provide decorators that can be applied to the Domain Types to perform useful functions in lieu of configuration options, such as 'ignore'

Companion Libraries

该库是 AbleStack 下一系列配套工具和库的一部分。 所有这些库都有一个共同的目标:

者快速且经济地构建大创意

为了实现这些目标,应用了以下原则:

  • Selectively leverage existing open source tools and libraries, where, high quality, open source tools and libraries where possible
  • Curate usage examples, and guidance where available, and create where not available
  • Prioritize technology choices that embrace open source
  • TypeScript over C#, and Node over .Net an example of this
  • Avoid technology choices that could result in hosting vendor lock-in
  • ApolloGraphQL over AWS Amplify is an example of this
  • Automate wherever possible, from development, through testing, to deployment, monitoring, and maintenance
  • Codegen from strongly types schemas is a good example of this.
  • Where needed, develop high quality, open source tools and libraries to augment and automate existing open source tooling and libraries

Alternative Solutions

帮助小团队和独立开发 解决一些非常具体的用例,可能并不适合所有人。 在做出选择之前,绝对值得检查这些替代解决方案:

  • MobX-state-tree 在很多方面都类似于这个图书馆。 reactive-domain-objects 旨在解决类似的问题,但不那么自以为是,不那么复杂,但也不那么复杂。 对于更高级的功能和更自以为是的解决方案,MobX-state-tree 绝对值得一试

  • Vanilla MobXreactive-domain-objects 的许多好处来自于与出色的 MobX 库的集成。 对于小型甚至中型解决方案,单独使用 MobX 也可以达到相同的结果。 reactive-domain-objects 提供的主要附加好处是自动将数据与外部数据源同步。 该任务变得比添加另一个依赖项或学习另一个库更复杂或令人厌烦的点是在混合中获得 reactive-domain-objects 的正确点

Instructions

查看相关的 reactive-domain-objects github repo 用于使用和配置信息。

@ablestack/rdo

Summary

This is a package from the reactive-domain-objects Library.

Overview

The reactive-domain-objects library intelligently synchronizes any source of JSON data with rich observable Domain Models, providing a bridge from an Imperative programming model of stateful objects to a Reactive programming model of observables, data streams, and reactive user interfaces.

A primary use case is connecting GraphQL client libraries (such as ApolloGraphQL) to reactive client libraries (such as React) with Observables (such as MobX).

See below for an introduction to the library, and Full Technical/Usage Documentation for a detailed description of all the functionality, configuration options, and additional usage examples.

The Problems Being Solved

The problems being solved primarily revolve around consuming and using JSON data in TypeScript/JavaScript client applications:

  • The Encapsulation Problem: Most modern state management frameworks rely on plain JavaScript object trees. This makes encapsulation (of data, logic, and behavior) difficult which, in turn, makes managing complexity in large codebases or complex business domains much more challenging

  • The Denormalization Difficulty: When working directly with plain JavaScript trees of any non-trivial complexity, denormalization (and corresponding normalization) is usually required for efficient graph traversal. This adds additional complexity and maintenance requirements

  • External Data Sync: Many client UI frameworks, such as React, rely on referential equality of state data. Results returned from external data sources, including REST and GraphQL, will never be referentially equal, even if their structures and values are actually the same. Extensive memoization code, or poor performance result

Key Features

  • Automatic synchronization of Reactive Domain Object Graphs with an external data-source
  • Automatic Change tracking, of external data-sources, with Reactive Domain Object Nodes only being updated only where changes are detected. When combined with Observable properties, this is a very powerful feature that reduces or eliminates the need for memoization code in dependent UI code
  • Convention, Configuration, or Code options for specifying the construction of Reactive Domain Object Graphs
  • Automatic Creation of Observable Domain Model Objects, (base on configuration settings)
  • Emits Node Change Events, which can be subscribed to via the GraphSynchronizer object
  • Rdo Synchronization Lifecycle Hooks, which can be implemented via interfaces
  • Performance Optimized, with sub 0.3 millisecond synchronizations for a medium sized graph (as measured on a 2015 quad-core laptop. Performanc test available for local performance verification)
  • One way data flow paradigm: Actions --> External Data Source --> State
  • Custom Collection Types, to support easy graph traversal, and reduce the need for denormalization of data

Installation

    // npm
    npm i @ablestack/rdo, @ablestack/rdo-apollo-mobx-connector --save

    // yarn
    yarn add @ablestack/rdo, @ablestack/rdo-apollo-mobx-connector

Abridge Usage Example

// DEFINE REACTIVE DOMAIN GRAPH
class FooSimpleDomainGraph {
  public bar = new BarRDO(); //*1
}

export class BarRDO {
  public id: string = '';
  public name: string = '';
}

// INSTANTIATE DOMAIN RDO AND GRAPH SYNCHRONIZER
const fooSimpleRDO = new FooDomainGraphSimple();
const graphSynchronizer = new GraphSynchronizer(/* Config Options Here */);

// SYNC
graphSynchronizer.smartSync({ rootRdo: fooSimpleRDO, rootSourceNode: { bar: { id: 'bar-1', name: 'Original Name' } } });

// Make any changes to the source data

// RESYNC
graphSynchronizer.smartSync({ rootRdo: fooSimpleRDO, rootSourceNode: { bar: { id: 'bar-1', name: 'New Name' } } });

Full Documentation

  • See Full Documentation for a detailed description of all the functionality, configuration options, and additional usage examples.

Definitions

Reactive Domain Object

A Reactive Domain Object (RDO) is any object which satisfies the following conditions:

  1. Contains state, and optionally behavior and logic, relating a discrete entity in a program domain
  2. Internal state is automatically synchronized with changes in an external data-source
  3. Action methods are provided for all acceptable state mutations
  4. Follows a one-way data-flow paradigm, from: Action-Method --> External Data Source --> Internal-State (though synchronization)
  5. Observable Public Properties (optional but recommended)
  6. Child nodes exposed as Maps for efficient graph traversal (optional but recommended)

Notes

Known Issues & Limitations

  • Source & Target Structural Similarity. While field names can be adjusted, by configuration, the overall 'shape' and nesting structure of the graph must match between the source and target graphs. This library does not, yet, have the capability of automatically manipulating the shape of a graph during the synchronization process
  • Array and Set collections types in RDOs are more processing intensive. It is suggested that they are avoided for collections that may contain a large number of elements (100+)

Disclaimers

This code was initially developed for use in a single commercial project. It is being shared in case useful to others, and as a contribution to the development community and the great tools and libraries that already exist.

Refinements and Enhancements Needed

  • Open to suggestions
  • Find a clever way to provide a default mechanism to instantiate Domain Objects without the need for user configuration to provide these. Will probably require some kind of TypeScript reflection, as in 'empty domain collection' scenarios, an instance will not be available, and nor will type runtime type information
  • Provide decorators that can be applied to the Domain Types to perform useful functions in lieu of configuration options, such as 'ignore'

Companion Libraries

This library is part of a collection of companion tools and libraries under the AbleStack umbrella. All of these libraries share the common goal:

Helping small teams and solo-developers build big ideas rapidly and affordably

To achieve these goals, the following principles are applied:

  • Selectively leverage existing open source tools and libraries, where, high quality, open source tools and libraries where possible
  • Curate usage examples, and guidance where available, and create where not available
  • Prioritize technology choices that embrace open source
  • TypeScript over C#, and Node over .Net an example of this
  • Avoid technology choices that could result in hosting vendor lock-in
  • ApolloGraphQL over AWS Amplify is an example of this
  • Automate wherever possible, from development, through testing, to deployment, monitoring, and maintenance
  • Codegen from strongly types schemas is a good example of this.
  • Where needed, develop high quality, open source tools and libraries to augment and automate existing open source tooling and libraries

Alternative Solutions

While this library solves several challenges relating to client-side JavaScript development, it was developed to solve some very specific use cases, and might not be the right solution for everyone. It is definitely worth checkout out these alternative solutions before making your choice:

  • MobX-state-tree is similar in many respects to this library. reactive-domain-objects is designed to solve similar problems, but is less opinionated, less complicated, but also less sophisticated. For more advanced features and a more opinionated solution, MobX-state-tree is definitely worth checking out

  • Vanilla MobX. Many of the benefits reactive-domain-objects come from the integration with the great MobX library. For small and even mid-sized solutions, the same result can be achieved with MobX alone. The primary added benefit that reactive-domain-objects provides is automating the synchronization of data with external data sources. The point at which that task becomes more complex or tiresome than adding another dependency, or learning another library, is the right point at which to get reactive-domain-objects in the mix

Instructions

See the associated reactive-domain-objects github repo for usage and configuration information.

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文