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

From Oop to Poop, from Excellent to Excrement, from Gold to Garbage

Posted on 1st February 2022 by Tony Marston

Amended on 16th April 2022

Introduction
What are "Best Practices"?
What are the benefits of OOP?
How using OOP increased my productivity
What is my definition of "Excellent"?
What is my definition of "Excrement"?
Ideas which score highly on the Faecal Scale (Shit List)
Confusion over what the term "Object Oriented Programming" actual means.
OOP requires a totally different thought process
OO programming is totally different from Procedural programming
What is the meaning of Encapsulation?
What is the meaning of Inheritance?
What is the meaning of Polymorphism?
Confusion about the word "type"
Confusion about the word "state"
Confusion about the word "interface"
Confusion about the words "use", "overuse", "misuse" and "abuse"
Confusion about the words "format", "transform" and "convert"
Confusion about the words "can" and "should"
Confusion about Design Patterns.
Confusion about the words "Information Hiding"
Confusion about the words "responsibility" and "concern"
Confusion about the Single Responsibility Principle (SRP)
Confusion about Separation of Concerns (SoC)
Confusion about Dependency Inversion and Dependency Injection
Confusion about Inversion of Control (IoC)
Confusion about Object-Relation Mappers (ORM)
Using OOP has no benefits until the first rewrite
Conclusion
References
Amendment History
Comments

Introduction

The purpose of this document is to answer my critics who insist on claiming that my methods of implementing the principles of OOP are inferior, wrong, impure and "not proper OOP" despite the fact that I can prove that my results are superior to theirs. They claim that I am not following "best practices" when what they actually mean is that I am not following the same set of practices as them. By constantly promoting their questionable versions of "best practices" and miscomprehension of basic programming principles, by constantly criticising me for having the audacity to voice an opinion which is different from theirs, by constantly promoting dogmatism over pragmatism, these people are steering the next generation of computer programmers down the wrong path. This will, in my humble opinion, prevent them from creating efficient and cost-effective software, so can have nothing but a detrimental effect on the whole of our industry.

What are "Best Practices"?

The idea that there exists a single set of "best practices" which all programmers are required to follow is complete and utter nonsense. Different groups have their own ideas on what is best for them, so I choose to follow those ideas which are best for me and the types of application which I write, ideas which have been tried and tested over several decades using several programming languages. This is in keeping with the following definitions:

Best practices are a set of guidelines, ethics, or ideas that represent the most efficient or prudent course of action in a given business situation.

Best practices may be established by authorities, such as regulators, self-regulatory organizations (SROs), or other governing bodies, or they may be internally decreed by a company's management team.

Investopedia

Notice here that it uses the term guidelines and not rules which are set in concrete and must be followed by everybody. Note also the phrase represent the most efficient or prudent course of action in a given business situation - if my business situation is different to yours then why should I follow your practices? I also do not recognise any governing bodies who have the authority to dictate how software should be written. There is no such thing as a "one size fits all" style as each team or individual is free to use whatever style fits them best.

A best practice is a method or technique that has been generally accepted as superior to any alternatives because it produces results that are superior to those achieved by other means or because it has become a standard way of doing things, e.g., a standard way of complying with legal or ethical requirements.

Wikipedia

When it comes to software development the only "requirement" that I recognise is the production of the most cost-effective results for the benefit of the paying customer. The term "cost-effective" includes the ability to both create software in a timely manner as well as to maintain it afterwards. I have seen code which has been written to conform to some of these weird ideas of "best practices", and I can immediately see the convoluted code which it produces and the productivity levels which are far below mine, so I feel confident in saying that my results are superior which means that my development methodology, my personal programming style, is also superior to theirs. My personal style has been the product of reviewing many different styles in my many decades of experience, and I have elected to adopt those styles which produce the best results and to ignore those which don't.

My reply to these critics can be summed up as follows:

If I were to follow the same methods as you then my results would be no better than yours, and I'm afraid that your results are simply not good enough. The only way to become better is to innovate, not imitate, and the first step in innovation is to try something different, to throw out the old rules and start from an unbiased perspective. Progress is not made by doing the same thing in the same way, it requires a new way, a different way.

If my development methodology and practices allow me to be twice as productive as you, then that must surely mean that my practices are better than yours. If my practices are better then how can you possibly say that your practices are best?

What are the benefits of OOP?

Switching from one programming paradigm and/or language to another should not be undertaken lightly. There should be some discernible benefits otherwise you will be taking a step backwards. While researching the meaning of OOP I found the following statements on the internet:

The power of object-oriented systems lies in their promise of code reuse which will increase productivity, reduce costs and improve software quality.
OOP is easier to learn for those new to computer programming than previous approaches, and its approach is often simpler to develop and to maintain, lending itself to more direct analysis, coding, and understanding of complex situations and procedures than other programming methods.

How do I write programs which are Object Oriented? All I had to go on at that time was the PHP manual plus some simple examples which I found online. This taught me how to create classes and how to use inheritance, but the descriptions of polymorphism were a bit vague, with no usable examples, so I had to work that out for myself.

How using OOP increased my productivity

Reading the PHP manual and experimenting with simple implementations was enough to teach me the mechanics of OOP, so I used this knowledge to rewrite in PHP the development framework which I had first designed and built in COBOL in the 1980s, then again in UNIFACE in the 1990s. The only applications which I design and build are database applications for businesses, which are more commonly known today as enterprise applications. In order to speed up the development of these applications I created frameworks which provided standard functionality as well as libraries of common subroutines. Both of the early frameworks were praised by my employer, a software house developing bespoke systems, as they helped the entire development team to become more productive and thus better able to compete against rival software houses. After switching to PHP as my main language I completely redeveloped this framework to take advantage of what the language had to offer, and I can only regard the result as a complete success. Why? With each change in language, with its new capabilities, I became more productive when developing a family of basic CRUD forms, as the following figures will show:

How did I achieve this significant improvement in productivity? I did not follow the rules of Object Oriented Programming, Object Oriented Design (OOD), Domain Driven Design (DDD) or any other formalised design process, nor did I try to implement any Design Patterns or follow the SOLID principles. Why not? Simply because I did not know they existed. Instead I learned to combine my prior experience of building dozens of different database applications with the principles of OOP which I read from the PHP manual and various online tutorials.

I am a pragmatist, not a dogmatist, which means that I judge whether my methods are successful or not based on the results which I achieve. A dogmatist, on the other hand, will insist on blindly following a set of rules, or a particular interpretation of those rules, and automatically assume that their results will be acceptable. This to me is a false assumption. Writing code which is acceptable to other programmers is not the aim of the game, it is writing code which is acceptable to the paying customer. If I can achieve significantly higher levels of productivity by breaking someone's precious rules then it proves that it is their rules which are worse than mine. Any methodology which fulfills the promises made for OOP can be regarded as excellent while everything else can be regarded as excrement, poop, faeces, dung or crap.

If you think that my claims of increased productivity are false and that you can do better with your framework and your methodologies then I suggest you prove it by taking this challenge. If you cannot achieve in 5 minutes what I can, then you have failed.


What is my definition of "Excellent"?

Any methodology which helps a programmer to achieve high rates of productivity should be considered as a good methodology. This can be done by providing large amounts of reusable code, either in the form of libraries, frameworks or tools, which the programmer can utilise without having to take the time to write his own copy. It should be well understood that the less code you have to write then the less code you have to test. Being able to produce cost-effective software in less time than your competitors means that your Time to Market (TTM) is quicker and, as time is money, your costs will be lower. Both of these factors will be appreciated by your paying customers much more than the "purity" of your development methodology.

So how much reusable code do I have? Take a look at a simplified diagram of my application structure in Figure 1:

Figure 1 - A simplified view of my application structure

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

As you should be able to see this is a combination of the 3-Tier Architecture and the Model-View-Controller (MVC) Design Pattern. A more detailed diagram, with explanations, can be found in RADICORE - A Development Infrastructure for PHP.

In his article How to write testable code the author identifies three main object categories:

The components in the RADICORE framework fall into the following categories:

It should also be noted that:

This arrangement helps me to provide these levels of reusability. This means that after creating a new table in my database I can do the following simply by pressing buttons on a screen:

Note that the whole procedure can be completed in just 5 minutes without having to write a single line of code - no PHP, no HTML, no SQL. If you cannot match THAT level of productivity then any criticisms that my methods are wrong and will always fall on deaf ears.

Note that some people claim that my framework can only be used for simple CRUD applications. These people have obviously not studied my full list of Transaction Patterns which provides over 40 different patterns which cover different combinations of structure and behaviour. I have used these patterns to produce a large ERP application which currently contains over 4,000 user transactions which service over 400 database tables in over 20 subsystems. While some of these user transactions are quite simple there are plenty of others which are quite complex.


What is my definition of "Excrement"?

