Tony Marston's Blog About software development, PHP and OOP

The Template Method Pattern as a Framework

Posted on 2nd March 2019 by Tony Marston
Introduction
Characteristics of the Template Method
My implementation
Using templates for more than operations
- Data Validation
- Reusable Views
- Reusable Controllers
- Data Dictionary
- Transaction Patterns
Reasons why other programmers cannot compete with my implementation
References
Comments

Introduction

In the book Design Patterns: Elements of Reusable Object-Oriented Software by the Gang of Four (GoF) the Template Method pattern is described as follows:

Defines the skeleton of an algorithm in an operation, deferring some steps to subclasses. It lets subclasses redefine certain steps of an algorithm without changing the algorithm's structure.

This is supposed to be a well known pattern, but apart from articles which describe what it is, I have encountered very few resources on the internet which describe how it can actually be used. The ones that I have seen have been pretty limited in their scope, such as Six common uses of the Template Design Pattern which makes absolutely no mention of database access although this occurs repeatedly in every database application. This leads me to wonder if I am the only programmer in the entire world who has managed to not only to use this pattern for accessing a database but also to create a framework which implements this pattern within every use case - not just parts of a use case but the entire use case.

Let me first explain that of all the different types of software that it is possible to write I specialise in only one kind - database applications. These are used by organisations, not individuals, so are also known as enterprise applications. These have forms at the front end, a relational database at the back end, and software in the middle which moves data between them. This replaces the pre-computerised version where there were paper forms at the front end, a filing cabinet at the back end, and a human being in the middle who filled out the forms and then filed them away. In the pre-internet days computer software used forms which were compiled and ran only on the desktop, but modern internet-enabled software uses HTML forms which can be accessed on any device with a web browser. Before I switched to using the PHP language in 2002 I had spent 20 years building database applications using languages such as COBOL and UNIFACE which used a variety of hierarchical, network and relational databases, so it is safe to say that I was no stranger to this genre.

Design patterns were not available for the COBOL and UNIFACE languages, and I managed to make the transition to PHP without ever reading a single article about them. The only architectural pattern that I encountered with UNIFACE was when version 7.2.04 was released in which it made the transition from a 2-Tier to the 3-Tier Architecture. Surprisingly this common pattern was not mentioned in the Gang of Four book. After working briefly with this pattern I immediately saw the benefits as it allowed a single component in the Business layer to be accessed by multiple components in the Presentation layer, and it allowed the whole application to be switched to a different DBMS by changing a single component in the Data Access layer. When I began rewriting my development framework in PHP I aimed to reproduce this architecture so that I could hopefully achieve similar benefits. This was actually the 2nd rewrite of my development framework which I first developed in COBOL in the 1980s, then rewrote in UNIFACE in the 1990s. My PHP implementation of this pattern is described in A Development Infrastructure for PHP and What is the 3-Tier Architecture?

No sooner had I begun to publish articles about my development practices on the internet than I was criticised by my peers for not using the "right" design patterns, or not implementing them in the "right" way. For "right" this means "personal preference" and not "standard practice". I bought the Gang of Four book, but after a brief read I put it on a shelf where it has been gathering dust ever since. The descriptions of each pattern and the small code samples were simply not good enough to persuade me of the benefit of using those patterns, so I ignored them. I prefer to start by writing simple code that works, then refactor it so that it works as efficiently as possible and makes use of reusable and sharable components instead of duplicate copies. If a recognisable design pattern emerges then great! If one doesn't then perhaps it is just a pattern that no-one has recognised yet. This actually echoes the thoughts of Erich Gamma, one of the authors of the Gang of Four book, who, in the article How to use Design Patterns, said the following:

Do not start immediately throwing patterns into a design, but use them as you go and understand more of the problem. Because of this I really like to use patterns after the fact, refactoring to patterns.

This philosophy was echoed by Dustin Marx, who, in the article Design Patterns: Mogwai or Gremlins? said the following:

The best use of design patterns occurs when a developer applies them naturally based on experience when need is observed rather than forcing their use.

The only pattern that I have ever read about and then sought to implement was the singleton. This was because I sometimes found myself instantiating the same object more than once in the same script, and I read that this pattern would be more efficient because it used a single shared instance instead of multiple duplicate instances.

