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 pattern also has its own wikipedia page.
I also found a reference to this pattern in The Art of Separation of Concerns which states the following:
One example where inversion of concerns can be seen is in the use of the Template Method pattern. This pattern is used to generalize the behavior of a process in order to allow variation through inheritance. When applying this pattern to an existing component, the steps performed by the desired process would be generalized and encapsulated in a base class. The existing component would then inherit from the new base class, maintaining only specialized behavior. Other types would then be free to inherit from the base class to provide variant implementations. This would be an example of inverting the concerns of an algorithm sequence.
In the book Applying UML and Patterns the author Craig Larman states the following:
38.11 Framework Design - Template Method Pattern
This pattern is at the heart of framework design. The idea is to define a method (the Template Method) in a superclass that defines the skeleton of an algorithm, with its varying and unvarying parts. The Template Methods invokes other methods, some of which are operations which may be overridden in a subclass.
Thus, subclasses can override the varying methods in order to add their own unique behavior at points of variability.
The Template Method Pattern illustrates the Hollywood Principle -Don't call us, we'll call you.
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 electronic forms at the front end, a relational database at the back end, and software in the middle which moves data between them and which processes the business rules. 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, often sending copies to other people so that they could carry out their part of the processing. 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 in order to access an application which is running on a remote server. 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. After working briefly with this pattern I immediately saw the benefits as it allowed multiple components in the Presentation layer to be access a single component in the Business layer, thus sharing the same business logic, 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, the "right" practices, or not implementing them in the "right way". Upon close examination I quickly realised that their definition of "not right" actually meant nothing more that "not the way that I was taught", but instead of recognising that this simply meant "different" they classified it as "wrong". I refused to accept this classification for one simple reason - my methods worked - and anyone with more than two brain cells to rub together should be able to tell you that something that works cannot be wrong just as something that does not work cannot be right. Not only do my methods work but they produce superior results by helping me create working software components with double the features in half the time. I quickly saw that changing my methods to mirror theirs would be a step backwards, not forwards, so I decided to ignore their criticisms. What they claimed to be "best practices" which they assumed were to be applied universally I dismissed as nothing more than "common practices" which only applied to a small group of individuals. I have worked with many different groups or teams of programmers in the past, and I observed that no two teams ever followed the same practices. Each team developed practices that worked best for them or which followed the personal preferences of the team leader. In some cases I encountered practices which were handed down by higher management and therefore treated as if they were cast in stone and immutable even though they were obviously out of date and no longer fit for purpose.
I bought the Gang of Four book to see what the fuss was about, but after a brief read I put it on a shelf where it has been gathering dust ever since. Each pattern had a scenario which described the circumstances in which that pattern could be applied, but as I could not recognise any of those scenarios in my code I could see no benefit in implementing any of those patterns, so I ignored them. Surprisingly this book did not include any reference to the 3-Tier Architecture, which made me assume that it was written as an academic exercise with no practical benefits. I do not write code to fit patterns, 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.
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 standard 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 from empty to non-empty. 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
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
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 in the subclass are populated with code. It just means that the standard code will be executed without being altered by any "hook" methods.
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 2003 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 these methods can be seen in UML diagrams for the Radicore Development Infrastructure. For a complete list of the template methods in my framework you should take a look at this sequence of events which shows a list of public methods on the left and the sequence of internal methods on the right. If you look at insertRecord and updateRecord you will see that some of these templates contain a large number of steps.
Note also that the data for each column for each concrete class is NOT held within a separate class property but instead is passed around in a single array, which usually starts off as being the $_POST array which is received by the application when the user presses a SUBMIT button in an HTML document. This means that the same code in the abstract class is able to work with ANY concrete class regardless of what data is handled by that concrete class.
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.
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 standard or 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 (such as an abstract class), and leave the low-level details to the individual components (such as a concrete class which inherits from that abstract class). 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:
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 in the Presentation layer 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 aspects of a particular domain, and the software is then designed and built around these unique aspects. 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. Every user transaction that I build (and I have built thousands) implements one of my Transaction Patterns in the Presentation layer, and every method called by a Controller on a Model is an instance of a template method.
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 OO 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 with its own database structure, its own rules in the Business layer and its own components in the Presentation layer, an experienced programmer should be able to look deeper and see where there are similarities:
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 table 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 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 them 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
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
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.
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 in the $fieldarray array with its specifications in the $fieldspec array. In my framework this code exists in my validation object.
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 3,500 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.
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 in the form of a GET or POST request, 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 in the form of an array 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
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:
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:
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
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,500 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.
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:
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.
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.
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.
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.
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.
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.
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.
The fact that my framework uses nothing but SQL in the DAO is irrelevant as I do not envisage ever using anything but a relational database (RDBMS), and the only way to access an RDBMS is to use SQL. Note that I am not tied to using a single RDBMS as I support a number of the most popular ones.
Saying that a database application is dependent on SQL is as pointless as saying a web application is dependent on HTML. The only way to communicate with a relational database is to send it SQL queries, and the only way to communicate with a web browser is to send it HTML documents. Why are you questioning the obvious?
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. The only golden rule in the 3 Tier Architecture, which I never break, is that only the Data Access layer can communicate with the database, just as only the Presentation layer can communicate with the user. Even a novice programmer should be able to understand that "knowledge of" is not the same as "communicate with".
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.
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.
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.
One criticism I received in a blog post said:
If you have one class per database table you are relegating each class to being no more than a simple transport mechanism for moving data between the database and the user interface. It is supposed to be more complicated than that.
You are missing the point. What you describe as "a simple transport mechanism for moving data between the DB and the UI" is part of the standard functionality of each and every table class and is provided by the invariant methods which are inherited from the abstract table class. All non-standard code (i.e. processing which is unique to individual table classes) is added in by inserting the relevant implementations into one or more of the variable "hook" methods which you can insert into that table subclass. Every table object contains a mixture of standard (boilerplate) code and non-standard (custom) code, but with my use of the Template Method Pattern the developer does not have to spend any time in writing standard code as that is provided by the framework and automatically shared by each component.
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.
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.
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.
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.
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.
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 one 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 40 Controllers and 450 Models this gives 40 x 450 = 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-rules and by aiming for high cohesion and loose coupling I am able to employ more instances of the Template Method Pattern, 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.
Here are some other heretical articles I have written on the topic of OOP: