When developing applications, we usually feel that some application parts are quite similar but not exactly the same. For example, in an application involving Customers and Products, it is only natural to have a Form to list Customers, and another Form to do the same for Products. Even though Customers and Products are totally different, these two Forms have many things in common: a grid, a fieldset to filter data, ordering, actions, etc.
This is called a "pattern" and has been a very popular topic in the software industry lately (see What Is a Software Pattern for more info).
The question is whether we can use these ideas in GeneXus. In other words, what exactly is a pattern in GeneXus, and why is it useful? Before answering these questions, we must first address some of the limitations of patterns today:
- Passive. They exist only in books; the only way to use them is to read the books and use these ideas while coding.
- At coding level. Even though patterns are usually referenced as "Design Patterns", they are mainly aimed at helping with coding.
Since GeneXus works at knowledge level instead of coding level, we wanted to use patterns as a way to enable knowledge reuse, not just code reuse. So, we developed a framework for patterns whose design goals are as follows:
- Active. An "active" pattern isn't just a guideline; you can "instantiate" it (meaning that the framework generates all the GeneXus objects needed to implement a pattern instance). See the Pattern Instantiation concept.
- Knowledge reuse. GeneXus has always tried to encourage knowledge reuse, but with the use of patterns we can deliver a new level of knowledge reuse: the same knowledge can be reused in many different situations. For example, a "specialized pattern" can be instantiated to Products, but also to Menus.
- Open. Anyone can generate his/her own patterns (or modify an existing one).
- User-friendly. In this way, we keep our promise to reduce complexity: to use a pattern you don't need to be an expert in this area. (Note: this may not always be the case; if you also want to develop your own pattern, a deeper knowledge of the subject is needed).
GeneXus Patterns are the result of these efforts. This extension is included in the GeneXus IDE and if you define a new Pattern you will also view it as a new option in the GeneXus IDE.
The extension itself comes with a set of "built-in" patterns such as Work With Pattern and the Category Pattern so the developer can start using patterns without the need to develop a pattern him/herself.
The framework also helps developers create their own patterns.
After you define your Pattern structure, as we will see later, the Pattern engine generates typed classes of your instances to use in the templates and in your custom code.
Going back to the question of why Patterns are useful for a GeneXus developer: a big boost in productivity and application quality is expected with the use of this tool. For example, a typical use scenario is when developers need to migrate a Knowledge Base from green screen or Windows forms to Web forms. In this case the Work With Pattern can be applied to generate most of the web objects needed for a nice-looking and user-friendly web application.
See People And Organizations Knowledge Base for an example.
Patterns are fully integrated into the GeneXus IDE. GeneXus has built-in Work With and Category patterns.
The implementation is based on the built infrastructure to create defaults for each object part. Basically, this means that now you don't need to apply the pattern and import the result. When you change a property in the pattern definition, objects will automatically react to the change without the need to recreate them.
Every part of every object can have a default value. We can have default Web Panel forms, Web Panel events, etc. The default for each part can be different for each specific object. You can have a Web Panel with one template set as default for the form, and another with a different one.
The Work With Pattern implementation creates a set of empty objects with specific default templates set in each object. It creates a “WW<Transaction>" Web Panel with a default template that reads the transaction structure and creates a grid. This means that every time you add an attribute to the transaction, it will also be added to the Web Panel without the need to apply the pattern again.