Readers of my blog are aware that my framework also contains an implementation of the Model-View-Controller Design Pattern, but that again is purely by accident and not by design. (That's a play on words. Geddit? Oh never mind.) Instead of writing a single component for my Presentation layer I had split it into two so that all HTML output was produced by a separate component which constructed an XML document using data supplied by both the application component and the framework, then used an XSL stylesheet to transform it into HTML. Although I had read a few articles on the MVC pattern I could not see how the code in the samples they provided could easily fit into my code, so I ignored them. It wasn't until a colleague pointed out that I had already implemented a version of MVC that I investigated further. It was only by ignoring their implementations and studying the root definition of MVC that I realised that my implementation did in fact meet that definition. This highlights one of my complaints against design patterns in general. Instead of providing patterns which can be utilised with a single "use pattern X" instruction they are nothing more than the descriptions of patterns for which you have to provide your own implementation. If you have to write your own code each time where exactly is the reusability?

Similarly it wasn't until several months ago, while writing How Radicore's Hook System Works, that I came across the definition of the Template Method Pattern. The more I read this definition the more I realised that my framework does more than contain just a few examples of this pattern, it is actually littered with them. Not only does every concrete class in my Business layer make use of this pattern, but every user transaction (use case), from the initial request all the way through to the eventual response, also implements code from standard templates which form the backbone of my framework.

Characteristics of the Template Method

According to the Gang of Four book this method can be applied in the following circumstances:

when common behaviour among subclasses should be factored and localized in a common class to avoid code duplication. You first identify the differences in the existing code and then separate the differences into new operations. Finally, you replace the differing code with a template method that calls one of these new operations.

Where the description of this pattern says "Defines the skeleton of an algorithm in an operation" some readers may assume that the word "algorithm" refers to a mathematical equation, but it actually includes any process or procedure that involves a series of discrete steps. The idea is that you define the operation name as a public method in a class, and when this method is called it simply calls a series of sub-methods, one after the other, in a predefined sequence. Some of these sub-methods are invariant in that they contain code which should not be altered, while others are empty "hook" operations which do nothing unless an implementation is provided in a subclass. Note that while the class itself is abstract, in my implementation none of these "hook" methods is abstract, which means that none of them need be defined in the subclass unless the implementation needs to be changed. Different subclasses can therefore provide different implementations for these "hook" methods while sharing the same set of invariant methods. This structure is shown in Figure 1 below:

Figure 1 - Steps in a Template Method

template-method-001 (1K)

The recommended technique for implementing this pattern is to define the operation and its sub-methods, both invariant and variant, in an abstract class, then create any number of concrete subclasses which inherit from this abstract class. Only those "hook" methods which require a particular implementation need be defined in the concrete class. This structure is shown in Figure 2 below:

Figure 2 - Template Method in an Abstract Class

template-method-002 (2K)

In this example the abstract class contains a single operation which then executes a series of steps in a predefined sequence. The operation is implemented as a public method while each step is implemented as an internal sub-method. Some of these sub-methods, shown in green, already contain concrete implementations which cannot be altered while others, shown in yellow, are designated as "hook" methods which contain no implementation at all. When the abstract class is inherited by a concrete class any of these empty "hook" methods can be copied into the concrete class and filled with whatever code is deemed to be necessary. Note that the operation will still function even if none of the "hook" methods is populated with code. It just means that the default code will be executed without being altered in any way.

Some OO purists seem to think that each of these "hook" methods should be implemented as abstract methods, but I do not as this would produce an unwanted side effect. If you inherit from a class which contains abstract methods then your concrete class is forced to implement each and every one of those abstract methods even though you might not want to change the empty implementation. By leaving these "hook" methods as normal methods I therefore do not need to define them in my concrete class unless I actually wish to provide a non-empty implementation. The number of "hook" methods in my abstract class has grown from a few dozen in 2002 to over 90 today, so the idea of being forced to populate each concrete class with over 90 empty methods is not something I would contemplate doing in a million years. It would be an enormous amount of effort for absolutely zero benefit, so in my world that idea is a non-starter.

It is recommended that each of these "hook" methods be given a prefix which readily identifies them as being able to contain custom code, which is why in my framework they all have the prefix "_cm_" to denote them as customisable methods. Examples of there methods can be seen in UML diagrams for the Radicore Development Infrastructure.

Template methods lead to an inverted control structure that's sometimes referred to as "the Hollywood Principle" (Inversion of Control), that is "Don't call us, we'll call you". This refers to how a parent class calls the operations of a subclass and not the other way around.

My implementation

Knowing the theory is one thing, but the real test of a programmer's skill is being able to put the theory into practice with maximum effect. The Gang of Four book contains the following statement regarding the Template Method pattern:

Template methods are a fundamental technique for code reuse. They are particularly important in class libraries because they are the means for factoring out common behaviour.

The programmer's objective should therefore be to put all the common behaviour into templates so that he need only supply the different behaviour in the "hook" methods. How do you do this? You start by examining all the components in an application in order to identify those pieces of code which are common/identical/similar, and those pieces of code which are uncommon/unique/different. The idea is then to put all the common code into sharable templates so that it can be isolated from the uncommon code, then provide the means to generate components which call the relevant template automatically and which allow the developer to specify the custom code for the relevant "hook" methods. In my software, which involves nothing but database applications, every one of my tasks (user transactions or use cases) involves performing one or more actions on one or more database tables. Because of this I created a single abstract table class which implements each of of the standard Create, Read, Update and Delete operations which can then be inherited by every one of the 400+ concrete Model classes which exist in my Business layer. The invariant methods in the abstract class contain the boilerplate code, which means that each Model class need only contain the code which is unique to that particular Model class. My abstract table class is quite large, but this means that the volume of sharable code is quite large, which in turn means that the volume of custom code in each Model class is relatively small.

The big problem for a lot of today's OO developers is that they have great difficulty in identifying abstractions at what I would call the "correct" level. The process of abstraction can be defined as:

1) the act of representing essential features [of a class of object] without including the background details or explanations.
2) the act of considering something as a general quality or characteristic, apart from concrete realities, specific objects, or actual instances.

