720 likes | 900 Views
MDSD Best Practices. MDSD Best Practices Markus Völter voelter@acm.org www.voelter.de. Note: This tutorial is an ongoing project. Updates of the slides can be found regularly at www.voelter.de/services/mdsd-tutorial.html Please check the site for updates, if you‘re interested. About me.
E N D
MDSD Best Practices MDSD Best Practices Markus Völtervoelter@acm.orgwww.voelter.de Note: This tutorial is an ongoing project. Updates of the slides can be found regularly at www.voelter.de/services/mdsd-tutorial.html Please check the site for updates, if you‘re interested.
About me Markus Völter voelter@acm.org www.voelter.de • Independent Consultant • Based out of Heidenheim, Germany • Focus on • Software Architecture • Middleware • Model-Driven SoftwareDevelopment
C O N T E N T S • Intro – What is MDSD • Best Practices • Domain Construction & Code Generation • Tool Construction and Selection • Process • Testing • Versioning and Multi-Model/Multi-Site • End.
C O N T E N T S • Intro – What is MDSD • Best Practices • Domain Construction & Code Generation • Tool Construction and Selection • Process • Testing • Versioning and Multi-Model/Multi-Site • End.
Model Driven Software Development Overview several target software software Metametamodel architecture architecture subdomains designexpertise Application bounded area of partial knowlege/interest composable multiple knowledge viewpoint multi-step transform Domain single-step compile semantics Model Ontology interpret no precise/ Domain roundtrip executable Specific Language graphical Metamodel textual
MDA and Model Driven Software Development Overview MOF several target software software Metametamodel architecture architecture subdomains designexpertise Application bounded area of partial knowlege/interest composable PIM, PSM, .... QVT multiple viewpoint multi-step transform Domain single-step compile semantics Model Ontology interpret no precise/ Domain roundtrip executable Specific OCL, Action Semantics Language UML+Profiles graphical Metamodel textual
MDSD Benefits I • Models are free of implementation artifacts – they directly represent domain knowledge and are thus reusable. • Implementations for various platforms can be generated in principle – the technology change problem is adressed to some extend. • Technology freaks and domain experts can take care of „their business“ (transformations and models, respectively) and need to care of each other‘s problems only in a limited way. • Domain experts can play a direct role in development since they can more easily understand models expressed with a DSL as opposed to implementation code.
MDSD Benefits II • Development becomes more efficient since repetitive implementation code can be generated automatically. • Architectural contraints/rules/patterns can more easily be enforced, since the they are embedded in the templates rather than just being documented (and ignored).This is especially important in really large teams, often in the context of Product-Line Engineering and Software System Families. • Transformer/Generator can address cross-cutting concerns (just like an aspect weaver)
MDSD Predjudices • MDSD does not require UML – any kind of modelling language is ok, graphical or textual • Precise and complete models… • … are not the the same as „visualized code“ – the abstraction level is higher • … are not the same as analysis models – analysis models are not computational • MDSD does not require – not even recommend – a waterfall. Development of the generative infrastructure is iterative and incremental. • You do not need big and expensive tools – a lot of small and useful open source tools are available. • You don‘t need to generate 100% of the code – it is ok, to also code some aspects in a 3GL.
C O N T E N T S • Intro – What is MDSD • Best Practices • Domain Construction & Code Generation • Tool Construction and Selection • Process • Testing • Versioning and Multi-Model/Multi-Site • End.
Believe in Re-Incarnation • The final, implemented application should be built by a build process that includes re-generation of all generated/transformed parts. • …which includes more than just code – see LEVERAGE THE MODEL • As soon as there is one manual step, or one line of code that needs to be changed after generation, then sooner or later (sooner is the rule) the generator will be abandoned, and the code will become business-as-usual. • Note that this pattern does not receommend to generate as much stuff as possible. • You should use a RICH DOMAIN-SPECIFIC PLATFORM, • And SELECT FROM BUILD, BUY OR OPEN SOURCE
Separate Generated and Non-Generated Code • Keep generated and non-generated code in separate files. • Never modify generated code. • Design an architecture that clearly defines which artifacts are generated, and which are not. • Use suitable design approaches to “join” generated and non-generated code. Interfaces as well as design patterns such as factory, strategy, bridge, or template method are good starting points.
Separate Generated and Non-Generated Code II • A) Generated code can call non-generated code contained in libraries • B) A non-generated framework can callgenerated parts. • C) Factories can be used to „plug-in“ the generated building blocks • D) Generated classes can also subclass non-generated classes. • E) The base class can also contain abstract methods that it calls, they are implemented by the generated subclasses(template method pattern)
Rich Domain-Specific Platform • Define a rich domain-specific application platform consisting of • Libraries • Frameworks • base classes • interpreters, etc. • The transformations will “generate code” for this domain-specific application platform. • As a consequence, the trans-formations become simpler.
Technical Subdomains • Structure your system into several technical subdomains such as persistence, GUI, deployment. • Each subdomain should have its own meta model and specifically, its own suitable DSL. • Define a small number of GATEWAY META CLASSES, i.e. meta model elements that occur in several meta models to help you join the different aspects together.
Gateway Metaclasses • Using TECHNICAL SUBDOMAINS results in different meta models as well as different concrete syntax for the different subdomains. • Example: workflow/using activity diagrams, Layout/ textual, XML-like language. • If you want to generate a system from these different specifications, your generator needs a mechanism to get from one model to the other: • you need model elements that are present in the meta models of both TECHNICAL SUBDOMAINS. IGNORING CONCRETE SYNTAX in your generator makes this simpler. • The second thing you need is a common meta meta model. For example, Java classes to be used as the meta meta model for all meta models.
Generator-based AOP • Implement the handling of cross-cutting concerns with the help of the generator. • You can either take advantage of the generator’s integral features (e.g. consider that it generates many instances of a meta model element with the help of one transformation/template), or • Weave various “aspect models” in the generator • use the generator to implement proxies, interceptors and other AOP-addressing design patterns in the generated system. • Consider the cross-cutting concern a TECHNICAL SUBDOMAIN and provide a suitable DSL for it.
Generator-based AOP II • Example:
Produce Nice-Looking Code … whenever possible! • PRODUCE NICE-LOOKING CODE … WHEREVER POSSIBLE! • When designing your code generation templates, also keep the developer in mind who has to – at least to some extent – work with the generated code, for example • When verifying the generator • Or debugging the generated code • Using this pattern helps to gain acceptance for code generation in general. • Examples: • Comments • Use pretty printers/code formatters • Location string („generated from model::xyz“)
Descriptive Metaobjects • The generated application often needs information about some model elements at run time to control different aspects of the applicaton plaform. • Use the information available at generation time to code-generate meta objects that describe the generated artifacts. • Provide a means to associate a generated artifact with its meta object. • You add a getMetaObject() operation to the generated artifact. • You can also use a central registry that provides a lookup function MetaRegistry.getMetaObjectFor(anArtefact). The implementation for the operations will be generated, too. • Make sure the meta objects have a generic interface that can be accessed by the RICH DOMAIN-SPECIFIC PLATFORM.
Descriptive Metaobjects II • Example:
Generated Reflection Layer public interface RClass { // initializer – associates with // base-level object public setObject( Object o ); // retrieve information about //the object public ROperation[] getOperations(); public RAttribute[] getAttributes(); // create new instance public Object newInstance(); } public interface ROperation { // retrieve information about op public RParameter[] getParams(); public String getReturnType(); // invoke public Object invoke(Object params) } public interface RAttribute { // retrieve information about op public String getName(); public String getType(); // set / get public Object get(); public void set( Object data ); } • You can even go one step further and generate an “interpreter”, a reflection layer that allows you to • “script” the system • build IDEs • Since the reflection layeris separate from the coreclasses, it can be excludedfrom the „real“ system for(performance reasons)
External Model Markings (AO-Modelling) • In order to allow the transformation of a source model into a target model (or to generate code) it is sometimes necessary to provide “support” information that is specific to the target meta model. • Example: Entity Bean vs. Type Manager • Adding these to the source model “pollutes” the source model with concepts specific to the target model. • MDA proposes to add “model markings”, but this currently supported well by only very few tools. • Instead, we recommend keeping this information outside of the model (e.g. in an XML file); the transformation engine would use this auxiliary information when executing the transformations.
Leverage the Model • The information captured in a model should be leveraged to avoid duplication and to minimize manual tasks. • Hence you may generate much more than code: • user guides • help text • test data • build script • content, etc. • Find the right balance between the effort required for automating manual tasks and the effort of repetitively performing manual tasks • Make use of SELECT FROM BUY, BUILD, OR OPEN SOURCE in your assessment.
Select from Buy, Build or Open Source • It is typically not a good idea to re-invent the wheel, even in case the wheel is generated. • Don't be blinded and ignore the potential of well-proven off-the-shelf products and robust Open Source infrastructure that is used by thousands of organizations! • However, do LEVERAGE THE MODEL and don't compromise hard-earned domain knowledge that has gone into your domain-specific frameworks and generators by replacing them with unrefined and blunt off-the shelf tools.
C O N T E N T S • Intro – What is MDSD • Best Practices • Domain Construction & Code Generation • Tool Construction and Selection • Process • Testing • Versioning and Multi-Model/Multi-Site • End.
Tools: Overview • Many kinds of tools can be used in the context of model driven development: • UML modelling tools • Metamodelling environments • (XMI) Repositories • Code Generators • Model verifiers • There is also a large amount of tools that are „MDA certified“. These range from completely integrated environments such as ArcStyler to simple code generators or technology specific generators (e.g. for J2EE).
Tools: Vendor Lock-in • Because a lot of issues are not yet standardized, it is hard to integrate tools. Open issues include: • Some XMI aspects • Specification of model transformation rules • Code generation • ... • As a consequence, integrated MDD/MDA tooling is currently impossible to achieve without vendor lock-in. • Alternatively, building/integrating your own tooling based on open source can be done, but requires compromises. • Many tools are exemplified in the context of code generation (see other presentation). Build Tools are also important. UML tools (such as Rational XDE) also develop in the direction of supporting MDA.
Tools: Examples • Rational XDE • AndroMDA • Velocity • XML + XSLT • openArchitectureWare • Xdoclet • ArcStyler • iUML
Tools: The Ideal One • MOF Based Metamodelling, including OCL • Usage of thses metamodels for subsequent modeling of M1 • Metamodel specific repositoriy • GUI adapted to metamodel • Model Validation based on metamodel • Also including OCL • Transformation rules based on user-defined metamodels • Flexible Code Generation • Test support
Implement the Metamodel • Implement the meta model in some tool that can read a model and check it against the meta model. • This check needs to include everything including declared constraints. • Make sure the model is only transformed if the model has been validated against the meta model. • The meta model implementation is typically part of the transformation engine or code generator since a valid model is a precondition for successful transformation.
Ignore Concrete Syntax • Define transformations based on the source and target meta models. • The transformer uses a three phase approach: • first parse the input model into some in-memory representation of the meta model (typically an object structure), • then transforms the input model to the output model (still as an object structure) • and finally unparse the target model to a concrete syntax
Transformations as first class citizens • Transformations (and Templates) are central assets in MDSD. You should treat them accordingly. • Transformations should be versioned. • Refactor transformations to keep them current and well organized. • Modularize transformations, e.g. using object-oriented concepts such as encapsulation, polymorphism, inheritance, etc.
Modular, Automated Transforms • In order to more easily reuse parts of a transformation, it is a good idea to modularize a transform. • Note that in contrast to the OMG, we do not recommend looking at, changing or marking the intermediate models. • They are merely a standardized format for exchangingdata among the transformations. • Example: Multi-Step transformation from a banking-specific DSL to Java via J2EE
Modular, Automated Transforms II • Example cont’d:Now consider a Call-Center application; only the first step needs to be adapted. • If both should be transformed to .NET, only the backend needs to be exchanged.
Build an IDE • Model-Driven Software Development often includes a wealth of input, intermediate and output artifacts. • Users (application developers) can easily be confused by these many artifacts. • To improve acceptance of the approach, you should consider building an IDE for application developers which • Hides unnecessary intermediate artifacts • Provides editors/support for “programming” with the DSL • Integrates all the validation, generation, build, etc. • Eclipse, for example, is a good toolkit for building these kinds of IDEs.
Two-Stage Build • Separate the generation run into two stages: • the first stage reads some kind of configuration and prepares the actual generator for the core transformation. • The second stage is the execution of the transformer and uses the preparations done in the first stage.
Two-Stage Build II • Example:
C O N T E N T S • Intro – What is MDSD • Best Practices • Domain Construction & Code Generation • Tool Construction and Selection • Process • Testing • Versioning and Multi-Model/Multi-Site • End.
Iterative Dual Track Development • Develop Domain Architecture and at least one application at the same time. • Establish rapid feedback from application developers to domain architecture developers. • Develop both aspects iteratively and incrementally. Use strict timeboxing. • Infrastructure develops iteration n+1 whereas application developers use iteration n. • Introduce new Domain Architecture releases only at the beginning of iterations.
MDSD Process II • Domain Architecture Development
Scope Trading • Use a formal scope tradingworkshop at the beginning of each iteration (for Domain Architecture as well as for application development). • All relevant stakeholders (including end users) need to be represented in the workshop. • Document results and make sure everybody understands and agrees. • Set priorities in the upcoming iteration based on the results of the workshop.
Validate Iterations • Each timebox is concluded with a formal iteration validation workshop to confirm progress • Let an end user that acted as the on-site customer drive the demonstration of implemented features. • Explicitly communicate to the end user and stakeholder community that new requirements can be brought up at any point. • Encourage exploration of "what-if" scenarios—stakeholders may develop a new idea while watching the demonstration • Similarly the architect may want to raise issues that may have escaped the requirements elicitation process and that have been uncovered by the development team.
Extract the Infrastructure • Before startingITERATIVE DUAL-TRACK DEVELOPMENT, Extract the transformations from manually developed application. • Either, start by developing this prototype conventionally, then build up the MDSD infrastructure based on this running application, • Or extract the code from applications developed in the respective domain before doing MDSD (but only if the quality is sufficiently good!)
C O N T E N T S • Intro – What is MDSD • Best Practices • Domain Construction & Code Generation • Tool Construction and Selection • Process • Testing • Versioning and Multi-Model/Multi-Site • End.
The Role of Testing in SW Development • In all but very few cases, the correctness of software cannot be verified theoretically or formally. • Thus the only way of verifying a system does what it should do is by testing it extensively. • There are different kinds of things that can be tested: • Ensuring that the software does what the developer wanted it to do • Ensuring that what the developer programmed is actually what the system should do (i.e. what the customer wants) • Ensuring that the system performs and scales adequately • Ensuring that other non-functional properties work as specified (such as transactions, security, ...) • Ensuring that the tools and technologies used in the implementation work together well • We will now look at each of these in the context of MDD.
Unit Testing • Ensuring that the code does what the developer wants is called Unit Testing. • Tools such as JUnit provide a framework to implement and repeatedly execute unit tests • They are written by the developer as he develops his code. • Typically, they test functionality, not nun-functional properties • In the context of MDD, unit tests can be generated from models, too • Tests for static properties can be generated directly from the model. • For behavioral aspects, It should be a different model – because if tests are created from the same model as the implementation code, tests will always pass. • Additional Testcases can also be generated from OCL expressions (invariants, as well as pre- and postconditions). • When the code is generated, we can even embed OCL constraint evaluation into the generated code and check these at runtime.
Unit Testing Example • Consider the following model: • This could result in the following code: • A similar approach could be taken for the invariant in Person. • In case of the invariant, it is easy to automatically create a set of unit tests that check ages like 0, 16, 78, 120, -1, 3.4 and see if the system behaves accurately. class Vehicle { ... public void setDriver( Person p ) { if (driver.getAge() < 18 ) throw new ConstraintViolated(); }}
Requirements Testing • Here we want to make sure that the system does what the customer (or the requirements) say. • We use the same technical approach here as for unit testing. However, here the test cases are written by domain experts and not by the developer. • If models are annotated with OCL constraints, they are significantly more rich that „typical“ requirements. A lot of test cases can be generated from these models. • If we have a suitable, high-level modeling notation (such as a UML profile), the domain expert can even specify test models himself, or with some support by a technical person. • Because of the domain-specific notation, developer/ customer communication about tests is simplified.
Performance and Scalability Testing • This kind of testing basically works by simulating a certain number of clients and then measuring response times and resource consumption. • Running such tests always requires a setup of an environment similar to the production environment. This is typically done manually, although some deployment artifacts can be generated from models. • The simulated clients can often be generated completely. The input is basically • Which operations to call • At which sequence and intervals • In how many parallel threads or processes • And where to store the timing measurements and in which format