I have often been told that you shouldn't be doing it that way, you should be doing it this way. When I look at what they are proposing and see immediately that it would have a negative impact on either the elegance of my code and/or my levels of productivity then I simply refuse to follow their "advice". I have yet to see any suggestion which would improve my code, but I have seen many that would degrade it beyond all recognition. Rather than saying "let's run it up the flagpole and see who salutes it" these ideas fall into the category of "let's drop it in the toilet bowl and see who flushes it".

What is the cause of these bad ideas? Ever since I have been perusing the internet reading other people's ideas and posting ideas of my own on various forums I have come to the conclusion that there are two contribution factors - poor communication and poor comprehension.

These problems are exacerbated by peculiarities in the English language:

This means that when being read by a clueless newbie the meaning of a sentence can be ambiguous instead of exact, and if there is any room for ambiguity then some people will always attach the wrong meaning to a word and therefore end up with a corrupted meaning for the sentence which contains that word. If that same person uses different words to explain that corrupted meaning to a third party then it can become even more corrupt. The more people the message passes through the more likely it is that it gets more and more corrupted, just like it does in the children's game called Chinese Whispers.

There are also some other problems which can add to the confusion:


Ideas which score highly on the Faecal Scale (Shit List)

Listed below are some of the stupid ideas, or misinterpretations of good ideas, which I believe result in crap code:

Confusion over what the term "Object Oriented Programming" actual means.

If you ask 10 different programmers what OOP really means you will get 10 different answers, and almost all of these will be so far off the mark I am truly amazed that their authors can get away with calling themselves "professional OO programmers". I have highlighted some of these goofy ideas in What OOP is NOT.

The only simple description I have ever found for OOP goes like this:

Object Oriented Programming is programming which is oriented around objects, thus taking advantage of Encapsulation, Polymorphism, and Inheritance to increase code reuse and decrease code maintenance.

Note here that I am only describing those three features which differentiate an OO language from a Procedural language. Some people seem to think that OO has four parts, with the fourth being abstraction. I do not agree. If the language manual does not show the keyword(s) which implement one of these parts the that part cannot be a feature of the language, it is only a design concept.

Many other descriptions of the "requirements" of OOP refer to additions which were made at a later date to different OO languages. I do not regard these additions as being part of the founding principles, so I ignore them if I don't like them.

Anybody who takes the time to study my framework in detail, either by reading the copious amounts of documentation or by examining and running the sample application or the full framework which can be downloaded, should very quickly see that the amount of reusable code which is provided means that new user transactions can be created very quickly. More reusable code equates to higher levels of productivity, and methodologies which directly contribute to higher productivity should be regarded as being superior to those which don't.

When I am told that I should be following the same set of rules and practices as other "proper" OO programmers just be "be consistent" and not "rock the boat" I refuse as, in my humble opinion, the dogmatic adherence to a series of bad rules will do nothing but make me "consistently bad". Further thoughts on this topic can be found at:


OOP requires a totally different thought process

I disagree. OO programming and Procedural programming are exactly the same except the former supports encapsulation, inheritance and polymorphism while the latter does not. They are both concerned with writing imperative statements which are executed in a linear fashion with the only difference being the way in which code can be packaged - one uses plain functions while the other uses classes and objects. Further thoughts can be found at:


OO programming is totally different from Procedural programming

I disagree. A person called Yegor Bugayenko made the following dubious statements in various blog articles:

Inheritance is bad because it is a procedural technique for code reuse. .... That's why it doesn't fit into object-oriented programming.

Inheritance Is a Procedural Technique for Code Reuse

I disagree. Inheritance does not exist in procedural languages, therefore it cannot be "a procedural technique for code reuse". Inheritance is one of the 3 pillars of OOP, so to claim that "it doesn't fit into object-oriented programming" is ridiculous beyond words.

Code is procedural when it is all about how the goal should be achieved instead of what the goal is.

Are You Still Debugging?

I disagree. You are confusing imperative programming, which identifies the steps needed to perform a function, with declarative programming, which expresses the rules that a function should follow without defining the steps which implement those rules.

A method is procedural if the name is centered around a verb, but OO if it is centered around a noun.

Are You Still Debugging?

I disagree. Classes in the business/domain layer, which represent the Model in MVC, represent entities, and entities are nouns, Methods represent the operations that can be performed on that entity, and operations (functions which can be performed) are always verbs.

Having used both procedural and OO languages for nearly 20 years apiece I have observed the following:

OO programming is exactly the same as procedural programming except for the addition of encapsulation, inheritance and polymorphism.

In his article All evidence points to OOP being bullshit John Barker says the following:

Procedural programming languages are designed around the idea of enumerating the steps required to complete a task. OOP languages are the same in that they are imperative - they are still essentially about giving the computer a sequence of commands to execute. What OOP introduces are abstractions that attempt to improve code sharing and security. In many ways it is still essentially procedural code.

In his paper Encapsulation as a First Principle of Object-Oriented Design (PDF) Scott L. Bain wrote the following:

Object Orientation (OO) addresses as its primary concern those things which influence the rate of success for the developer or team of developers: how easy is it to understand and implement a design, how extensible (and understandable) an existing code set is, how much pain one has to go through to find and fix a bug, add a new feature, change an existing feature, and so forth. Beyond simple "buzzword compliance", most end users and stakeholders are not concerned with whether or not a system is designed in an OO language or using good OO techniques. They are concerned with the end result of the process - it is the development team that enjoys the direct benefits that come from using OO.

This should not surprise us, since OO is routed in those best-practice principles that arose from the wise dons of procedural programming. The three pillars of "good code", namely strong cohesion, loose coupling and the elimination of redundancies, were not discovered by the inventors of OO, but were rather inherited by them (no pun intended).

What is the meaning of Encapsulation?

I have seen many descriptions of encapsulation which insist on including data hiding which, in my humble opinion, is derived from a misunderstanding of the term implementation hiding. Encapsulation, when originally conceived, did not specify data hiding as a requirement, and when PHP4 was released with its OO capabilities it not not include property and method visibility, so I never used it. Even though it was added in later versions of PHP I still don't use it. Why not? Simply because my code works without it, and adding it would take time and effort with absolutely no benefit.

The true definition of encapsulation is as described in What is Encapsulation? as follows:

In object-oriented computer programming languages, the notion of encapsulation (or OOP Encapsulation) refers to the bundling of data, along with the methods that operate on that data, into a single unit. Many programming languages use encapsulation frequently in the form of classes. A class is a program-code-template that allows developers to create an object that has both variables (data) and behaviors (functions or methods). A class is an example of encapsulation in computer science in that it consists of data and methods that have been bundled into a single unit.

Encapsulation may also refer to a mechanism of restricting the direct access to some components of an object

Note that the second paragraph includes the word may, so the ideas of object visibility are option, not a requirement.

My own personal definition of encapsulation is concise and precise:

The act of placing data and the operations that perform on that data in the same class. The class then becomes the 'capsule' or container for the data and operations. This binds together the data and functions that manipulate the data.

Note that this definition states that ALL the data and ALL the methods which operate on that data should be defined in the SAME class. Some clueless newbies out there use a warped definition of the Single Responsibility Principle to say that a class should not have more than a certain number of properties and methods where that number differs depending on whose definition you are reading.


What is the meaning of Inheritance?

This has a fairly simple definition:

The reuse of base classes (superclasses) to form derived classes (subclasses). Methods and properties defined in the superclass are automatically shared by any subclass. A subclass may override any of the methods in the superclass, or may introduce new methods of its own.

Note that I am referring to implementation inheritance (which uses the "extends" keyword) and not interface inheritance (which uses the "implements" keyword).

While it is possible to create deep inheritance hierarchies this is a practice which should be avoided due to the problems noted in Issues and Alternatives. People who encounter problems say that the fault lies with the concept of inheritance itself when in fact it lies with their implementation. This is why they Favour Composition over Inheritance. In Object Composition vs. Inheritance I found the following statements:

Most designers overuse inheritance, resulting in large inheritance hierarchies that can become hard to deal with. Object composition is a different method of reusing functionality. Objects are composed to achieve more complex functionality. The disadvantage of object composition is that the behavior of the system may be harder to understand just by looking at the source code. A system using object composition may be very dynamic in nature so it may require running the system to get a deeper understanding of how the different objects cooperate.
[....]
However, inheritance is still necessary. You cannot always get all the necessary functionality by assembling existing components.
[....]
The disadvantage of class inheritance is that the subclass becomes dependent on the parent class implementation. This makes it harder to reuse the subclass, especially if part of the inherited implementation is no longer desirable. ... One way around this problem is to only inherit from abstract classes.

This tells me that the practice of inheriting from one concrete class to create a new concrete class, of overusing inheritance to create deep class hierarchies, is a totally bad idea. This is why in MY framework I don't do this and only ever inherit from an abstract class. While inheritance itself is a good technique for sharing code among subclasses, the use of an abstract class opens up the possibility of being able to use the Template Method Pattern which is described in the The Gang of Four book as follows:

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.

Template methods lead to an inverted control structure that's sometimes referred to as "The Hollywood Principle" 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.