What this means is that in an application which contains a large number of components you need to identify those components which share a set of essential features, put these high-level sharable features into a sharable abstraction, and leave the low-level details to the individual components. But in a large enterprise application which is broken down into a series of different business areas how easy is it to spot a set of "essential features" which are shared by multiple components? The term "business area" is what I refer to as a "subsystem" in my framework, but which OO aficionados refer to as a "domain". Using my framework I have built a large enterprise application which contains the following business areas/subsystems/domains:

  1. Role Based Access Control - users, tasks, permissions, menus.
  2. Audit - logs all database changes.
  3. Workflow - activity based workflows.
  4. Data Dictionary - class generation and transaction generation.
  5. Party - people and organisations, customers and suppliers.
  6. Product - products, components, features, prices.
  7. Order - sales orders, purchase orders, transfer orders.
  8. Invoice - sales invoices, purchase invoices, debit notes and credit notes.
  9. Inventory - products in inventory, issuances, receipts, facilities, containers, lots.
  10. Shipment - outbound shipments, inbound shipments, customer shipments, supplier shipments.
  11. Request - requirements, requests and quotations.
  12. Survey - surveys and questionnaires.
  13. Content - miscellaneous content.
  14. Work Effort - timesheets and expenses.
  15. Blockchain - configuration and administration.
  16. Personnel - strategic HR, performance reviews.

This is not a complete list as work on several new subsystems is ongoing.

At first glance an inexperienced programmer would regard each of these subsystems/domains as being totally unique with absolutely nothing in common, nothing which can be shared. Each subsystem has its own database where the structure and content is totally unique, each has its own set of business rules which is totally unique, and each has its own unique set of tasks which can be selected by the user in order to carry out any of the many business transactions. It is because of this blinkered view that the idea of Domain Driven Design (DDD) was born in which the primary focus is placed on the unique business logic within a particular domain, and the software is then designed and built around this business logic. Any other code which is not unique to the domain is added on later as an afterthought. To my way of thinking this is an arse-backwards philosophy which I have debunked in my article Why I don't do Domain Driven Design. Starting with the differences and bolting on the similarities as an afterthought makes the use of the Template Method pattern totally impossible. That is why I start with the similarities and bolt on the differences as an afterthought.

The main reason that I don't follow DDD is that I had been successfully designing and building database applications for over 30 years without knowing that DDD existed, and using a methodology that was totally different from DDD. As soon as I read the principles of DDD I deduced that it was approaching the problem from entirely the wrong angle, and to change my methodology to follow this arse-backwards approach would seriously impair my ability to write cost-effective software, so I consigned the whole idea to the rubbish bin and carried on doing what I had been doing for the previous 30 years. The main point of my design philosophy when it comes to database applications is surprisingly simple, but which far too many OO programmers completely overlook:

In a database application the software does not interact with objects in the real world, it interacts with objects in a database.

