[Translation] DSL and model-driven development best practices (4/4)

Source: Internet
Author: User

I will not translate the rest, but I am tired. It is also mixed with my understanding.

3. Processing Model

Parser vs code generation (unrated)
Generally, everyone tends to generate code. In fact, parsing is also an available option. After we complete our metadata model, the parser reads the metadata of this metadata model and can query or traverse the model, it can be directly computed for mutual processing and UI rendering.
Weigh resolution and code generation. Advantages of code generation:
1. It is simpler. We can check the generated code. In addition, the templates used for generating the code are extracted from the original handwritten code abstraction.
2. Easier debugging than Parsing
3. The Code extension method is more powerful and customizable. You can flexibly develop more powerful functions as needed, which is more effective than the parser.
4. It can be any target language or platform directly, because the generated target language code is controlled by the template, we only need to customize templates in different languages. If the target language supports other platforms, this method is also supported, and the parser method must run directly on the target platform.
5. Use the code generation method to make the MD * mode more thorough. Directly model-driven business and Driver Interface
Advantages of parsing:
1. Modifying the model does not require re-generation, re-compilation, re-test, or re-deployment. This significantly shortens the cycle.
2. The entire system is based on the model, and can even directly modify our model in the running system to make the modification take effect immediately (such as some online SaaS systems ).
3. In some cases, the parser and model are easier than generating code.
The parsing and code generation methods can also be combined to directly generate some model data in XML format, which is then parsed by 3gl language, such as Java parser, to drive the entire system operation. In theory, another method is also feasible. Code is generated directly in the parser to improve performance.

Independent model check mechanism
The metadata model is not necessarily correct, but contains a large amount of user input. Model constraints are mandatory and must be processed throughout the Model. constraints not only determine whether an error exists, but also indicate specific error information to the user. the more models and constraints, the more errors the user may encounter, but this ensures the correctness of the target system. Check constraints as much as possible!
Constraints should be checked as early as possible during model processing and cannot be put into the code generation stage. This will make the template too complex and inefficient at reuse.If you have different language templates, you also need different check implementations. If there is a model problem, you should not allow code generation. Otherwise, it will only cause more problems.
Different constraints must be checked for different stages and parts of the Model during model processing.For example, you need to check after conversion, while you need to check when saving partitions, after some user input, you need to check after you perform some operations on the model.
During the model improvement process, check at each level to prevent cascade impact during the modification process. In addition, make sure that all points at each level are checked, it is only possible to check the correct input from the upper level.But the user's input is not credible.
The inspection result information cannot be divided into levels, such as errors and warnings. If an error occurs, the next step cannot be performed..

Do not modify the generated code
Even if the model generates code, it is necessary to write code in most cases. Therefore, we need to combine the code written by hand with the generated code, so that we cannot overwrite the code written by hand every time. most tools provide so-called protected areas where you can insert your handwritten code to protect them from being overwritten.
This also has some problems. Generating code is not a one-time task. When modification and improvement lead to a lot of "sediment" in your generated code, it is often necessary to re-generate the code to clean these "sediment". If there is no such thing as a protected area, you can directly delete all the generated code and re-generate it.
Use the extension method to add extension points to the generated code, use the delegate, interface, # include method, or use the reflection and AOP mode, some languages provide partial classification (such as C #), so that the generated code file can be separated from the handwritten extended code file.. This method also has disadvantages. If you modify the model to generate different code, the manually modified code will not be automatically restructured (requires practical verification ), in addition, this will increase the implementation of the Code and the Compilation Time.
As tools continue to improve, there may be more feasible methods, but until now, the method for adding extensions is the least problematic.