Not only do I *NOT* have any problems with inheritance, by using it wisely I not only have the benefits of sharing code contained in an abstract class I have the added benefit of increasing the amount of code I can reuse by implementing the Template Method Pattern for every method which a Controller calls on a Model.

If I am following the advice of experts and only inheriting from an abstract class and making extensive use of the Template Method Pattern, both of which provide a great deal of reusable code, and you are not, then how can you possible say that your practices are better?

Some clueless newbies claim that inheritance is now out of date and that I am not following the latest "best practices" by still using it. I dismissed these ridiculous claims in Your code uses Inheritance. Other ridiculous claims can be found at the following:

Inheritance breaks encapsulation.

I read this statement in several places but immediately dismissed it as hogwash as there was no explanation as to how inheritance breaks encapsulation. The author obviously had the wrong end of the stick regarding either one or both of these terms. I eventually found this description in wikipedia:

The authors of Design Patterns discuss the tension between inheritance and encapsulation at length and state that in their experience, designers overuse inheritance. They claim that inheritance often breaks encapsulation, given that inheritance exposes a subclass to the details of its parent's implementation. As described by the yo-yo problem, overuse of inheritance and therefore encapsulation, can become too complicated and hard to debug.

This description immediately tells me that inheritance itself is not a problem, it is the overuse of inheritance, especially when it results in hierarchies which go down to many levels, which is the problem. The notion that "inheritance exposes a subclass to the details of its parent's implementation" also strikes me as being hogwash. If you have class "B" which inherits from class "A" then all those methods and properties defined in class "A" are automatically available in class "B". That is precisely how it is supposed to work, so where exactly is the problem? If you have any bugs in your code which use inheritance then I'm afraid that there must be bugs in your code and not the concept of inheritance itself.

Inheritance produces tight coupling.

A clueless newbie called TomB criticised my use of inheritance with the following statement:

Your abstract class has methods which are reusable only to classes which extend it. A proper object is reusable anywhere in the system by any other class. It's back to tight/loose coupling. Inheritance is always tight coupling.

I debunked his claim in this article.

Favour Composition over Inheritance.

The first time I came across this principle several questions jumped into my mind:

I could see no answers to any of these questions, so I dismissed this principle as being unsubstantiated.

This is supposed to be a solution to the problem that Inheritance breaks encapsulation. As that problem does not exist in my framework I have no need for that solution. Object Composition would not give me anywhere near the same amount of reusable code with so little effort, and as one of the principle aims of OOP is to increase the amount of reusable code I fail to see why I should employ a method which does the exact opposite.

My main gripe about object composition is that it plays against one of the primary aims of OOP which is to decrease code maintenance by increasing code reuse. Directly related to this is the amount of code you have to write in order to reuse some other code - if you have to write lots of code in order to take an empty object and include its composite parts then how is this better than using inheritance which requires nothing but the single word extends?


What is the meaning of Polymorphism?

When attempting to discover a meaningful definition of this concept which showed how it could be used to provide reusable code I came across the following statement in this wikipedia article:

In programming languages and type theory, polymorphism is the provision of a single interface to entities of different types or the use of a single symbol to represent multiple different types.

I did not find this description useful at all due to my confusion with the words interface and type. I was even more confused with the different flavours of polymorphism. Which flavors could I use in PHP? Which flavors should I use in PHP? Which flavour provided the most benefits? Instead of attempting to implement polymorphism according to a published definition (which I could not find) I just went ahead and implemented the concepts of encapsulation and inheritance to the best of my ability and hoped that opportunities for polymorphism would appear somewhere along the line.

It just happened that after building my first Page Controller which operated on a particular table class, where the name of that table class was hard-coded into that Controller, I wanted to use the same Controller on a different table class but without duplicating all that code. I quickly discovered a method whereby, instead of hard-coding the table's name I could inject the name of the table class by using a separate component script which then passes control to one of the standard Page Controllers which are provided by the framework, one for each Transaction Pattern.

Eventually I came across a less confusing description (I forget where) which simply defined polymorphism as:

Same interface, different implementation

This enabled me to expand it into the following:

The ability to substitute one class for another. This means that different classes may contain the same method signature, but the result which is returned by calling that method on a different object will be different as the code behind that method (the implementation) is different in each object.

This meant that, because of the architecture which I had designed, and the way in which I implemented it, I had stumbled across, by accident and not by design, an implementation of polymorphism which provided me with enormous amounts of reusable components. The mechanics of the implementation are as follows:

In this way I satisfy the "same interface" requirement by having the same methods available in every concrete table class via inheritance from an abstract table class.

I satisfy the "different implementation" requirement by having the constructor in each concrete table class load in the specifications of its associated database table, with various "hook" methods being available in every subclass to provide any custom processing.

This means that if I have 45 Page Controllers which can be used with any of my 400 table classes then I have 18,000 (yes, EIGHTEEN THOUSAND) opportunities for polymorphism. How many do you "experts" have?

Yet there are still some clueless newbies out there whose understanding of polymorphism is so warped that they have the audacity to criticise my implementation. If you take a look at What Polymorphism is not you will see false arguments such as:


Confusion about the word "type".

Do you remember Hungarian Notation? This was invented by a Microsoft programmer called Charles Simonyi, and was supposed to identify the kind of thing that a variable represented, such as "horizontal coordinates relative to the layout" and "horizontal coordinates relative to the window". Unfortunately he used the word type instead of kind, and this had a different meaning to those who later read his description, so they implemented it according to their understanding of what it meant instead of the author's understanding. Thus they used it to differentiate between data types such as strings, integers, decimal numbers, floating point numbers, dates, times, booleans, et cetera. The result was two types of Hungarian Notation - Apps Hungarian and Systems Hungarian. You can read a full description of this in Making Wrong Code Look Wrong by Joel Spolsky.

Some bright spark in the world of OOP has subsequently added to the confusion by attaching an additional meaning - they use the word type when what they actually mean is class. This may be a shortening of the term abstract data type, in which case it should only apply to an abstract class and not a concrete class which inherits from it. For example, in my framework I have an abstract table class which contains properties and methods which can be shared by any database table, and a separate concrete table class for each table in the application database which contains the details, specifications and rules for that particular table. To say that each of these concrete table classes is of a different type is technically wrong as they are all database tables. They are subtypes (concrete implementations) of the abstract table class. If an idea or concept can be described using unambiguous terminology then, in my humble opinion, it is profoundly wrong to use terminology which already has several different and unrelated meanings. If the author of an idea cannot provide precise and unambiguous descriptions of that idea then the result will be misinterpretation which, in turn, will lead to faulty implementations of that idea.


Confusion about the word "state".

The word "state" has several meanings, among which are:

state (condition) - as in "The building was in a state of disrepair".

However, in computer science a system is described as stateful if it is designed to remember preceding events or user interactions; the remembered information is called the state of the system. This is in contrast to a stateless system which does not maintain any memory of its state between function calls.

In 2018 I came across an article called Objects should be constructed in one go in which Matthias Noback said:

When you create an object, it should be complete, consistent and valid in one go.

When I had the audacity to challenge this statement Matthias Noback, being a snowflake who cannot tolerate opinions which are different from his own, promptly deleted my response, which forced me to create my own article at Re: Objects should be constructed in one go. As far as I am concerned the true definition of a constructor is as follows:

The purpose of a constructor is to initialize an object into a sane state/condition so that it can accept subsequent calls on any of its public methods.

Notice here that the word state means condition. It does NOT mean that all the object's properties must be loaded with pre-validated data. It is perfectly acceptable to load and validate data using separate public methods.

Matthias Noback's opinion is in total contrast to that of Yegor Bugayenko who wrote an article called Constructors Must Be Code-Free. It is simply not possible for both of these opinions to be right, and as they both disagree with the true definition of a constructor I consider them both to be completely wrong and not worth the value of the toilet paper on which they are written.


Confusion about the word "interface"

Before I became involved in OOP I understood the word "interface" to be shorthand for Application Programming Interface (API) which has the following definition:

An application programming interface (API) is a connection between computers or between computer programs. It is a type of software interface, offering a service to other pieces of software. A document or standard that describes how to build or use such a connection or interface is called an API specification. A computer system that meets this standard is said to implement or expose an API. The term API may refer either to the specification or to the implementation.
[....]
One purpose of APIs is to hide the internal details of how a system works, exposing only those parts a programmer will find useful and keeping them consistent even if the internal details later change. An API may be custom-built for a particular pair of systems, or it may be a shared standard allowing interoperability among many systems.

All the API documentation which I read contained a list of function calls (sometimes called function or method signatures) which identified the function name and its input and output arguments, plus a description of what the function actually did. The code behind the function, the implementation, was never revealed.

Later, while reading articles on OOP, I came across some confusing references to the term "interface" which had a different meaning. I did not understand this meaning as PHP4 did not support this idea. I later discovered this meaning when PHP5 was released. I looked at how much additional code was required to implement this feature, then I looked for the benefits. Guess what? There ARE no benefits, just costs. All my existing code, which calls method signatures inside concrete classes, would not work any differently or faster by creating abstract classes using the word interface then modifying the concrete class to use the word implements. No matter how many articles I read which said that these new-fangled interfaces were the best thing since sliced bread I just could not see the point. As I already made extensive use of an abstract class in my framework I could see no need for abstract interfaces.

Those programmers who are aware of the history of OOP should know that interfaces were only added to some early languages to get around a deficiency in those languages. Modern languages, and this includes PHP, do not have this deficiency so interfaces have become a totally redundant fix to a problem which no longer exists. The "deficiency" is discussed in Object Interfaces.

I later came across the principle of program to the interface, not the implementation which confused me even more. If I am writing an application which has been divided into multiple smaller modules instead of a single huge block of monolithic code then I am automatically calling each module by its method signature without being concerned about that method's implementation. I know what the method does (or is supposed to do) but I do not know or even care about how it does it.

If this is the way that all modular software has behaved since computers were invented, then why is it expressed as a new rule just for OOP?


Confusion about the words "use", "overuse", "misuse" and "abuse"

I have seen far too many instances where someone with experience says "do not overuse/misuse/abuse X" where "X" can be almost anything, and this is immediately translated into "do not use X" by those who do not understand the difference in meaning. Here are some examples:


Confusion about the words "format", "transform" and "convert"

Although these three words are different they mean virtually the same thing:

Some while ago one of my critics, of whom there are many, said that the the existence of a method called formatData() in my abstract table class was proof that the class was doing too much and therefore violated SRP. He focussed his entire attention on the method name and did not look at what the method does or the volume of data on which it operates. In some cases it operates on only a single column of data while in other cases it operates on a whole file of data, as shown by the following functions in the PHP manual:

In his article Test Induced Design Damage? Robert C. Martin summarised his Single Responsibility Principle (SRP) as follows:

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.

This means, to me at least, that the code for each of those three areas - GUI, business rules, database - in your software should be maintained in separate modules and should not be allowed to mix. By building my framework around the 3 Tier Architecture I have done just that. Claiming that a method in the business layer with the name formatData() "proves" that I am violating SRP shows that the claimant does not fully understand what SRP means or how it is implemented in my framework.

The first two functions in the above list are used by that method to change the contents of individual columns of data according to the business rules for that particular installation. The processing of business rules belongs in the Business layer.

The third function, the XSL Transformation process operates on a collection of values which are pulled from the application components (one or more Models) in the form of PHP arrays and other data which is maintained by the framework. The HTML output which it produces is part of the GUI or Presentation layer. The conversion of raw data (PHP arrays) into the XML document, loading of the XSL stylesheet and transformation into HTML are all performed within a single View component. Note that there are separate components which produce CSV and PDF output.

You should therefore be able to see that in my framework all business logic is contained within the Business layer and all presentation logic is contained in the Presentation layer. This conforms to the separation of concerns identified by Robert C. Martin.

If you still think that my code breaks SRP then as far as I am concerned your opinion is not worth the toilet paper on which it is written.

Here are some similar claims which I have rejected:


Confusion about the words "can" and "should"

I have seen far too many instances where as soon as someone says "you can do so-and-so" a lot of newbie programmers act as if it was an instruction instead of a suggestion and rush to obey this new directive, even if it means amending code that already works. I have even been personally accused of being someone who still writes legacy code because I do not keep up with changes to the language and adopt a new feature or new syntax as soon as it becomes available and fashionable in the language. The fact that I still write code that uses a great deal of PHP4 syntax does not mean that my code will ONLY run in PHP4, it simply means that either I have no need for the new syntax or I cannot see the point in expending effort in changing code that works to exactly the same thing but differently. Any long-term user of PHP should be aware that 99% of the syntax which was available in PHP4 is still available in the current PHP8 version. The only time I change my code is in order to replace PHP4 syntax which has been removed in the latest version, so because my code still runs on the current version it cannot be classed as legacy code. I am a follower of the tried and tested It if ain't broke then don't fix it philosophy. If there are no tangible benefits to changing my code then why should I expend the cost? The following is a list of all those things that I could do, but which I refuse to do simply they do not offer the best solution.

My philosophy of not jumping on the bandwagon and refactoring my code as soon as a new feature comes along avoids the problem highlighted in When is Enough, Enough? I am not the only one who thinks that using the latest features in the language simply because they are shiny and new may not actually be a good idea. This is known as the Magpie Syndrome and is discussed by Matt Williams in his article Oooh Shiny! Magpies don't know what's just enough! as well as Does Your Team Have STDs?

You can model the real world

This is only advisable if you are writing software which interacts directly with objects in the real world, such as elevator systems, missile control systems, robotic machines or domestic appliances, etc. If like me you are writing nothing but enterprise applications which have electronic forms at the front-end and a relational database at the back-end you are most certainly NOT interacting or controlling any physical object, you are interacting with information about physical objects which is held in a relational database, and the only objects in a database are called tables. Regardless of what operations can be performed on a physical object, the only operations which can be performed on a database table are Create, Read, Update and Delete (CRUD).

It does not matter if a database contains hundreds of tables each of which represents a totally different external object, the structure of each and every table follows the same rules, and the structure of the SQL queries used to read and write that structure also follows the same rules. It does not matter that a person in the real world has operations such as stand, sit, walk, run, eat, sleep and defecate, for a "person" table in the database the only operations are Create, Read, Update and Delete. It does not matter if you are holding information on a variety of different physical products each of which has a totally different set of operations, for a "product" table in the database the only operations are Create, Read, Update and Delete.

You can treat everything as an object

I find this idea to be one of those things that sounds fine in theory but not so good in practice. In pre-OO procedural languages it was quite acceptable to treat every value as a primitive, such as integer, float, decimal, character string, date and time, which could be manipulated using functions. Then OOP came along and some purists decided that this approach was not good enough, that all values should be objects and could only be manipulated using object methods. For example:

Although both lines of code will produce exactly the same result there is one glaring problem which is hidden from view - PHP does not have value objects, so it requires a lot of work in the background before you can use them. In my humble opinion this extra effort is a complete waste of time as there is no benefit, only costs. The idea that "everything is an object" is a complete fallacy because when writing a program with an HTML front-end and an SQL back-end with some PHP code in the middle the following conditions exist:

This therefore means that if you wish to use value objects in your PHP code you have to do the following:

You then end up with lots of extra code to convert strings into objects and then back into strings, but where is the benefit? Does your code run faster? No. All this extra code guarantees that it will in fact be slower. Does it have fewer bugs? No. All this extra code provides the opportunity for more bugs, not less.

Some OO purists complain that my code is not 100% object oriented because it does not use value objects, but I ignore them for the simple reason that OOP does not require the use of value objects, and that I can still write cost-effective code using nothing more than encapsulation, inheritance and polymorphism.

I read a blog post some while ago in which the author claimed that value objects were absolutely essential for "proper" OO programming. To reinforce this statement he pointed out that numerous software applications, such as Order Processing, cater for a monetary value which includes a currency code. He insisted that this can only be dealt with "properly" by having a value object which combines both an amount and a currency code. The hole in this argument is that such a value object cannot be represented in either a relational database or an HTML document. In both they are separate fields with no physical connection, only a logical relationship. I have been developing such applications for 4 decades, and I have had no problem with dealing with currency amounts using two separate fields. Not only has there never been a need to combine them, none of the languages I have used have ever provided the ability to combine them.

You can create deep inheritance hierarchies

This follows on directly from the previous point. I have seen too many instances of a clueless newbie designing his first Sales Order Processing (SOP) system coming up with statements such a "we deal with customers, and each customer is a person, so we will need a Person class from which we can inherit to form a Customer class". This to me is total nonsense. I would never make such a division in my database design, and I see no reason why I should make that division in the design of the software which accesses that database design. The problem with trying to follow the description of an "IS-A" relationship on OO theory is that newbie programmers start from the wrong place and keep going in the wrong direction.

I never made this mistake for the simple reason that from my very first foray into the world of OOP, after several decades of writing database applications in non-OO languages, I recognised that every object in a database IS-A table, which is precisely why I create a separate class for each database table. I have been told by several clueless newbies that this means duplicating the code for each of the CRUD operations in each class, but I shoot this argument down in flames by pointing out that the sharing of common code among multiple classes is precisely why inheritance was invented. This is why I have created an abstract table class which contains the code which is common to every database table, and extend this class into a concrete subclass for each physical table to contain the code which is unique to that physical table. This arrangement of an abstract superclass and numerous concrete subclasses also means that I found it incredibly easy to implement the Template Method Pattern which is another technique for sharing code.

You can duplicate the code written by experts by using lots of design patterns

Ever since the first book on design patterns was published there have been numerous clueless newbies who think that since these patterns were written by "experts" all they have to do to write "export" code is to employ as many of these design patterns as possible. Please read Design Patterns - a personal perspective to see why this idea is wrong. People who employ principles indiscriminately without understanding the reasons behind those principles will always end up as being nothing more than Cargo Cult Programmers.