This means that if I have a PERSON table in my database which holds data on people who are relevant to the organisation, then the software does not interact with a real person in the real world, it interacts with a person's data in the database. If I have a PRODUCT table in my database which holds data concerning the products which the organisation sells to customers, then the software does not interact with a real product in the real world, it interacts with a product's data in the database. Even though my enterprise application with its mixture of 15+ domains now handles over 400 database tables, each of which has a unique structure and content, there is one major characteristic that they all have in common - they are all database tables. Anyone with any experience of accessing a database will be aware that regardless of its actual structure and content every table in the database has to be handled in exactly the same way using the four operations which are built into every SQL database - Create, Read, Update and Delete, or CRUD for short. It does not matter that in the real world a real person has such operations as "stand", "sit", "walk", "run", "eat", "sleep" and "defecate", in a database there is only Create, Read, Update and Delete. It does not matter that in the real world a real product has such operations as "switch on", "switch off", "start", "stop", "forward" and "reverse", in a database there is only Create, Read, Update and Delete. It is exactly the same with every other object in the database - regardless of what operations are available to objects in the real world, for objects in a database the only operations available are Create, Read, Update and Delete.

I have seen documented in more than one article where programmers use the IS-A relationship to help them identify what should be an abstract class and what should be in a concrete class, and they make a fundamental mistake by saying something like "a CUSTOMER is-a PERSON, so I should make an abstract class called PERSON which I can then inherit into a concrete class called CUSTOMER". Similarly they say that "we sell widgets, and a widget is a PRODUCT, so we should have an abstract class called PRODUCT which I can then inherit into a concrete class called WIDGET". Unfortunately with this approach you can end up with a relatively large number of abstract classes containing small amounts of reusable code which can only be inherited by small numbers of concrete classes. They are so full of OO theory they try to make everything in the world conform to that theory, but this is a serious mistake. Relational databases and the Structured Query Language have their own way of doing things, and in order to be able to write efficient and effective database programs you need to build your software around the way that databases work instead of forcing the database to conform to the way that your software works. I dismiss complaints such as databases do not support inheritance simply because I have learned how to achieve the same results in an SQL way which then enables me to write code which conforms to the SQL way. By following "the SQL way" I am effectively "going with the flow" and sailing down stream with little effort. By "going against the flow" I would be putting in much more effort and achieving much smaller results.

While it is true that each of those subsystems/domains is completely different, most of those differences are encapsulated in the database structure while a relatively smaller number are implemented in program code. No matter how many different database tables you have (and I currently have over 400) each of those tables can only ever be accessed using the same four CRUD operations. The default method of performing these operations is to write code around a specific table with its specific structure, but after having done this several times an experienced programmer should see a great deal of repetition in the code. Because the only difference between one table and another is its structure, it should be possible to create an abstraction which is devoid of any particular table structure where the missing details can be supplied in a concrete implementation of that abstraction. That is why my abstract table class contains code which can be performed on any database table, while it is the concrete table class which marries the generic code with a particular database table and its particular structure.

The methods in my abstract table class perform a set of standard operations on an unknown database table with an unknown structure, and it is the concrete table class which provides the missing details. I do not write these classes by hand, I have a function within my framework's Data Dictionary which does this for me. I first have to import the structure of a physical database into my dictionary, then I export that information in the form of two files - a table class script and a table structure script. The idea of having two separate scripts is that is that the class file can be amended by the developer to include the code for any "hook" methods, while the structure file can be overwritten at any time following a change to the table's structure.

Instead of having limited amounts of inheritance from PERSON-to-CUSTOMER and PRODUCT-to-WIDGET, which would result in a large number of small abstractions, by realising that every object in the business/domain layer IS-A database table I am able to have a single large abstraction which can be inherited by any number of concrete classes. It does not matter how many tables I add to my database they can all be handled by code which exists within my abstract table class. When I create a new table in my database I do not have to create the class file and the structure file by hand, I get the framework to generate it for me. If I amend the structure of a database table I can make that change visible to my application simply by regenerating the structure file. Instead the framework provides usable templates which provide the basic working code, and all I have to do is populate the various "hook" methods with additional business logic

Using templates for more than operations

While this pattern was designed to cover small operations or algorithms, and this is how most programmers use it, I have demonstrated in the previous sections that I use it for every possible operation that can be performed on any table in my database. As I write nothing but database applications which use hundreds of tables this means that I do not have to waste any of my valuable time in writing any of that boring and repetitive boilerplate code as a wrapper for the all-important business logic, I simply insert that business logic into the empty spaces provided by the framework.

However, my framework provides other forms of templates which go far beyond those which can be found as methods within my abstract table class. As I have said previously every task (user transaction or use case) in a database application will touch the database in some way, and some of these tasks, even though they access a different table, exhibit similar behaviour. Some of the screens involved may have similar structures. When you have written a significant number of user transactions, and I have written thousands, you may begin to recognise recurring patterns of structure and behaviour, but how can it be possible to put these patterns into code which can be reused and shared? The first thing you need to do is examine each individual user transactions and describe it in terms of the following:

The content portion is variable, but structure and behaviour can be repeated in various combinations, so the trick is to find a way to get the framework to provide the code for these two so that it does not have to be hand crafted by the developer. The starting point is to utilise an architectural pattern which breaks individual user transactions into separate components each of which is responsible for a different category of logic. I use the 3-Tier Architecture which is comprised of the following:

While implementing this architecture I found myself splitting the Presentation layer into two separate and distinct components, and a colleague later pointed out that by doing so I had also provided an implementation of the Model-View-Controller (MVC) design pattern which is comprised of the following:

The combination of these two patterns results in the architecture shown in Figure 3.

Figure 3 - MVC plus 3 Tier Architecture

model-view-controller-03a (5K)

It should be obvious from the above diagram that all business knowledge, which includes the execution of business rules, exists in the Business/Domain layer in the form of individual Model objects, one for each entity with which the application needs to be concerned. For a database application each of these entities is an object in a database, not the real world, and as each object in a database is a table I have a separate class for each table. Any code which is not specific to a single database table has been defined in an abstract table class which can therefore be inherited by every concrete table class. Having a single abstract class which is inherited by every Model class in the application means that I am able to use the Template Method pattern for all standard operations. As the only standard operations which can be performed on a database table are Create, Read, Update and Delete you should see that the use of this pattern could provide enormous benefits if implemented correctly.

Data Validation

Any experienced database programmer will tell you that one of the most important rules is that you validate every piece of data from the user before you construct the SQL query which puts that data into the database. If you try to insert the value "three" into a numeric field, or the value "today" into a date field, then the query will fail. Rather than letting the query fail you should detect the error in your code and throw it back to the user with an appropriate error message without every generating the query.

Every database table has a totally different structure with a different set of fields, so how is it possible to automate this validation process? The simple answer is that many programmers still write their own validation code for each individual database table because they don't know how it can be automated. I do not suffer from this mental blockage. One of the advantages of having the contents of the table structure file available to each table object is that it provides a complete list of all the columns/fields which exist in that table along with each field's specifications (data type, size, nullable, et cetera). All user data gets inserted into the table object in the form of an associative array of name=value pairs, so all I need do to validate the contents of this array is to compare it field by field with the contents of the $fieldspec array which consists of a series of name=specification pairs. Any competent programmer should see how easy it is to have standard code which can compare a field's value with its specifications. In my framework this code exists in my validation object.

Reusable Views

When I began rewriting my existing development framework in PHP I decided that all HTML output would be produced by XSL transformations using XML documents and XSL stylesheets. I had encountered this technique a few years earlier in my previous language, and I immediately saw its power and flexibility. I did some experiments to see how easy PHP could implement this idea, and I published my results in Using PHP 4's DOM XML functions to create XML files from SQL data and Using PHP 4's Sablotron extension to perform XSL Transformations. As shown in Generating dynamic web pages using XSL and XML I originally had to create a separate XSL stylesheet for each web page as it contained hard-coded references to each column from the application database in order to identify where it appeared on the screen and with what HTML control, but as I created more and more stylesheets I began a process of refactoring which eventually produced a series of Reusable XSL Stylesheets and Templates. This means that I can now create any web page in my application from a library of just 12 templates. As my ERP application currently has over 2,700 web pages that is an amazing amount of reusability. This also means that I have a single View component which can produce an HTML page using the data from any Model class with the aid of a simple screen structure file.

Reusable Controllers

It should be obvious to any programmer that if you have an object which contains a number of methods which can be called then you must have a separate object which calls those methods. That is why each Model requires a Controller. The Controller receives requests from the user, and translates those requests into one or more method calls on one or more Model objects. When the Model(s) have finished their processing the results are then passed to the View so that they can be presented to the user in the desired format.

This is where I avoided a common mistake made by far too many programmers. When it comes to performing the common CRUD operations on different database tables, such as Customer, Product and Invoice, I have seen too many implementations using method names which include the name of the object such as the following:

This approach is bad because it creates tight coupling between the Controller and the Model and makes it impossible to use a Controller with any other Model. It was obvious to me from the outset that the end result of each of those operations was to Create/Read/Update/Delete a record in the database table for which the object was responsible, so my approach has always been to use generic methods such as the following:

This meant that instead of code such as this:

require "classes/customer.class.inc";
$customer = new customer;
$result = $customer->insertCustomer($_POST);
-- or --
require "classes/product.class.inc";
$product = new product;
$result = $product->insertProduct($_POST);
-- or --
require "classes/invoice.class.inc";
$invoice = new invoice;
$result = $invoice->insertInvoice($_POST);

I could actually use code such as this:

<component script>
$table_id = 'customer';
-- or --
$table_id = 'product';
-- or --
$table_id = 'invoice';
-- followed by
require 'std.add1.inc';

<std.add1.inc>
require "classes/$table_id.class.inc";
$dbobject = new $table_id;
$result = $dbobject->insertRecord($_POST);

What I am actually doing here is using a component script to identify which Model (database table) needs to be acted upon before calling the page controller which performs those actions on that Model. The 'actions' are calls on method names which are defined within the abstract table class, so they are automatically available in every concrete table class. You should also notice that I do not unpick the contents of the $_POST array and load it into the object with a series of individual setters, I simply insert the entire array as a single argument on the method call. This is a perfect example of loose coupling as the controller is not inextricably tied to a particular Model - it can work with ANY Model regardless of its underlying database structure.

As I continued adding more and more components to my application I found myself creating more and more page controllers to handle different combinations of structure and behaviour, but these were always written in such a way that they were not tied to a particular table, they could function on any table whose identity was passed down in the $table_id variable. Note also that some Controllers can function on more than one Model, which means that several variables need to be passed down.

This means that in the execution of a user transaction (use case) the following components are involved:

Figure 4 - Components accessed within each User Transaction

template-method-004 (5K)

The following components (in green) are pre-written and provided by the framework:

This leaves the following components (in yellow) to be generated for each user transaction:

Data Dictionary

You may think that the work involved to create the components for a user transaction was so small that I need go no further, but you would be wrong. After doing this a few dozen times I found the process to be boring and repetitive, so I looked for a way to automate it. My first step was to automate the construction of the table class file and its associated table structure file. Instead of creating a process which read the table's structure and created the two files immediately I decided to introduce an intermediate step, which is why I created my Data Dictionary. This enabled me to capture the raw data provided by the dbms's INFORMATION SCHEMA and add enhancements before it is written out. This was initially because I needed a way to identify any relationships between the various tables, but over the years I have found the need to add even more information. There are three steps to this process:

  1. IMPORT - use an online screen to identify the table structure to be imported, and at the press of a button that information will be imported into the dictionary's own database.
  2. EDIT - use online screens to view and, if necessary, add additional details.
  3. EXPORT - press another button and the table's data will be exported as scripts in the file system. The table class file will only be created once, but the table structure file will be overwritten each time. If a table's structure changes over time then all that is necessary is to re-import and then re-export.

Transaction Patterns

Next to come under the microscope was the creation of the component script and the screen structure file. As I had already created a library of page controllers which I had documented in Transaction Patterns for Web Applications all I needed was a process which could take the name of a database table and the name of a pattern and, at the press of a button, generate the necessary scripts. I developed such a process by adding the Generate PHP scripts functionality to my Data Dictionary.

This process does more than create the PHP scripts, it actually writes the details to the MENU database so that the newly created transaction can be run immediately. The developer is then free to move it to any menu bar or navigation bar of his choice. It can also be added to the ROLE_TASK table so that only those users with that role can activate it.

As an example the most basic of transactions that may be required to view and maintain the contents of a database table is the forms family shown in Figure 5:

Figure 5 - A typical Family of Forms

LIST1 ADD1 DELETE1 ENQUIRE1 SEARCH1 UPDATE1 dialog-types-01 (1K)

Note: each of the boxes in the above diagram is a clickable link.

In this set of components the parent LIST1 screen will be available on a menu bar, while the 5 child screens will be available on the navigation bar of the parent. By using the procedures outlined above I can take any table in my application database, import it into my Data Dictionary, generate the class file, then generate and run the family of user transactions within the space of 5 minutes without having to write a single line of code - no PHP code, no SQL code, and no HTML code. The only code the developer has to write is that which deals with the unique business rules, and this is inserted into the relevant ready-made "hook" methods.

Some of my critics seem to think that my library of Transaction Patterns contains only those six shown in Figure 5 above, which is why they assume that my framework can only handle simple CRUD screens. If they opened their eyes and looked more closely they would see that my library actually contains about 45 different patterns, and as my main enterprise application has over 3,000 transactions which were each built from one of these patterns then it is safe to say that they have been seriously misinformed. Either that or they are blind and cannot see, or they do not have the mental intellect to understand what they see.

Reasons why other programmers cannot compete with my implementation