Control handwriting code
The generator generates abstract classes for some model elements. Developers are expected to implement the abstract classes and comply with naming conventions. But if we only generate them, how can we prompt developers to implement their own code?
If a specific implementation class is called or an abstract method is called, a compilation error occurs during compilation. Developers implement their own code based on different errors, but this is not obvious, because developers also need to troubleshoot the error type.
There are two ways to solve this problem:
1.Generate constraints and checks on the generated code. The IDE can call the evaluation code. If an error occurs, the message is reported to the developer. The error will disappear only when the code is implemented in the specified method..
2.Sometimes the generated code is not executed, and the IDE calls the missing part directly.For example, if you need to manually write a generated subclass, we can generate the following sentence: If (false) {generatedbaseclass x = new manualsubclass ()}.

Follow the generated code
Do not discard the generated code.When integrating with the generated code, you will have to look at the generated code, understand it to a certain extent, and even debug it in some cases. For this reason, make sure that the generated code document specifications, naming conventions, and code indentation. In fact, these can be easily implemented in your template file. In addition, you can write the required information in the generated code for later viewing.
Make the generated code conform to the same standards as the handwritten code.
In some very mature environments, you can generate 100% of the Code, instead of writing the code to extend the implementation. In this case, what we call here is not applicable.

Ensure that the generated code does not deviate from the Model
In many cases, some constraints need to be implemented to verify the correctness of some attributes. To ensure that model data is saved by the Code, use the following two methods:
1.The generated code cannot violate the model commitment.For example, you must use dependency injection to provide reasonable object references instead of exposing the factory to allow components to search for and use other components (directly create dependencies.
2. Use a Structure Analysis Tool (dependency checker) to verify the handwritten code, which can easily generate inspection rules from the structure analysis tools such as model autumn.

Viewpoint-level processing
The viewpoint mentioned above is not only related to model design, but also important for model processing.In some cases, you may need to check constraints on different viewpoint models separately. Some viewpoints may be more suitable for interpretation rather than code generation. When generating code, you may also consider generating code in stages based on the viewpoint..
In addition, you need to note that there is a mechanism to use model partitions for segmentation, and each partition should be processed separately. If the partition and viewpoint are consistent, it makes it easy to process.

Viewpoint configuration (unrated)
For systems that use viewpoint and partition, when the model processor is running, there are often some options that need to be specified: Use a subset of constraints to verify the entire model; only generate the business logic code of the subsystem; or generate the deployment code for the entire system in the production environment.
It is a good option to use a separate model to process the configuration. In this way, the model processor is bound with a "Focus range ".", By processing the" compiler configuration ", it also serves as a model, which can bring a lot of convenience, generate model data to the attribute file or XML file, making it easier to process.

Follow Template
The code generation template is one of the core assets in the model processing process. It contains the domain concepts expressed by DSL to the ing of implementation code. Over time, the number of templates will certainly increase, and there will be some problems with maintenance. Pay attention to the following technologies:
1. Divide the Template into several small templates and call each other.
2. extract some common complex expressions into methods that can be called by all templates.

There is also a prompt: The template file only provides the indent mode for itself. For the generated file, you can directly use the code formatting tool to process it globally.
For a successful framework Generation Code, the total amount of template code needs to be reduced, and only a few of them need to be improved.

M2M conversion simplifies code generation
In some cases, a model-to-model converter is used to replace code generation. For example, for a DSL that describes the layered component architecture, most component runtime platforms do not support such a hierarchical structure, therefore, a "flat" structure is required. In this case, do not plan to use the code generator, and consider using M2M conversion first, and then write a simple generator for the flat and non-hierarchical model.
Here we will discuss unidirectional conversions in model conversion. Bidirectional conversions are only used in rare cases that are not mentioned here.

Semantic Analysis Using M2M conversion (unrated)
Another important scenario of model-to-model conversion is to convert some models into other models that are easier to understand, easier to verify, and more easily supported by tools for better semantic analysis. for example, you can convert the behavior description of a concurrent and distributed system into a Petri Net and then use appropriate tools.

Allow adaptation
To enable our model driver to meet more projects, make sure that I can directly adapt to some adjustments in a non-intrusive manner:
1.We can add hash ing key-value pairs for each model element to store additional information that can be used elsewhere in model processing..
2. code Generation templates can be customized in a non-invasive manner, and different codes can be generated directly. factory and polymorphism can be used. no, there is no need to allow all adjustments. They can be divided into public and private, and private templates are unnecessary.
Cascade Effect
When you start the MD * method, you can first define the PIM model, then convert it to a less abstract, platform-specific SM model, and finally generate code.However, based on my experience, it is best to define a DSL at the bottom to describe the software architecture of the system, and then define a generator to automatically complete the heavy work related to the implementation technology. Abstract The architectural concepts of the target architecture directly in DSL.
Then, we will establish specific business fields in a stable and basic abstraction,M2M conversion can be used to map more abstract concepts with existing abstractions in the architecture language and "Feed" them to existing generators.For architecture abstraction that cannot be mapped to the final level, a specific generator is provided to generate code as the "business logic implementation" of the Architecture generator viewpoint (replacing the code that must be written before ).
Note that you never need to modify intermediate stage models. They are used for transmission and are generally not stored. They are the "data extension form" of each stage of your cascade. If you want to add information to your target model, use the annotation model..

Comment Model
Using Model-model conversion may encounter the same problem as code generation. It is necessary to manually identify the result of the conversion step before further processing, one of the methods is to modify the model after the creation, but this method will encounter the same problems as the protection zone during code generation.
A better solution isCreate a separate model-comment the model, directly reference the elements in the intermediate model, and specify some additional model data, the downstream processor processes the model created after the upstream model-to-model converter and the annotation model combination..
For example, if you create a relational data model from an object-oriented data model, you may automatically regard the Class Name of the OO model as the name of the table in the database. If you need to change these names, if you use a comment model to specify a backup name, the downstream processor will know that the name in the comment model overwrites the name in the original model.

Classified Behavior
To more effectively implement behaviors, behavior can be classified into several types, such as status-based or business rule-based. provide specific DSL for these behaviors. In many cases, you only need to configure very limited parameters to generate behaviors.

Do not forget to test
In MD *, testing is an important part.
1. Constraints check is also a form of testing, such as the compiler in the program language.
2. When testing the code generator, do not test the syntax of the generated code, compile the Code directly, use unit testing, and test the semantics of the Code.
3. Write constraints for specific data in the conversion results to test model conversion.
4. Test the code generator,Build a test model to test all the functions of the language. This is done by the generator developer, not the builder user..
If the generator has passed the complete test and is relatively mature, there is no need to use the generator to test the generated code in the project. However, you can still use unit testing to test the entire system.
Do not use the same model to generate a system or test the system. This may lead to incorrect tests on the wrong system but pass the tests.

4. Handling and organizing
Iteration
Some people use MD * to apply the waterfall type and spend several months developing languages, tools, and frameworks. This is not a successful method, but an iterative method.You can first develop a small part for deep understanding, first build a small part of the language, build a small part of the generator, develop a small example model to verify what is done, and then gradually implement as needed.
Concepts and Languages develop together
Build a language to give you a clearer understanding of concepts and fields.
Document is required
Building a DSL and model processor is not enough for the MD * to succeed. You must also communicate with the user so that the DSL and the processor can be used. At this time, documents must be provided to describe the language and editor, generator, how to write code, how to integrate and so on. you can also record videos, which is a good choice for discussion.
Regular review
DSL limits some user freedom in some aspects and can only express things within the limits of DSL. In addition, some implementation decisions are not determined by the DSL user, but directly handled by the model processor.
Even with a good DSL, users still make mistakes and may abuse the DSL. Regular review is important and critical.The frequent errors found in the review may be errors that users often make. We can add a constraint check to automatically check this problem. Maybe this is not an error, but it is correct in the use period. At this time, you can adjust a language as appropriate..
Good understanding
MD * allows everyone to do what they are best:
1. target technical experts can thoroughly study some technical details in the target architecture, so that they can abstract the knowledge into generator templates in an optimal way, can be copied and widely used. They only need to communicate with the generator and the language designer.
2. Language designers and field experts define abstraction, symbols, and constraints together. Work with platform experts and architects to define code generators or interpreters.
You must ensure that all people in your team understand language design, domain objects, and target platforms. You must have the idea of "MD *". Otherwise, the "MD *" method will not succeed.
Do field users need to write programs?
Domain Users are not programmers. They only describe domain knowledge. If domain users understand your DSL, it may not be their fault. Your language is not suitable for this field, this requires constant attention.
Field users vs field experts (unrated)
These two roles can play different roles when creating DSL. domain experts participate in domain analysis and DSL definition. domain users can use DSL to express specific domain knowledge.
Metadata-level products
Generally, a small number of developers use these languages, constraints, and generators. This requires a good mechanism. From time to time, some developers of the generator need to directly participate in the actual development project, so that they can understand whether these are actually applicable to the actual application.
Compatible Organization
MD * may need to work across projects. when applications are deployed in multiple projects and environments, it must be well handled across fields.
Forget the real case of release
Many new software development methods are publicized through release cases. Although examples are used to demonstrate some usefulness, real decisions are not made based on the cases.The only way to determine whether DLS and MD * are suitable is to build a prototype..

5. Open Question
When we end this best practice, there are still some pending issues. To this end, the Community and tool providers must find a satisfactory solution:
(1)Mixed symbolsThere is no available tool to directly embed text symbols in the graphic model. alternatively, you can use a formula-like editor to create a DSL in semi-graphic syntax. software has this trend, but the tool cannot keep up.
(2)Language modularization and combinationIn some environments, it is also a challenge, especially for text languages. Based on the parsing technology, combined parsing does not need to be well handled. The MPs of jetbrains has an advantage in making text models as metadata structure storage, metaedit + handles language modularization very well.
(3) Metadata-level ReconstructionIt is not supported in most systems. In fact, this is not a big challenge, I think it is just that no one has done it.
(4)Model/code ReconstructionIt's not that simple. For code that relies on the Automatic Generation of code from the model and hand-writing your own code, if you modify the model and re-generate the code, how do you deal with handwritten code? It is often not processed, but ideally it is expected that the handwritten code can be automatically changed to adapt directly to the changes in the model.
(5)Automatic model migrationIt is also an unsolved problem. How will you deal with your model after your language changes? Abandon them because they can no longer open them? Open them in the new editor, but some of the tags in the original model are not compatible with the new language? Automatic migration attempt? These are all optional solutions, but I really don't know what the best practices look like.
(6)Model debuggingDebugging a running system at the model level. Although you can manually construct a specific solution, there is no work yet to directly support the implementation of such a debugger.
(7)Interpretation and code generation are generally considered as two choices.Instead of a unity. you may only need a parser, so you can choose to use code generation when the parser is slow. no processing is available only in the study.
(8)Process a large number of models or a large number of modelsThis is also a problem. How to expand the basic architecture? How do I perform impact analysis after something changes? How to navigate to a large and large model? How can we efficiently search and query them? How to present them gradually?
(9)How to combine the generated modules?How do I define the interfaces of these modules? How do these modules depend indirectly on the code generated by you?

Too many challenges. Let's get started!

[Translation] DSL and model-driven development best practices (1/4)
[Translation] DSL and model-driven development best practices (2/4)
[Translation] DSL and model-driven development best practices (3/4)

 

Original article: http://www.jot.fm/issues/issue_2009_09/column6/index.html
Because the length is too long, it is divided into several parts for translation. The translation level is limited. If the English is good, you 'd better read the original article directly.
I strongly recommend this article to model-driven developers!

Author: lone knight (like a year of water)
Source: http://lonely7345.cnblogs.com/
The copyright of this article is shared by the author and the blog Park. You are welcome to repost this article. However, you must retain this statement without the author's consent and provide a clear link to the original article on the article page. Otherwise, you will be held legally liable.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.