You can create aggregate objects

I could, but I don't. An aggregate object is one which contains one or more other objects. For example, in an application which deals with classrooms, teachers, students, subjects and lessons a clueless newbie might be tempted to put them all into a single aggregate object called "School". After all, by following the rules of the HAS-A relationship any object in the real world which contains other objects should automatically become the root in an aggregate object. This is obvious when you realise that a school is a container for classrooms, teachers and students.

I remember a newsgroup post many years ago from a clueless newbie who had designed such an aggregate object. When he started his application it read in all the classroom records, all the teacher records, all the student records, and all the other records which were part of that aggregation so that they were instantly available should they needed to be displayed. He complained that it was taking far too long to build this object which was causing his users to complain, and he had the audacity to complain that the whole concept of OOP was at fault. Every competent database programmer knows that it is far more efficient to only read data from the database when it is actually needed and not to preload it just in case it might be needed. That is why, in my Prototype Classroom Application, I completely avoid any aggregate objects and have a separate stand-alone object for each individual table. Each table then has its own set of user transactions in order to perform the different operations on that table. You can run this application yourself as one of the prototype applications in my online demonstration

The only point in Domain Driven Design with which I agree (I ignore everything else) is that you should model your software design to suit the domain which is being covered by your application. However, in my world where I have designed and built a large ERP application which includes a number of different subsystems I do not regard each of those subsystems as a separate domain, they are simply different instances of the same super-domain which is that of a database application. While each of these subsystems has its own set of unique aspects an experienced developer should see that they can all be covered by the same architectural structure. Regardless of the individual business rules the user transactions within each subsystem follow exactly the same pattern:

The biggest difference with each subsystem is he database design. Each subsystem has its own database with its own set of tables, and each table has its own unique structure of columns, primary keys, candidate keys and foreign keys. There are no such things as aggregate tables in a database, so why should I have aggregate objects in my software? Each table is a separate entity which follows the same rules as every other table and is accessed in exactly the same way as every other table. This is why I create a separate class for each database table to contain the structure and business rules for that table. I have been told many times that this is wrong and not the way that "proper" OO programmers do it, but I have yet to see any evidence to substantiate such claims.

Please refer to A minimalist approach to Object Oriented Programming with PHP - Object Aggregation for more details.

You can create a separate method for each use case

I could, but I don't. This is another part of Domain Driven Design which I ignore for the simple reason that it instantly disables a huge amount of reusability which is supposed to be one of the benefits of OOP in the first place. In my large ERP application I have over 4,000 use cases (which I call user transactions or tasks) and I never in a million years dream of creating a separate and unique method for each one. Every experienced database programmer knows that the only operations which can be performed on a table are Create, Read, Update and Delete (CRUD), so I have the same method name in each table class to support these standard operations. To avoid duplicating the same code in each table class I have defined these methods in an abstract table class which is then inherited by every concrete table class. This enabled me to implement the Template Method Pattern on a large scale whereby standard code which can be shared by every database table is defined inside invariant methods while custom code, that which is unique to each database table, is defined within variable/custom methods in each table's subclass. Having the same methods available in multiple classes provides the opportunity for polymorphism, so I question why why any competent OO programmer would choose a design which does not provide any polymorphism at all.

You can create a separate controller for each use case

I could, but I don't. In my early COBOL days it was common practice to create a single program for each database table which contained a collection of screens which dealt with the standard list/browse, add/create, enquire/read, update and delete operations. The program would then have function keys with different labels to enable the user to switch from one operating mode to another. This disadvantage to this approach was that every user could access every operating mode within every program, and this disadvantage became a real obstacle when a new client demanded that we built a system with some sort of Role Based Access Control (RBAC) which restricted access to each of the operating modes within each program to specific users. At first we tried adding code to each program to read the Access Control List (ACL) and to check after a function key was pressed if the user was allowed to access that function within that program, and to display an error message if not. The client did not like this approach. Instead of seeing a label which generated an error message if pressed he preferred not to see that label at all, meaning that each user could only see the labels for the functions which he was allowed to access while all others were hidden from view.

This made each program more and more complicated, so I decided that the best solution would be to split each "Maintain Table X" program which dealt with the five operating modes (list, add, enquire, update and delete) into five separate subprograms each of which dealt with a single operating mode for that table. Although this replaced a single large program with five smaller programs it actually made each subprogram much simpler, as documented in Component Design - Large and Complex vs. Small and Simple. I could also move the checking of the ACL out of each subprogram into a new standard control program (which I designed in a few hours one Sunday and had competed by the following Friday) which used a combination of menu screens and function keys to allow the user to select the next transaction. The details of each user transaction were stored on the M-TRAN table, details of users were held on the M-USER table, and details of menus were held on the M-MENU table. The list of transactions which were accessible by each user was stored in the D-TRAN-USER table. This also meant that all the menu screens were dynamic as details were assembled at runtime by reading the database instead of being static by having to hard-code each individual menu screen. The functional specification for this software can be found at Menu and Security System - Functional Specification.

This software was adopted as the company standard for all new projects. I created an implementation in UNIFACE in the 1990s and again in PHP in 2003.

You can load and retrieve object variables by using setters and getters

The idea of moving data between the software and the screen and between the software and the database one piece at a time, as with getters and setters, is something which I never encountered in any of my pre-OO languages. With COBOL all data was moved around in blocks called buffers, and each buffer had to be subdivided into its individual elements. With UNIFACE each database table was defined as an entity in the application model, and when building a form component you first painted a rectangle on the screen as an entity frame, then filled this frame with controls for each of that table's columns which you wished to be displayed. You could even paint a second entity frame within the first in order to display columns from a different table. Each screen could contain as many entity frames as you liked in whatever hierarchy you liked. After activating the "Retrieve" trigger UNIFACE would automatically read each table one record at a time starting with the outer-most entity and terminating with the inner-most entity. The data would automatically be loaded into the form component, and each columns value from the current record could be referenced using the column name, which could be prefixed with the table name if there was any ambiguity.

While COBOL had primitive arrays and UNIFACE had lists, I found PHP arrays to be much more powerful and flexible. When I noticed that data from an HTML form was presented to a PHP script in the form of the $_GET or $_POST array, and data from a database table was returned as an associative array using mysqli_fetch_assoc my instinctive reaction was to keep all application data in an array when passing it between the HTML form and the database. The idea that I not only could but should be using getters and setters to pass data around one column at a time never entered my head. When I saw example code that was written this way I immediately saw a bucket load of disadvantages, so I stuck to my original idea of passing all application data around in a single variable called $fieldarray, and is a decision which I have never regretted.

Another idea which I refuse to employ is to define each individual column as an argument on a method call. This has similar disadvantages as with using getters and setters. My method of using a single argument called $fieldarray which contains an unknown amount of data in an associative array (or an indexed array of associative arrays) has the following advantages:

Here is an example of the code which I use to insert data into any of the 400+ tables in my ERP application:

<?php 
require "classes/$table_id.class.inc";  // $table_id contains 'user'
$dbobject = new $table_id;
$fieldarray = $dbobject->insertRecord($_POST);
if (!empty($dbobject->errors)) {
    // do error handling 
} // if
?> 

The $dbobject->insertRecord($fieldarray) method is the start of a Template Method which has several steps.

Here is an example of the code which I use to read data from any of the 400+ tables in my ERP application:

<?php 
require "classes/$table_id.class.inc";  // $table_id contains 'user'
$dbobject = new $table_id;
$fieldarray = $dbobject->getData($where);
?> 

The $dbobject->getData($where) method is the start of a Template Method which has several steps.

Please notice the following:

Because neither of these scripts contain any hard-coded table names or column names they can operate on any of the 400+ database tables in my ERP application. I can add and remove tables and columns at will without having to make any corresponding changes to these scripts. This would be an example of loose coupling which is supposed to be a good idea. The use of getters and setters would require the use of scripts containing hard-coded column names, and this would be an example of tight coupling which is supposed to be a bad idea.

Please refer to A minimalist approach to Object Oriented Programming with PHP - Getters and Setters for more details.

You can treat each error as an exception

It now seems that all OO programmers are taught to use exceptions for every error, that they are a standard feature of OO, but this is not the case. They were invented to solve the Semipredicate problem where a function can only return a single output value which is either a valid result or an indication of failure (such as boolean FALSE) but without the ability to identify the actual reason for that failure. The solution is to change the function so that when it detects an error it can throw an exception which is separate from the normal result and which can then be caught by the calling code. While every OO language supports the use of exceptions with the try/catch block and the throw commands, it is completely wrong to use exceptions for every possible type of error. In this technopedia page it says the following:

An exception is an abnormal or unprecedented event that occurs after the execution of a software program or application. It is a runtime error of an undesired result or event affecting normal program flow.

An exception is also known as a fault.

