Composed methods
RISE allows the user to combine, or orchestrate, existing methods into higher order methods. The RISE composed method editor implements a drag-and-drop approach to linking one method to the output of other methods. The composed editor assures the consistency of composed methods and makes creating composed, high level, methods real simple.
A composed method consists of a sequence of calls to other methods, possibly composed ones. When creating a composed method the method is named ComposedMethod by default. You should change it to a more suitable name reflecting its functionality.
Rules for the Composed method sterotype:
Why and when?
A composed method is, in all aspects, far more complex than a basic stereotype method such New or List. This because, the composed method signature doesn't reveal the purpose nor the functionality of the method. It means that before adding composed method to your project you should decide why you need them and select a naming convention for your composed methods. Otherwise, you're likely to end up having a set of methods that no one is capable of understanding, let alone using. Still, however, composed methods are very powerful and here are some of the scenarios when you need them:
-
To simplify, or hide, complex creation or deletion processes. For instance, deleting an object in a hierarchic, tree-like, structure might require deletion of dependent objects, possibly in several steps. Implementing such deletion code is a complex as well as tedious task. Furthermore, such code wll prove error prone and difficult to maintain. The solution: black box it in a composed method. See
IDocument example below.
-
To implement server-side permission control in your information solution. This is necessary if the information solution is to be deployed in an environment where the clients using it isn't entirely under your control, for instance, if you're exposing the information model web services on the Internet or if you're modeling the server-part of product. See
Permission control sample below.
-
To implement, and blackbox, high level business logics or system integrations. In these cases you implement the actual logics, or integrations, in
custom methods that, entirely or partially, operate on data managed in the model. For instance, consider a composed method that first retrieves data from your information model and then calls custom code that puts the data into a Word document and stores it in your document or record management system.
We proceed with the miniature Folder-Document project, by adding a simple composed method that deletes all documents in a specific folder.
The logics behind such a delete operation is: a loop that finds all Documents related to a specific Folder and then deletes them. This can be accomplished by calling the auto-generated primitive methods in the IDocument interface from anywhere. In this case, we'll invoke them from within a composed RISE method. This is done using the Composed method editor opened, for instance, by dragging a composed method from the left-hand toolbar and dropping it on the interface.
The composed method editor dialog is divided into five fields.
- Upper-left: displays the currently available output of the methods used within the composed method. These correspond to the possible output of the composed method itself. Drag them to the "Return set" in order for the method to actually return them.
- Upper-right: input and output of the composed method. The Arguments are managed by the method editor, though, you may rename them. The Return set is user managed and populated from the Available output.
- Mid-left: displays available interfaces and methods in the project that can be used inside the composed method. To use a method, drag it to right-hand window and drop it on proper place in the program flow.
- Mid-right: displays the program flow of the composed method. The composed method is executed top-down. The symbol interconnecting two method shows how the subsequent method retrieves its input, either once (straight arrow) or repeatedly (circular arrows) if the preceding method generates a list. You may further modify the flow by
- Double-clicking a method call to open its method editor (drill-down).
- Right-click a method call to specify conditional execution (flow control).
- Right-click a method call to specify post processing options. Currently, only methods return lists (multiple rows) have post processor options.
- Bottom: show the input arguments of the currently selected program flow method. This is where you can see, in detail, where from a method receives its input.
In a scenario where you intend to implement server-side permission control you should keep your public, secured, methods separate from the auto-generated data access methods (New, Delete, List etc). The following recipe will guide you in the implementation process:
-
Keep your public, secured, methods separate from the auto-generated data access methods. This is done by placing all low-level primitives in interface marked as private.
Read about private interfaces.
-
Implement your permission control methods. This is done by implementing custom code methods that verifies the user credentials and, typically, generates an exception if the user is unauthorized. These methods, too, are best placed in private interfaces.
Read about custom methods.
-
Create composed methods, in a public interface, that calls the appropriate permission control method prior to executing any of the private, data access, methods.
The below is a snapshot of a real-world scenario. The composed method ChangeUserPassword is available solely for users with administrative privileges. The method first calls IArchive.ThrowIfNotAdministrator before running the sequence of operations updating a user's password. Note, that ThrowIfNotAdministrator as well as EncryptPassword are custom methods whereas GetUser and SetUser are auto-generated methods.