Even though the Template Method is supposed to be a well known pattern I have never seen any article which explains how other programmers have used it in their database applications. This is probably because they are physically prevented from doing so because they follow the wrong set of programming rules. When I say that they are following the wrong rules what I really mean is they insist on telling me at every possible opportunity that their rules are different from mine, and this leads them to believe that my rules must therefore be wrong. As I keep telling these people I am results oriented while they are rules oriented, and in this business the results which you achieve are more important than the rules you follow to achieve them. Below are some of these so-called "rules" which I do not follow:

  1. Having a separate class for each database table is not good OO

    Why not? I hear excuses such as "It's not done that way", but I have never heard any valid arguments which identify any actual problems which this approach causes. I have never read any description on "what is a class" which states that I should NOT have a separate class for each table. On the contrary I have even found a design pattern which actually allows it.

    Every object in my business/domain layer IS-A database table, and in such circumstances it is considered good practice to create an abstract class to deal with the common characteristics of an unknown database table, and then supply the missing details for a particular database table in a concrete class.

    It would be difficult to implement the Template Method pattern without the use of an abstract class, so the fact that you do not have an abstract class for accessing a database table means that you cannot use the Template Method for any database access.

  2. You should try object composition instead of inheritance

    If you bothered to read why this rule was created you would see that inheritance only causes problems when it is overused, usually by creating deep inheritance hierarchies and extending one concrete class to create a different concrete class. The Gang of Four book clearly states that one simple way to avoid any such problems is to only inherit from an abstract class, which is PRECISELY what I am doing.

  3. You are using the wrong design patterns

    There are no rules which state which design patterns I am or am not allowed to use, or how I am supposed to implement them. I will use or not use whatever patterns I see fit, and implement them in whatever way I see fit in order to get the job done as quickly and efficiently as possible. I am driven by results, not rules, so I will always ignore rules which prevent me from producing the best results.

  4. An object can only deal with a single database row

    Who says? If it is so wrong then why does Martin Fowler have a design pattern for it? If you bothered to understand how databases work you would realise that they work in data sets, not individual columns, so I pass sets of data from one object to another in the form of standard PHP arrays. This is, after all, how the $_GET or $_POST data from an HTML form is first presented to the PHP script. An array can contain any number of columns from any number of rows, and I see no reason to make my life more difficult than it need be by forcing each row to be in a separate object. This would make those screen which show multiple rows more difficult to code, and as a follower of the KISS principle I prefer to avoid unnecessary complications.

    An SQL SELECT query can return any number of columns from any number of rows, and with JOIN clauses can include columns from any number of other tables. By limiting an object to containing a single row from the database and a fixed set of column names I would be preventing the use of this powerful query, and as an experienced database programmer I see no reason to do so, especially when it is just to obey an artificial rule which was invented by someone who doesn't understand how databases work.

  5. You must use getters and setters to access your data

    Who says? Having a separate class property for each column in a table may be the way that you are taught, and this would indeed require the use of separate setters and getters, but this would also lead to far too much tight coupling. I avoid this code smell by aiming for loose coupling by passing sets of data between objects as arguments containing arrays. In this way I can alter the contents of the array at any time without having to change any method signatures or the code which calls those signatures.

  6. You must validate your data in the setter methods

    Who says? The only golden rule in database programming is that any data which you wish to add to your database MUST be validated before you send that data to the database otherwise the database query would fail. I do not use setters and getters in my code, instead I perform all the necessary validation using a standard validation object which is built into the framework.

  7. Your design is dependent on SQL

    You obviously do not understand what the term "dependency" means. You can only say that there is a dependency between my Presentation layer and my Data Access layer when there is a method call from my Presentation layer to my Data Access layer, but there is no such thing. Calls to the Data Access layer are only made by the Business layer, which is how things are done when implementing the 3-Tier Architecture. What you see in some parts of my Presentation layer are variables which contain fragments of what looks like SQL, but pieces of data are not the same as method calls.

  8. Your database schema is known to your domain layer

    So what? In a database application a significant portion of the business rules are encapsulated in the database schema, so it is only right that objects in the business/domain layer have knowledge of the structure so that they can apply the rules correctly.

  9. you must hide the fact that your software is communicating with database

    Who says? When you are writing an application whose sole purpose is to put data into and get data out of a database, then hiding the fact that you are communicating with a databases is just too stupid for words. It would be like writing a missile control system which doesn't know that it's controlling missiles, or an elevator control system which doesn't know that it's controlling elevators.

  10. You have the same data names in every layer

    So what? Can you identify a single problem that this causes? In all my years as a programmer I have never seen anyone attempt to use different names in different layers for the same piece of data. Not only that, some of the languages I have used insisted that the column names in the database were the same as the field names in the screen simply because no form of mapping was possible. It was standard practice then, and it is standard practice now.

  11. Your approach is too simple

    That is because I am an ardent follower of the KISS principle whereas you are obviously a follower of the KICK (Keep It Complex, Knucklehead) principle which is also known as Let's make it more complicated than it really is just to prove how clever we are.

  12. You have not achieved the correct separation of concerns

    Then you clearly do not understand what Separation of Concerns (SoC) really means. This rule also goes by the name Single Responsibility Principle (SRP) and it is not surprising that a lot of people are confused by it as it is very badly written. Any principle which is so badly written that it can be interpreted in 100 different ways, where 99 of those ways are wrong, should be consigned to the rubbish bin. The only descriptions of any use in the several articles which Robert C Martin has written on SRP were as follows:

    From The Single Responsibility Principle:
    This is the reason we do not put SQL in JSPs. This is the reason we do not generate HTML in the modules that compute results. This is the reason that business rules should not know the database schema. This is the reason we separate concerns.

    From Test Induced Design Damage?:
    GUIs change at a very different rate, and for very different reasons, than business rules. Database schemas change for very different reasons, and at very different rates than business rules. Keeping these concerns (GUI, business rules, database) separate is good design.

    In case you hadn't realised it the separation of GUI, business rules and database access describes the 3-Tier Architecture which is the main architectural pattern used in my framework.

  13. Your classes are too big

    This is related to the previous item where people don't understand the correct way to implement either SoC or SRP, so they resort to the primitive act of measuring an object's size. This proves that they can count, but not that they can think. It also proves that most of them are so stupid that they cannot count higher than 10 without taking their shoes and socks off. The correct separation of concerns is achieved when you implement either the 3 Tier Architecture or the Model-View-Controller design pattern, and if you looked at my development framework you would see that I have implemented both.

  14. You must not have more than N methods in a class

    Who says? There is no limit on the number of methods which a class may contain, nor the number of lines of code within a method. The only golden rule is that once you have identified an entity which needs to go into your business/domain layer then you construct a class for that entity which contains ALL the methods and ALL the properties which are related to that entity. This is what encapsulation is all about. Putting all methods which are related to the same object in a single class results in high cohesion, which is supposed to be good.

  15. A Model can only have one Controller

    Who says? In a multi-layered architecture such as the 3 Tier Architecture such a thing is not only allowed it is actively encouraged. The whole purpose of separating the Presentation layer from the Business layer is that it is then possible for a single object in the Business layer to be accessed by multiple objects in the Presentation layer in order to deal with different views or different behaviours. If you look at the family of forms in Figure 5 you will see 6 user transactions using 6 different page controllers which all access the same Model.

  16. A Controller can only speak to one Model

    Who says? Just because you never see sample code for a Controller which accesses more than one Model does not mean that it is forbidden to do so. I regularly encounter screens which have several distinct zones which need to be populated with data from different database tables, and it has always been standard practice for the code which constructs that screen to communicate with each database table's object individually instead of going through a single aggregate object. That is why I have LIST2, LIST3 and LIST4 patterns where the Controller communicates with multiple Models. I find it easier to use Controllers which talk to multiple Models than have single Models which are responsible for multiple tables.

  17. You must create a separate method for each use case

    Who says? This may seem like a good idea to the uninitiated, but by doing so you would be closing the door on the prime benefits of object oriented programming. Each user transaction (use case) is totally unique in that it performs a particular action on a particular part of a domain object, and by creating unique method names in your domain objects (Models in MVC) you would also need to duplicate those unique methods in the Controllers which communicate with those Models. Polymorphism is only possible when groups of objects share the same method names, which allows a Controller which calls those methods to operate on more than Model. All my Model classes inherit their methods names from the same abstract class, and as every Controller communicates with its Model via those method names it means that in my framework with its 45 Controllers and 400 Models this gives 45 x 400 = 18,000 yes EIGHTEEN THOUSAND opportunities for polymorphism.

As you should be able to see, by sticking to the simplest definitions of encapsulation, inheritance and polymorphism, by ignoring all these artificial pseudo-rukes and by aiming for high cohesion and loose coupling I am able to employ more instances of the Template Mthod patter, which in turn enables me to produce software at a more cost-effective rate than others.

Here endeth the lesson. Don't applaud, just throw money.

References

Here are some other heretical articles I have written on the topic of OOP:


counter