Note that unless an error signifies an abnormal or unprecedented event then it should NOT be classed as an exception and should be dealt with in a different manner. Exceptions should only be used for software bugs which require corrective action by a developer and not for common occurrences such data validation errors. All user input should be validated before it is processed, and it is a common occurrence for a fat-fingered user to enter a wrong value into a field on the screen. The software should therefore check every value to ensure that it is of the correct type (number, date, et cetera) and if it is not then it should be rejected with a suitable error message, thus prompting the user to correct his mistake and try again. This type of error is not a fatal error as it does not cause the program to abort.

The significance of using exceptions for fatal errors only was highlighted many years ago when I read a comment from a developer who was working with an application which recorded each and every exception in a log file, and it was his job to search through this log file and identify every bug that needed to be fixed. Unfortunately for him over 99% of the log file entries were for non-fatal data validation errors which could be fixed by the user and not a developer, so he had a hard time sorting out the wheat from the chaff.

Please refer to A minimalist approach to Object Oriented Programming with PHP - Exceptions for more details.

You can use interfaces

My first OO language was PHP version 4. This did not provide support for object interfaces, so when I read several blog/newsgroup posts which used the word interface I assumed it meant the same as Application Programming Interface (API) which was the same as method signature. It wasn't until PHP5 was updated to include the keywords "interface" and "implements" that I realised there was a difference. My first thought was that the person who decided to use an existing term to means something else deserved a smack on the back of the head. The more I read about object interfaces the more convinced I became that they were a really bad idea and that refactoring my codebase to use them would be a complete waste of time. My reasons for reaching this conclusion were as follows:

Please refer to A minimalist approach to Object Oriented Programming with PHP - Object Interfaces for more details.

You can use namespaces

Namespaces were designed to solve a problem which I don't have, so I don't use them. They are an option, not a requirement, so I choose not to use them.

Please refer to A minimalist approach to Object Oriented Programming with PHP - Namespaces for more details.

You can use autoloaders

Autoloaders were designed to solve a problem which I don't have, so I don't use them. They are an option, not a requirement, so I choose not to use them.

Please refer to A minimalist approach to Object Oriented Programming with PHP - Autoloaders for more details.


Confusion about Design Patterns.

The wikipedia page on Software Design Patterns contains the following statements:

In software engineering, a software design pattern is a general, reusable solution to a commonly occurring problem within a given context in software design.
[....]
Design patterns are formalized best practices that the programmer can use to solve common problems when designing an application or system.

The big problem that clueless newbies have with design patterns is that they see the words "reusable solution" and "best practice" and they automatically assume that as those patterns were written by expert programmers then by employing as many patterns as possible in their code it will make it just as good as that produced by those experts. This idea is debunked in Design Patterns - a personal perspective and You don't understand Design Patterns.

In the article How to use Design Patterns there is this quote from Erich Gamma, one of the authors of the GOF book:

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.

One comment I saw in a news group just after patterns started to become more popular was someone claiming that in a particular program they tried to use all 23 GoF patterns. They said they had failed, because they were only able to use 20. They hoped the client would call them again to come back again so maybe they could squeeze in the other 3.

Trying to use all the patterns is a bad thing, because you will end up with synthetic designs - speculative designs that have flexibility that no one needs. These days software is too complex. We can't afford to speculate what else it should do. We need to really focus on what it needs. That's why I like refactoring to patterns. People should learn that when they have a particular kind of problem or code smell, as people call it these days, they can go to their patterns toolbox to find a solution.

I do not consider Design Patterns to be proper patterns at all for the simple reason that they do not provide anything which is actually reusable. They simply describe a pattern and then force you to provide your own implementation, and each implementation can be different. The only patterns I know of which actually provide implementations, and implementations which are reusable, are Transaction Patterns. I wrote further on this topic in Design Patterns are dead! Long live Transaction Patterns!


Confusion about the words "Information Hiding".

Time after time I see people use the 1972 paper On the Criteria To Be Used in Decomposing Systems into Modules written by D.L. Parnas to "prove" that the term "information hiding" is exactly the same as "data hiding". That paper contains the following words:

The second decomposition was made using 'information hiding" as a criterion.
...
Every module in the second decomposition is characterized by its knowledge of a design decision which it hides from all others. Its interface or definition was chosen to reveal as little as possible about its inner workings.

Notice that I highlighted the words to reveal as little as possible about its inner workings. In my humble opinion the words "inner workings" do not refer to the data which is operated upon but the internal implementation of the module (the operations which are performed on that data). In my experience this has been the way that every subroutine/function in every programming language has ever been documented - it lists a series of APIs which identify nothing but the function name and its input and output arguments (the function signature), plus a brief description of what its does. This description does not include the code which actually implements what it does. This means that the function's internal implementation can be changed at any time without necessarily having to change the function's signature.

Each class has both properties and methods, but it was never intended that properties had to be hidden and could only be accessed via a method instead of directly. If you don't believe me then take a look at the following articles:

This observation is taken from the C2 wiki:

- Encapsulation is a programming language feature.
- Information Hiding is a design principle.

This observation is taken from Nat Pryce's article:

- Encapsulation ensures that the behaviour of an object can only be affected through the object's API.
- Information hiding conceals how an object implements its functionality behind the abstraction of the object's API.

I have been writing database applications for 40 years, the last 20 of which have been dedicated to web applications. In all those pre-OO languages it was standard practice to pass all the table's data in a single argument on the procedure call as once that call had ended the procedure was terminated and all memory dropped. While making myself familiar with PHP I noticed two things:

These simple facts led me to the idea of creating object methods such as the following:

Anybody who knows anything about OOP should recognise that these are perfect examples of loose coupling, which is supposed to be a Good Thing. The idea that "proper" OO programmers should use getters and setters for each individual item of data never crossed my mind. Besides, this idea is a perfect example of tight coupling which is supposed to be a Bad Thing.


Confusion about the words "responsibility" and "concern"

While these words seem to have completely different meanings there is actually some overlap:

This means that the following sentences mean exactly the same thing:

Provided that the module in question has only one responsibility or concern then neither the Single Responsibility Principle (SRP) nor the Separation of Concerns (SoC) is violated. However, this does not stop some clueless newbies from inventing some perverse reasons why the two words are different which automatically makes the two principles different:


Confusion about the Single Responsibility Principle (SRP)

When I was first told "Your code breaks SRP" my first thought was "What the heck is SRP?" After a quick search on the internet I found this wikipedia article which stated:

The single-responsibility principle (SRP) is a computer-programming principle that states that every module, class or function in a computer program should have responsibility over a single part of that program's functionality, and it should encapsulate that part. All of that module, class or function's services should be narrowly aligned with that responsibility.

I then found Robert C. Martin's original article which stated the following:

This principle was described in the work of Tom DeMarco and Meilir Page-Jones. They called it cohesion. They defined cohesion as the functional relatedness of the elements of a module. In this chapter we'll shift that meaning a bit, and relate cohesion to the forces that cause a module, or a class, to change.

SRP: The Single Responsibility Principle

A CLASS SHOULD HAVE ONLY ONE REASON TO CHANGE.

In my humble opinion this shifting of the meaning of cohesion to "reason to change" was a HUGE mistake which caused, and is still causing, enormous amounts of confusion. In a later article, Test Induced Design Damage? he tried to clear up this confusion by using the following words:

How do you separate concerns? You separate behaviors that change at different times for different reasons. Things that change together you keep together. Things that change apart you keep apart.

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.

A few days later he followed this up with The Single Responsibility Principle which stated the following:

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.

When I read the statement Keeping these concerns (GUI, business rules, database) separate is good design it immediately struck me that this level of separation is an exact match to the levels defined the 3-Tier Architecture (3TA) with its Presentation layer, Business layer and Data Access layer. As my entire framework is based on 3TA, and 3TA is the same as SRP, then I have automatically followed the principle of SRP. Case closed.

The two articles Test Induced Design Damage? and The Single Responsibility Principle were published in 2014, but in an earlier 2009 article called One Thing: Extract till you Drop he talks about splitting the code in a large function until you end up with a collection of smaller sub-functions which are so small that it is impossible to split them any further. While in this article he is talking about splitting a method into a series of smaller sub-methods within the same class some clueless newbies seem to think that this means putting each of those sub-methods into a separate class. which means that they end up with a large number of classes each of which contains a single method with just a few lines of code. Further information can be found at Too much separation. A wise programmer should immediately see the error in this thinking - if you have a class which contains only a single method then you are abusing the idea of encapsulation and should leave that method as a procedural function.

I personally do not follow this idea as trying to follow a path through code which constantly jumps from one place to another makes it far too easy to lose track of where you came from, where you are going, and what you are trying to achieve. I prefer not to extract code in a function into a sub-function unless the code in that sub-function needs to be called from multiple places, or if steps performed in a function require such large amounts of code that it makes it more readable to put each of those steps into a sub-function. If all these functions are in fact class methods I *NEVER* put these sub-functions into their own classes as this would violate the principles of both encapsulation and cohesion. For example, in my framework I have a single View object which which is responsible for creating all HTML output for any web page. This involves several distinct steps each of which is performed by its own method, but all these methods are in the same class. The principle of cohesion states that as these functions are closely related (i.e. they are all concerned with some part of the HTML output) then they should all be kept together in the same class as Any attempt to divide them would only result in increased coupling and decreased readability.

