

AWS 大型机现代化服务（托管运行时环境体验）不再向新客户开放。有关类似于 AWS 大型机现代化服务（托管运行时环境体验）的功能，请浏览 AWS 大型机现代化服务（自我管理体验）。现有客户可以继续正常使用该服务。有关更多信息，请参阅[AWS 大型机现代化可用性变更](https://docs.aws.amazon.com/m2/latest/userguide/mainframe-modernization-availability-change.html)。

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 大型机 AWS 转型中的数据简化器是什么
<a name="ba-shared-data"></a>

在大型机和中端系统（以下主题中称为 “传统” 系统）上，常用的编程语言（例如 COBOL PL/I 或 RPG）提供对内存的低级访问。这种访问侧重于通过本机类型（例如分区、打包或字母数字，也可能包括组或数组聚合）访问内存布局。

在给定程序中，通过类型化字段和直接访问字节（原始内存）来访问给定内存的两种方式共存。例如，COBOL 程序会将参数作为连续的字节集（LINKAGE）或以相同方式来自文件 read/write 的数据（记录）传递给调用者，同时使用在抄写本中组织的类型化字段来解释此类内存范围。

这种对内存的原始访问和结构化访问的组合、对精确的字节级内存布局的依赖以及遗留类型（例如分区或打包）是在 Java 编程环境中不容易实现的非本机特征。

作为将传统程序现代化为 Java 的大型机 AWS 转换解决方案的一部分，**Data Simplifier** 库为现代化的 Java 程序提供了此类结构，并以 Java 开发人员尽可能熟悉的方式公开这些结构（获取器/设置器、字节数组、基于类的字节数组）。数据简化器是从这些程序生成的现代化 Java 代码的核心依赖项。

为简单起见，以下大部分解释都基于 COBOL 结构，但您可以对两者使用相同的 API PL1 和 RPG 数据布局现代化，因为大多数概念都是相似的。

**Topics**
+ [主要的类](#ba-shared-data-main-classes)
+ [数据绑定和访问](#ba-shared-data-binding-access)
+ [所讨论的 Java 类型的 FQN](#ba-shared-data-fqn)

## 主要的类
<a name="ba-shared-data-main-classes"></a>

为了便于阅读，本文档使用了大型机 API 接口和类的 AWS 转换的 Java 简称。有关更多信息，请参阅 [所讨论的 Java 类型的 FQN](#ba-shared-data-fqn)。

### 低级别内存表示
<a name="ba-shared-data-main-classes-memory"></a>

 在最低级别上，内存（以快速、随机方式访问的连续字节范围）由 `Record` 接口表示。该接口本质上是固定大小字节数组的抽象。因此，它提供了能够访问或修改底层字节的 setter 和 getter。

### 结构化数据表示
<a name="ba-shared-data-main-classes-structured"></a>

要表示结构化数据，例如 COBOL DATA DIVISION 中的“01 data item”或“01 copybook”，则使用 `RecordEntity` 类的子类。它们通常不是手写的，而是由 Tr AWS ansform for 大型机现代化工具从相应的遗留结构中生成的。了解它们的主要结构和 API 也仍有用，可方便您了解现代化程序中的代码如何使用它们。就 COBOL 而言，该代码是从 PROCEDURE DIVISION 生成的 Java。

生成的代码使用 `RecordEntity` 子类表示每个“01 data item”；组成它的每个基本字段或聚合都表示为一个私有 Java 字段，采用树状结构进行组织（每个项都有一个父项，根项除外）。

为便于说明，以下是一个 COBOL 数据项示例，后面是相应的 Trans AWS form 为大型机生成的代码，用于对其进行现代化改造：

```
01 TST2.
 02 FILLER PIC X(4).
 02 F1     PIC 9(2) VALUE 42.
 02 FILLER PIC X.
 02        PIC 9(3) VALUE 123.
 02 F2     PIC X VALUE 'A'.
```

```
public class Tst2 extends RecordEntity {

	   private final Group root = new Group(getData()).named("TST2"); 
	   private final Filler filler = new Filler(root,new AlphanumericType(4));
	   private final Elementary f1 = new Elementary(root,new ZonedType(2, 0, false),new BigDecimal("42")).named("F1");
	   private final Filler filler1 = new Filler(root,new AlphanumericType(1));
	   private final Filler filler2 = new Filler(root,new ZonedType(3, 0, false),new BigDecimal("123"));
	   private final Elementary f2 = new Elementary(root,new AlphanumericType(1),"A").named("F2");
	

	   /**
	    * Instantiate a new Tst2 with a default record.
   	 * @param configuration the configuration
   	 */
	   public Tst2(Configuration configuration) {
		      super(configuration);
		      setupRoot(root);
	   }
	   /**
	    * Instantiate a new Tst2 bound to the provided record.
	    * @param configuration the configuration
	    * @param record the existing record to bind
	    */
	   public Tst2(Configuration configuration, RecordAdaptable record) {
		      super(configuration);
		      setupRoot(root, record);
	   }

	   /**
	    * Gets the reference for attribute f1.
	    * @return the f1 attribute reference
	    */
	   public ElementaryRangeReference getF1Reference() {
		      return f1.getReference();
	   }

	   /* *
	    * Getter for f1 attribute.
	    * @return f1 attribute
	    */
	   public int getF1() {
		      return f1.getValue();
	   }

	   /**
	    * Setter for f1 attribute.
	    * @param f1 the new value of f1
	    */
   	public void setF1(int f1) {
		      this.f1.setValue(f1);
	   }
	   /**
	    * Gets the reference for attribute f2.
	    * @return the f2 attribute reference
	    */
	   public ElementaryRangeReference getF2Reference() {
		      return f2.getReference();
	   }

	   /**
	    * Getter for f2 attribute.
	    * @return f2 attribute
	    */
	   public String getF2() {
		      return f2.getValue();
	   }

	   /**
	    * Setter for f2 attribute.
	    * @param f2 the new value of f2
	    */
	   public void setF2(String f2) {
		      this.f2.setValue(f2);
	   }
}
```

#### 基本字段
<a name="ba-shared-data-main-classes-structured-elementary"></a>

类 `Elementary`（或者 `Filler`，如果未命名）的字段代表遗留数据结构的“叶子”。它们与底层字节的连续跨度（“范围”）相关联，并且通常具有表示如何解释和修改这些字节的类型（可能已参数化）（通过分别对字节数组 “解码” 和 “编码” 一个值 from/to ）。

所有基本类型都是 `RangeType` 的子类。常见的类型如下：


| COBOL 类型 | 数据简化器类型 | 
| --- | --- | 
|  `PIC X(n)`  |  `AlphanumericType`  | 
|  `PIC 9(n)`  |  `ZonedType`  | 
|  `PIC 9(n) COMP-3`  |  `PackedType`  | 
|  `PIC 9(n) COMP-5`  |  `BinaryType`  | 

#### 聚合字段
<a name="ba-shared-data-main-classes-structured-aggregate"></a>

聚合字段组织其内容（其他聚合或基本字段）的内存布局，本身没有基本类型。

`Group` 字段表示内存中的连续字段。其中包含的每个字段在内存中的布局顺序相同，第一个字段位于偏移 `0`（相对于组字段在内存中的位置），第二个字段处于偏移 `0 + (size in bytes of first field)`，依此类推。它们用于表示同一包含字段下的 COBOL 字段序列。

`Union` 字段表示访问同一内存的多个字段。其中包含的每个字段都布局在偏移 `0`（相对于内存中的 Union 字段位置）。例如，它们用于表示 COBOL“REDEFINES”结构（第一个 Union 子项是重新定义的数据项，第二个子项是对第一个的重定义，以此类推）。

数组字段（`Repetition` 的子类）表示其子字段（无论本身是聚合还是基本项目）在内存中的布局重复。它们在内存中布局了给定数量的此类子布局，每个字段都位于偏移 `index * (size in bytes of child)`，用于表示 COBOL“OCCURS”结构。

#### 基本数据类型
<a name="ba-shared-data-main-classes-structured-primitive"></a>

在某些现代化案例中，“基本数据类型”也可以单独用来表示“根”数据项。它们的使用方法与 `RecordEntity` 非常相似，但并非来自于它，也不是基于生成的代码。相反，它们由大型机运行时的 Tr AWS ansform 作为接口的子类直接提供。`Primitive`提供的此类的示例包括 `Alphanumeric` 或 `ZonedDecimal`。

## 数据绑定和访问
<a name="ba-shared-data-binding-access"></a>

结构化数据和底层数据之间的关联可以通过多种方式实现。

用于实现关联的一个重要接口是 `RecordAdaptable`，该接口用于获取提供 `RecordAdaptable` 底层数据的“可写视图”的 `Record`。如下所示，多个类实现了 `RecordAdaptable`。相反，大型机的 Tr AWS ansform APIs 和操作低级内存（例如程序参数、文件 I/O 记录、CICS 通信区域、分配的内存...）的代码通常会期望使用`RecordAdaptable`作为该内存的句柄。

在 COBOL 现代化案例中，大多数数据项都与内存相关联，内存在相应程序执行的生命周期内固定。为此，`RecordEntity` 子类在生成的父对象（程序上下文）中实例化一次，并根据 `RecordEntity` 字节大小负责实例化其底层 `Record`。

在其他 COBOL 情况下，例如将 LINKAGE 元素与程序参数相关联，或者对 SET ADDRESS OF 结构进行现代化，必须将 `RecordEntity` 实例与提供的 `RecordAdaptable` 关联。为此，可使用两种机制：
+ 如果 `RecordEntity` 实例已经存在，则可以使用 `RecordEntity.bind(RecordAdaptable)` 方法（继承自 `Bindable`）使此实例“指向”此 `RecordAdaptable`。然后，在 `RecordEntity` 上调用的任何 getter 或 setter 都将由底层 `RecordAdaptable` 字节支持（字节读取或写入）。
+ 如果要将 `RecordEntity` 实例化，生成的接受 `RecordAdaptable` 的结构可用。

相反，可以访问结构化数据当前绑定的 `Record`。为此，`RecordEntity` 实现了 `RecordAdaptable`，因此可以在任何此类实例上调用 `getRecord()`。

最后，许多 COBOL 或 CICS 动词都需要访问单个字段来进行读写。`RangeReference` 类用于表示此类访问。它的实例可以从 `RecordEntity` 生成的 `getXXXReference()` 方法（`XXX` 即访问的字段）中获取，然后传递给运行时方法。`RangeReference` 通常用于访问整个 `RecordEntity` 或`Group`，而其子类 `ElementaryRangeReference` 表示对 `Elementary` 字段的访问。

请注意，上面的大多数观察结果都适用于`Primitive`子类，因为它们努力实现与大型机运行时Tr AWS ansform提供的行为相似（而不是生成的代码）。`RecordEntity`为此，`Primitive` 的所有子类实现 `RecordAdaptable`、`ElementaryRangeReference` 和 `Bindable`，以便可以代替 `RecordEntity` 子类和基本字段。

## 所讨论的 Java 类型的 FQN
<a name="ba-shared-data-fqn"></a>

下表显示了本节中所讨论 Java 类型的完全限定名称。


| 短名称 | 完全限定名称 | 
| --- | --- | 
|  `Alphanumeric`  |  `com.netfective.bluage.gapwalk.datasimplifier.elementary.Alphanumeric`  | 
|  `AlphanumericType`  |  `com.netfective.bluage.gapwalk.datasimplifier.metadata.type.AlphanumericType`  | 
|  `BinaryType`  |  `com.netfective.bluage.gapwalk.datasimplifier.metadata.type.BinaryType`  | 
|  `Bindable`  |  `com.netfective.bluage.gapwalk.datasimplifier.data.Bindable`  | 
|  `Elementary`  |  `com.netfective.bluage.gapwalk.datasimplifier.data.structure.Elementary`  | 
|  `ElementaryRangeReference`  |  `com.netfective.bluage.gapwalk.datasimplifier.entity.ElementaryRangeReference`  | 
|  `Filler`  |  `com.netfective.bluage.gapwalk.datasimplifier.data.structure.Filler`  | 
|  `Group`  |  `com.netfective.bluage.gapwalk.datasimplifier.data.structure.Group`  | 
|  `PackedType`  |  `com.netfective.bluage.gapwalk.datasimplifier.metadata.type.PackedType`  | 
|  `Primitive`  |  `com.netfective.bluage.gapwalk.datasimplifier.elementary.Primitive`  | 
|  `RangeReference`  |  `com.netfective.bluage.gapwalk.datasimplifier.entity.RangeReference`  | 
|  `RangeType`  |  `com.netfective.bluage.gapwalk.datasimplifier.metadata.type.RangeType`  | 
|  `Record`  |  `com.netfective.bluage.gapwalk.datasimplifier.data.Record`  | 
|  `RecordAdaptable`  |  `com.netfective.bluage.gapwalk.datasimplifier.data.RecordAdaptable`  | 
|  `RecordEntity`  |  `com.netfective.bluage.gapwalk.datasimplifier.entity.RecordEntity`  | 
|  `Repetition`  |  `com.netfective.bluage.gapwalk.datasimplifier.data.structure.Repetition`  | 
|  `Union`  |  `com.netfective.bluage.gapwalk.datasimplifier.data.structure.Union`  | 
|  `ZonedDecimal`  |  `com.netfective.bluage.gapwalk.datasimplifier.elementary.ZonedDecimal`  | 
|  `ZonedType`  |  `com.netfective.bluage.gapwalk.datasimplifier.metadata.type.ZonedType`  | 