迹忆客 专注技术分享

当前位置:主页 > 学无止境 >

从 UML 生成 Dart 代码——代码生成

作者:迹忆客 最近更新:2022/08/16 浏览次数:

这是这篇从 UML 生成 Dart 代码 - 类图文章的附带文章,我们在 NClass UML 工具中添加了 Dart 专用类图。 请快速阅读这篇文章,它概述了我们在这里所做的事情以及在哪里可以找到资源等。

对,现在我们在 NClass 工具中有了 Dart 类图,是时候看看如何从它们生成 Dart 代码了。 我们使用的 NClass 项目名为 Generation,可以在这里找到。

打开项目,选择 Simple class diagram 并从 Diagram 顶层菜单项中选择 Generate Code 打开 Code Generation 对话框

Dart 代码生成对话框

如果我们想从不同的项目生成代码,我们可以选择项目路径,在左侧下拉菜单中也选择了“Dart”,因为我们正在为 Dart 生成代码。导入列表允许你添加任何你想要的代码导入,这些将被添加到每个生成的 Dart 文件的顶部。

在右侧,我们可以选择我们需要的解决方案文件的类型,在我们的例子中选择了 Dart,这将为我们的项目生成一个骨架 pubspec.yaml 文件。其他设置是是否使用制表符进行缩进,用未实现的异常填充方法主体(在 Darts 情况下,这实际上是“UnimplementedError()”异常,我们将看到)。最终选择在项目之后命名生成代码的文件夹(在文档中)。

当我们的选择完成后,按下 Generate 按钮,代码生成将出现一系列进度消息。请注意,无论当前打开的是什么,都会为项目中的所有 Dart 类图生成代码。

简单类图包含一个名为 Shoe 的简单类

Dart 简单 Shoe 类

可以看出,这个类包含一个默认构造函数、一个命名构造函数和一个工厂构造函数、公共和私有成员、公共和私有实例以及静态成员和属性(getter 和 setter)。 请注意,这些属性保留了在所有 NClass 类图中使用的 UML 表示法样式。

这会生成以下 Dart 代码

import 'dart:io';
class Shoe
{
 int _privateField;
 int publicField;
Shoe()
 {
  throw new UnimplementedError();
 }
factory Shoe.IsFactory()
 {
  throw new UnimplementedError();
 }
Shoe.withSize()
 {
  throw new UnimplementedError();
 }
int _size;
 int get Size => _size;
bool willFit(int footSize )
 {
  throw new UnimplementedError();
 }
int _lacelength;
 int get LaceLength => _lacelength;
 set  LaceLength(int value) => _lacelength = value;
void _privateMethod()
 {
  throw new UnimplementedError();
 }
static void StaticMethod()
 {
  throw new UnimplementedError();
 }
}

可以看出,构造函数被适当地声明,私有成员以“_”为前缀,并且 setter 和 getter 已被转换为 Dart 风格的语法。 代码生成对话框中的导入列表位于以类命名的文件的顶部,即 shoe.dart。 方法主体已扩展并填充了“代码生成”对话框中选择的“UnimplementedError()”

为了完整起见,这里还有更多工作要做,请参阅下面的“进一步工作”部分。

现在让我们看一个更复杂的例子,展示继承和接口/混合处理。 复杂类图包含一个基于继承的类图 -

Flutter Dart 复杂类图

它包含一个抽象基类 Bird、3 个派生类 Eagle、Emu 和 Hawk、2 个混合类 Flyer 和非 Flyer 以及两个接口类 NZBirds 和 FunnyBirds。 请注意,尽管被注释为 mixin 的 mixin 类在图中显示为接口类,因为它们旨在用作接口并因此实现为接口。 Dart 在这方面与 UML 不同,因为 mixin 既可以充当类也可以充当接口。

代码生成生成 8 个 dart 文件,从 Bird 开始

import 'dart:io';
abstract class Bird
{
 bool hasWings();
}

注意 hasWings 的主体没有实现,因为该类是抽象的。 Eagle如下图,Hawk也是一样

import 'dart:io';
import 'bird.dart';
import 'flyer.dart';
class Eagle extends Bird with Flyer
{
 @override
 bool hasWings()
 {
  throw new UnimplementedError();
 }
}

注意导入、抽象基类 Bird 的扩展和 mixin Flyer 的包含。 还要注意 hasWings 方法上的“@override”注解。

Mixin类Flyer如下,NonFlyer同理

import 'dart:io';
mixin Flyer
{
 bool canFly()
 {
  throw new UnimplementedError();
 }
}

请注意,“class”文本现在已替换为“mixin”,并且 CanFly 的主体现在已实现。

接口类NZBirds如下,FunnyBirds 同理

import 'dart:io';
abstract class NZBirds
{
}

请注意,Dart 没有这样的接口类,因此该类已被声明为抽象类,并且将针对没有主体等的成员生成此类。

最后我们来到 Emu 类,这显示了使用 NonFlyer mixin 和上面显示的两个接口类从 Bird 继承

import 'dart:io';
import 'bird.dart';
import 'nonflyer.dart';
import 'nzbirds.dart';
import 'funnybirds.dart';
class Emu extends Bird with NonFlyer implements NZBirds, FunnyBirds
{
 bool hasWings()
 {
  throw new UnimplementedError();
 }
}

请注意,Emu 类的代码扩展了 Bird,“带有”NonFlyer mixin 并实现了两个接口类。在这个例子中,hasWings 方法没有“@override”注解,这个注解不是自动生成的,它必须在创建成员时添加,或者像在普通 Dart 代码中一样由用户使用 NClass 成员编辑对话框添加。

所以我们可以看到,使用 NClass UML 工具可以从专门的 Dart 类图中生成基本的 Dart 代码。


进一步的工作

为了更完整的代码生成、对后期/最终变量的支持、在构造函数参数中使用“this”注解来初始化最终变量、更好地支持类图上的包实体和更完整的导入生成,还有更多工作要做 pubspec.yaml 生成。当最初的工作被合并时,我打算将这些作为未来的问题添加到 NClass 项目中。

最后的想法

NClass 还具有加载现有 C# 程序集并使用反射从它派生 UML 图的工具,这相当漂亮。这在 Dart 中应该是可能的。以 Dart 程序为例,我们应该能够从中生成一个内核文件(.dill),然后使用内核 ast 库从中获取 AST,并从中生成一个 UML 图,可能在第一个实例中使用 Plant UML 表示法。使用 Dart 源代码和 Dart 分析器包也可以使用类似的方法,我现在还没有真正进一步研究这个,但听起来很有趣并且可行。

转载请发邮件至 1244347461@qq.com 进行申请,经作者同意之后,转载请以链接形式注明出处

本文地址:

相关文章

从 UML 类图生成 Dart 代码

发布时间:2022/08/16 浏览次数:141 分类:学无止境

我最近看到的一些文章展示了如何将 Dart 代码映射到 UML,甚至如何将 Dart 代码逆向工程到 UML(使用 Plant UML 表示法),但是发现没有一篇文章展示了如何从 UML 模型自动生成 Dart 代码.

扫一扫阅读全部技术教程

社交账号
  • https://www.github.com/onmpw
  • qq:1244347461

最新推荐

教程更新

热门标签

扫码一下
查看教程更方便