SRP is based on cohesion, not the ability to count

Robert C. Martin's original article on this subject clearly states that SRP is based on the principle of cohesion, yet there are some numpties out there who clearly do not understand what this means. They do not have the mental capacity to tell if a module/class demonstrates either high cohesion or low cohesion, so they resort to a simpler technique - the ability to count. They say that a class should not contain more than n methods, and a method should not contain more than n lines of code. Different people have a different view on what the number n actually is. Even then they demonstrate that they cannot count any higher than 10 without taking off their shoes and socks.

In March 2017 a numpty called Hall_of_Famer created a post on Reddit titled How would you go about maintaining a class with 9000 lines of code like this one? It quickly degenerated into a personal attack on many fronts, so rather than replying in situ I created Response to personal attack on reddit.com

The premise of that Reddit post goes along the lines of "it is so large that it surely must be breaking SRP". Nowhere in Robert C. Martin's definition of SRP, or his subsequent follow-up articles, does it say that the splitting up of a large module with multiple responsibilities should be based on the ability to count, only the ability to think. Each "responsibility" can be summed up as "in which of the three layers - Presentation (GUI), Business or Data Access - does this code belong?" I have followed this interpretation of SRP by dividing my code into separate modules where each module sits in just one of those three layers. Note that I have also split my Presentation layer into separate Controller and View modules.

Before jumping in so quickly to criticise my code not one of these newbies took the time to see how it fits into my framework, otherwise they would have spotted the following:

  1. That class is never instantiated into an object as it is an abstract class which is inherited by every concrete table class. This approach is described in Object Composition vs. Inheritance as follows:
    Most designers overuse inheritance, resulting in large inheritance hierarchies that can become hard to deal with. Object composition is a different method of reusing functionality. Objects are composed to achieve more complex functionality. The disadvantage of object composition is that the behavior of the system may be harder to understand just by looking at the source code. A system using object composition may be very dynamic in nature so it may require running the system to get a deeper understanding of how the different objects cooperate.
    [....]
    However, inheritance is still necessary. You cannot always get all the necessary functionality by assembling existing components.
    [....]
    The disadvantage of class inheritance is that the subclass becomes dependent on the parent class implementation. This makes it harder to reuse the subclass, especially if part of the inherited implementation is no longer desirable. ... One way around this problem is to only inherit from abstract classes.
  2. Every one of the methods it contains is an implementation of the Template Method Pattern, being either an invariant method containing common code or an empty "hook" method which can be added to each subclass to contain custom code. This pattern is described in the Gang of Four book as follows:
    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.

    Template methods lead to an inverted control structure that's sometimes referred to as "The Hollywood Principle" 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.
    If you look at Sequence of events the column labelled Entry Point identifies the public methods while the column labelled Sequence shows which internal methods are called. The customisable methods have a "_cm_" prefix.
  3. Every one of my 45 reusable Page Controllers, one for each of my Transaction Patterns, communicates with its Model class(es) using different combinations of these Template Methods. These Controllers are reusable by virtue of the fact that none of them contains any hard-coded class names as they are injected (passed down) from a separate component script. Thus any one of these Controllers can be used with any one of my 400+ Model classes.
  4. This means that at any time I can create a new user transaction for a database table using any one of my Transaction Patterns without having to write any code to include the invariant methods required by that Pattern as all these methods are automatically inherited from the abstract class. The only code which is necessary is custom code which can be inserted into the relevant "hook" methods which can be added to the concrete subclasses.

My abstract table class is so large because it contains *ALL* the Template Methods which may be needed by *ANY* of my Transaction Patterns. This means that I can create a new task using a new Transaction pattern at any time, and I do *NOT* have to make any adjustments to any concrete class (except to modify any "hook" methods where necessary). I have been told that this is wrong as each concrete subclass should only inherit those methods that it actually needs, so I should split the single abstract class into smaller classes. This idea is crap for the following reasons:

My current solution gives me the maximum amount of benefits from the minimum amount of code which, in my book, makes it highly efficient. Being a pragmatic rather than a dogmatic programmer I favour code which demonstrates efficiency over paradigm purity any day of the week.

Confusion about the meaning of "God Object"

It has been said that my abstract class is so big that it must be a God Object, but I have debunked this theory in several other articles:

It has also been said that any class which inherits from that abstract class results in an anemic domain model. Those descriptions are mutually exclusive, so how is that criticism possible?


Confusion about Separation of Concerns (SoC)

When I was first told "Your code breaks SoC" my first thought was "What the heck is SoC?" After a quick search on the internet I found this wikipedia article which stated:

In computer science, separation of concerns (SoC) is a design principle for separating a computer program into distinct sections. Each section addresses a separate concern, a set of information that affects the code of a computer program. A concern can be as general as "the details of the hardware for an application", or as specific as "the name of which class to instantiate". A program that embodies SoC well is called a modular program. Modularity, and hence separation of concerns, is achieved by encapsulating information inside a section of code that has a well-defined interface.

Notice that it does not say anything about cohesion and coupling.

A few sentences later it says the following:

Layered designs in information systems are another embodiment of separation of concerns (e.g., presentation layer, business logic layer, data access layer, persistence layer).

This arrangement of layers - presentation layer, business layer, data access layer (to me the data access layer and persistence layer are the same thing) - is an exact match to the description of the 3-Tier Architecture (3TA) upon which my entire framework was based from the outset, so it should be perfectly reasonable to conclude that any design which is based on the 3-Tier Architecture automatically satisfies the "layered design" description quoted in the above definition.

You should also note that the description of the Single Responsibility Principle also mentions exactly the same layers, so it should be perfectly reasonable to conclude that as SRP = 3TA and SoC = 3TA then SRP = SoC.

This is not just my opinion. Robert C. Martin himself, in his article The Single Responsibility Principle, actually uses the following words:

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.

If the man who first defined "single responsibility" says that it is the same as the "separation of concerns" then who are you to argue?


Confusion about Dependency Inversion and Dependency Injection

When I was first told "You're not following the Dependency Inversion Principle (DIP)" my first thought was "What the heck is DIP?" After a quick search on the internet I found this wikipedia article which stated:

In object-oriented design, the dependency inversion principle is a specific methodology for loosely coupling software modules. When following this principle, the conventional dependency relationships established from high-level, policy-setting modules to low-level, dependency modules are reversed, thus rendering high-level modules independent of the low-level module implementation details. The principle states:
  1. High-level modules should not import anything from low-level modules. Both should depend on abstractions (e.g., interfaces).
  2. Abstractions should not depend on details. Details (concrete implementations) should depend on abstractions.

