Recently I was talking with a colleague who mentioned that his company was working on adding the MVC design pattern as a PHP extension.
He explained that they wrote C code for adding Controllers, Models and Views
to the language constructs to increase performance.
Now I know that MVC is an architectural design pattern that is used widely in web applications, but I still have to come across languages that have a language construct for Controllers for example.
IMHO integrating design patterns into a language can emphasize the importance of good OO design.
So, Why aren’t the most used design patterns (MVC, Factory, Strategy,…etc.) added to the language constructs?
If the question sounds too broad then you may limit the question to PHP only.
Edit:
I’m not implying that one must use a design pattern when developing a project. Actually I promote the methodology of keep it simple as long as it works.
15
Design Patterns are added to language constructs all the time. Ever heard of the Subroutine Call Design Pattern? No? Me neither. That’s because Subroutine Calls, which were a Design Pattern in the early 1950s got added to languages pretty much instantly. Nowadays, they are even present in the machine code instruction sets of CPUs.
What about the For Loop Design Pattern? The While Loop Design Pattern? The Switch Design Pattern? The Object Design Pattern? The Class Design Pattern? All of these have been added to some languages.
2
Some of them are. For example iterators are language feature in many languages and their standard libraries (hi there, foreach and yield return). Observer is also frequently present in form of events (not in PHP – you have to manage callback subscription yourself). Command is core feature in WPF.
Many of the others wouldn’t really benefit from language support (and would make the language more cumbersome) – how would you simplify Controllers if you could design language feature for them? As classes, they benefit from all the infrastructure already present to support classes – you can instantiate them, pass them around and for example unit test them as any other object.
The only component of MVC which IMO could benefit from some sort of language support is View (with some official templating engine) – and it in PHP already kind of is supported – you are able to dynamically create and load PHP scripts (which are often with some kind of preprocessing used as templates).
The same applies for factory method – how would you simplify that, if you could have any kind of language feature you wanted? One feature which some languages (such as C++) lack is ability to construct object from this type name, but most higher level languages can do this (and it is not even necessary to create useful factory methods). Other than that, all you need is to be able to create a method which instantiates and returns and object.
1
Some design patterns are indeed added as language constructs – they just don’t get identified as such because people start regarding them as “syntax” once they are built in. Exception handling in Java is a good example – many people would code something similar explicitly as a design pattern if it wasn’t part of the core syntax.
But to focus on the question – there are many reasons why you would not want to add too many design patterns to a language:
- It isn’t necessary to add them as language constructs – all design patterns can be implemented in other ways
- It would complicate the language – this is a bad idea as it makes the language harder to learn, makes compilers and tools more difficult to write
- Alternative implementation approaches exist for many design patterns. Choosing one approach and blessing it as part of the core language would probably lead people to use that approach over others (which might be much better in some circumstances)
- Over-reliance on design patterns is probably a bad idea in any case – language designers probably realise that they shouldn’t be encouraging them even further.
Also, if you use a sufficiently powerful language with metaprogramming capabilities (e.g. a Lisp), it becomes relatively straightforward to extend the language yourself to implement any design pattern. You don’t need any patterns at all in the core language if it is easy to add your own with a 5-line macro.
Why aren’t the most used design patterns (MVC, Factory, Strategy,…etc.) added to the language constructs?
Most of these patterns can implemented in most programming languages without specific linguistic support. Take for instance MVC in Java:
- You can code it directly.
- You can implement it using an application generator … and take care of a whole lot of other boilerplate at the same time.
- You can implement it using “framework” library classes.
- You can implement it using annotations and static or runtime annotation processing.
Given all of these options, there is little value in directly extending the language. And there are a number of “downsides”:
- It would tend to clutter up the language syntax, (arguably) making life harder for novice programmers.
- It would tend to make the language specification larger and more complex, making it harder for language implementors. (And, of course, the larger the spec is, the more likely that there will be errors and inconsistencies.)
- There will always be pressure to add yet another pattern … leading to issues / concerns with language stability.
- By supporting specific patterns in the language, you hard wire specific ways of supporting the patterns, which may not suit some applications.
They are.
Functions were a design pattern in assembly code before they became a language construct in C.
Virtual functions were a design pattern in C before they became a langiage construct in C++.
However, there’s a trade off. If the pattern involves production of boilerplate code (even a couple of keywords), that’s an indication it would be a useful language feature. But if the pattern is simple and clear, eg. C’s “for (int i=0;i<10;i++)”, it’s still useful for everyone to write it the same way, but it’s not significantly longer than “for i = 0 to 10” and has the significant advantage that it’s obvious how to alter it to make a slightly different loop.
Read the ‘gang of four’ book and it’ll become clear that:
- Design patterns in the book are actually well known smalltalk conventions encoded in other OO languages.
- As such, those patterns cannot be included to the OO language — it would be reimplementing smalltalk inside those languages — it’s better to use smalltalk directly
- Why design patterns are useful is because they de-emphasize the role of the currently used language, and focuses on other issues than syntax. Encoding those patterns inside the language would lose this feature of the design patterns.
- The real problem in the above question is that it misses the point that writing software is not only about learning the language. It’s important to take sufficient distance from what language is directly providing and focus on current requirements.
Because design patterns are implemented perfectly well with user code. His example only happened because it’s PHP- but if you actually needed performance, you’d just work in another language or get HipHop or something.
Language features are complicated, both to specify and to implement, and it’s not justifiable to create one for the sole purpose of “The current idioms are X”. You’d barely save any meaningful user code at all, and for nothing.
Eh, stale question but I disagree with a lot of the answers depending on where you set “Design Patterns” on the semantics dial including the accepted one.
In the GoF Design Patterns book sense, I would say it depends. MVC, for instance (not actually a GoF pattern but fits that mold), is totally inappropriate to express as language constructs for mass consumption (although it might make sense for a specific PHP project). As an architectural pattern there are constant variations on the theme and a wide variety of perfectly legit interpretations on it for different circumstances (although many depart so far from MVC they probably shouldn’t call it MVC anymore). For instance, on the web, the http barrier makes it a somewhat awkward fit depending on whether you’re trying to include the client-side (no doubt painfully) in the equation and what you’re considering “the view” from a more appropriately strictly server-side perspective.
Iterator on the other hand is a highly general concept that can be applied in a very wide variety of ways to a wide variety of constructs.
Where the line should be drawn on whether something belongs in a core language design, even in a server-side-web-specific-language, IMO, is the point where something crosses the line from making it easier to do an incalculable number of things more easily vs. doing an overly specific yet broadly implemented thing like an architecture pattern for you.