I did not understand this gobbledygook (I still don't!), so I looked for a more detailed description. The article tried to explain how to use this pattern using a diagram which showed a Policy Layer, a Mechanism Layer and a Utility Layer, but no such layers exist in my architecture. The only layers I have are the Presentation layer, the Business layer and the Data Access layer, so I found the article to be totally useless and so ignored it.

I later discovered that this was also related to the Dependency Injection Principle which again lacked a sensible description, so I ignored that as well. It was not until I read Robert C. Martin's article The Dependency Inversion Principle that the light began to dawn, that the penny began to drop. My reading of the example "Copy" program highlighted the following points:

After reading How to write testable code the following additional points became obvious:

It also breaks down classes into two broad categories:

It then states the following:

The last point tells me that it is permissible to inject entities/newables into services/injectables but not the other way around. This follows the example shown in Robert C. Martin's The Dependency Inversion Principle where the two device objects, which are entities, are injected into the copy program, which is a service. The process would not work if you tried to inject the copy service into a device entity. This is logical to me for the simple reason that the operation performed by each service is unique while the identity of the dependent objects on which that service can be performed is not - it could be any one of the possible dozens of different devices or, in my case, any one of the hundreds of tables in my database. I have implemented this approach in the following ways:

It should also be noted that as each service object, which should be the only one able to provide that service, communicates with its dependent object(s) which could come from any number of numerous entities, with a common API. This means that this common API must be available in all those dependent objects. Thus you cannot have Dependency Injection without sharing a set of common APIs, and this fits the description of polymorphism. In my framework all the Model objects share exactly the same APIs as they are all inherited from the same abstract table class.

This topic is also discussed in the following articles:


Confusion about Inversion of Control (IoC)

I have read in quite a few places that Inversion of Control, Dependency Injection and the Dependency Inversion Principle mean roughly the same thing and are almost interchangeable. But is this true? The wikipedia article at Inversion of Control states the following:

In software engineering, inversion of control (IoC) is a programming principle. IoC inverts the flow of control as compared to traditional control flow. In IoC, custom-written portions of a computer program receive the flow of control from a generic framework. A software architecture with this design inverts control as compared to traditional procedural programming: in traditional programming, the custom code that expresses the purpose of the program calls into reusable libraries to take care of generic tasks, but with inversion of control, it is the framework that calls into the custom, or task-specific, code.

In the next paragraph it also says:

The term is related to, but different from, the dependency inversion principle, which concerns itself with decoupling dependencies between high-level and low-level layers through shared abstractions.

Please note the phrase related to, but different from. This means that the two principles are different, not identical.

In a later paragraph it also says:

Inversion of control is sometimes facetiously referred to as the "Hollywood Principle: Don't call us, we'll call you".

The term "inversion of control" was first used by Ralph Johnson and Brian Foote in 1988 in a paper called Designing Reusable Classes which stated the following:

White-box vs. Black-box Frameworks

One important characteristic of a framework is that the methods defined by the user to tailor the framework will often be called from within the framework itself, rather than from the user's application code. The framework often plays the role of the main program in coordinating and sequencing application activity. This inversion of control gives frameworks the power to serve as extensible skeletons. The methods supplied by the user tailor the generic algorithms defined in the framework for a particular application.

A framework's application specific behavior is usually defined by adding methods to subclasses of one or more of its classes. Each method added to a subclass must abide by the internal conventions of its superclasses. We call these white-box frameworks because their implementation must be understood to use them.
Inheritance

Most object-oriented programming languages have another feature that differentiates them from other data abstraction languages; class inheritance. Each class has a superclass from which it inherits operations and internal structure. A class can add to the operations it inherits or can redefine inherited operations. However, classes cannot delete inherited operations.

Class inheritance has a number of advantages. One is that it promotes code reuse, since code shared by several classes can be placed in their common superclass, and new classes can start off having code available by being given a superclass with that code. Class inheritance supports a style of programming called programming-by-difference, where the programmer defines a new class by picking a closely related class as its superclass and describing the differences between the old and new classes. Class inheritance also provides a way to organize and classify classes, since classes with the same superclass are usually closely related.

One of the important benefits of class inheritance is that it encourages the development of the standard protocols that were earlier described as making polymorphism so useful. All the subclasses of a particular class inherit its operations, so they all share its protocol. Thus, when a programmer uses programming-by-difference to rapidly build classes, a family of classes with a standard protocol results automatically. Thus, class inheritance not only supports software reuse by programming-by-difference, it also helps develop standard protocols.

Notice here that it specifies the use of superclasses to provide standard behaviour and subclasses which share this behaviour while allowing a technique called programming-by-difference.

The term "inversion of control" was later used by by Michael Mattsson in his 1996 paper titled Object-Oriented Frameworks - A survey of methodological issues in which he states the following:

The problems with reusing class libraries are that they do not deliver enough software reuse. Software developers still have to develop a lot of application code themselves. Limitations in reusing classes and objects from class libraries comprise [Cot95]:

In the section labelled Object-Oriented Design Patterns he states the following:

When discussing metapatterns, the following classification of methods [Joh91] is used:

In the section labelled Conclusion he states the following:

The major difference between an object-oriented framework and a class library is that the framework calls the application code. Normally the application code calls the class library. This inversion of control is sometimes named the Hollywood principle, "Do not call us, we call You".

Notice that he uses the words template methods, hook methods and the Hollywood principle. These are described in the 1995 Gang of Four book Design Patterns: Elements of Reusable Object-Oriented Software under the title TEMPLATE METHOD as follows:

Intent
Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm's structure.

Applicability

The Template Method pattern should be used
Consequences
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 in library classes.

Template methods lead to an inverted control structure that's sometimes referred to as "the Hollywood Principle", 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.

The Template Methods call the following kinds of operations:

This link between the terms "inversion of control" and the "Hollywood principle" is also echoed in Martin Fowler's article InversionOfControl.

Note that all the above articles describe "inversion of control" as being linked to the "Hollywood principle", "template methods", and the difference between a library and a framework. I therefore regard any attempt to link IoC with anything else to be a misrepresentation, a serious mistake which shows the confused mind of the author.

The wikipedia article called Dependency Injection contains the following statement:

Dependency injection is one form of the broader technique of inversion of control. A client who wants to call some services should not have to know how to construct those services. Instead, the client delegates to external code (the injector). The client is not aware of the injector. The injector passes the services, which might exist or be constructed by the injector itself, to the client. The client then uses the services.

The wikipedia article called Dependency Inversion Principle states its objective as being to separate the place where an object is instantiated from the place where its services are consumed.

How and when services are constructed has absolutely nothing to do with the Hollywood principle, template methods nor frameworks, so how anyone can link these principles with inversion of control is beyond me.


Confusion about Object-Relation Mappers (ORM)

There are some OO programmers out there who seem to think that it is forbidden to have your software components being aware of your database structure. Take the following as examples:

By following the "rules" of Object Oriented Design (OOD) they therefore produce an object structure which is totally out of sync with their database structure. Being "out of sync" produces a condition known as Object-relational impedance mismatch. One proposed solution for this problem was the invention of an Object-Oriented Database (OODBMS), but their adoption and market share is minimal when compared with Relational Databases which have grown in sufficient power to lessen the need for a radically different approach. As a substitute the OO world has chosen to add in is an extra piece of software known as an Object-Relational Mapper (ORM).

In my humble opinion this is a train wreck of a solution, or as someone else put it The Vietnam of Computer Science. Instead of writing code to deal with the after effects of this train wreck my approach is to adopt a design methodology which prevents the train from being wrecked in the first place. This approach is known as prevention is better than cure. Instead of wasting my time using one methodology to design my database and a different methodology to design my software I have completely ditched the need for OOD and instead create class structures which is a mirror image of my database structure. This means that there is no mis-match, therefore no need to include code which deals with that mis-match.

I do this by first designing and building my database, then creating a separate concrete class for each database table. Some people say that this would produce huge amounts of duplicated code, but they obviously have not understood the concept of sharing code through inheritance. My method of only inheriting from an abstract class also means that I can make extensive use of the Template Method Pattern which is yet another mechanism of reusing code. The full list of savings which I am able to achieve is discussed further in Having a separate class for each database table *IS* good OO.

Further criticisms of ORMs can be found at Object Relational Mappers are EVIL.


Using OOP has no benefits until the first rewrite.

In a previous blog post entitled In the world of OOP am I Hero or Heretic? there is a section labelled What are the benefits of OO Programming? which contains the following statement from a person who goes by the moniker lastcraft:

I find that OO is best as a long term investment. This falls into my manager's bad news (which I have shamelessly stolen from others at various times) when changing to OO...
1) Will OO make writing my program easier? No.
2) Will OO make my program run faster? No.
3) Will OO make my program shorter? No.
4) Will OO make my program cheaper? No.
The good news is that the answers are yes when you come to rewrite it!

If he really thinks that the benefits of OOP do not appear when first creating an application but only after you rewrite it then as far as I am concerned his approach to OOP is totally wrong. My own implementation has produced superior results with my very first attempt and not with any subsequent rewrite. Note that I have NEVER had to redesign and rewrite my code, all I have done is start from a solid foundation then enhance and expand it.


Conclusion

In Programming is an art, not a science I state that unless a person has the basic talent to begin with it will be very difficult to turn that person into a skilled programmer. Instead you will end up with a bunch of Cargo Cult programmers or Copycats. Being an art computer programming relies on a person's creativity and not the blind following of sets of pre-conceived rules. I managed to make the switch to OO programming by making myself familiar with the basic concepts - that of encapsulation, inheritance and polymorphism - then by reading the PHP manual (which at the time was for version 4) to work how to take advantage of them in my code. I was totally unaware of all the things called "best practices", "principles" and "rules" which is probably why I managed to create a very successful implementation.

This is not the first time that I have ignored other people's so-called "best practices" and achieved a superior result, which begs the question are these best practices really the best? In my humble opinion the answer is an emphatic NO! If you read my definitions of Excellent and Excrement you should be able to see and perhaps understand the points I have made in Ideas which score highly on the Faecal Scale. When I was made aware of all the different OO principles which materialised over the years I had great difficulty in understanding what they meant in practical terms. All I could see was a large number of words with very little substance. Descriptions such as "reason for change", "program to the interface, not the implementation" and "Depend on abstractions, not on concretions" were as clear as mud to me, and the lack of examples which proved they had any benefits could not convince me that they had any benefits at all. I spent most of my software career designing and building bespoke systems for software houses where, in order to win contracts, we had to prove that your solution was the most cost-effective. The quality of our software was judged on the results which it achieved, not on the way in which it was built. What I have attempted to expose in this article is that, in my humble opinion, far too much of what is being taught to today's young programmers is not the best at all, it is much closer to being absolute rubbish. All the while newbie programmers are taught this rubbish they will never be better than rubbish programmers themselves.

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


References

The following articles express my heretical views on the topic of OOP:

The following articles describe aspects of my framework:


Amendment History

16 Apr 2022 Added Confusion about the words "use", "overuse", "misuse" and "abuse"
Added Confusion about the words "format", "transform" and "convert"
Added Confusion about the words "can" and "should"
Added Confusion about the words "responsibility" and "concern"

Comments

counter