Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

We all know the venerable Model-View-Controller pattern used to design interaction [mostly] with human users. It is the de-facto standard in OOP environment.

What are some other architectural patterns of interaction worth mentioning? Non-OOP (functional, logical, etc) approaches welcome, too.

share|improve this question

closed as not constructive by gnat, Yannis Rizos Jun 18 '12 at 7:38

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.If this question can be reworded to fit the rules in the help center, please edit the question.

2  
One common approach is the "default PHP mode", in which you merge the model, view and controller into one component which handles everything. –  Martin Wickman Mar 9 '11 at 15:32
    
@Martin-Wickman: this pattern is OK for single-purpose, single page scripts. It's an important but degenerate case of what I'd like to learn more about :) –  9000 Mar 9 '11 at 15:41
    
<a href="en.wikipedia.org/wiki/Model-view-presenter">Model View Presenter</a> is slightly different version of MVC. –  Zannjaminderson Mar 9 '11 at 15:51
add comment

7 Answers

Another important concept to think about when taking about Architecture is SOLID object-oriented design. If you are looking for a book on the subject Head First Design Patterns is by far my favorite. It's written in Java, but very easy to follow and the code examples are available in other languages.

Single responsibility principle - the notion that an object should have only a single responsibility.

Open/closed principle - the notion that “software entities … should be open for extension, but closed for modification”.

Liskov substitution principle - the notion that “objects in a program should be replaceable with instances of their subtypes without altering the correctness of that program”. See also design by contract.

Interface segregation principle - the notion that “many client specific interfaces are better than one general purpose interface.”

Dependency inversion principle - the notion that one should “Depend upon Abstractions. Do not depend upon concretions.” Dependency injection is one method of following this principle.

http://en.wikipedia.org/wiki/Solid_(object-oriented_design)

share|improve this answer
1  
Oh, well I guess the question changed from "Design Patterns" to "Architectural Patterns". Not sure if this applies any more. –  Evan Mar 9 '11 at 16:09
1  
A good list anyway. –  9000 Mar 9 '11 at 18:42
    
This answer does not relate the question. –  m3th0dman Jul 23 '12 at 15:29
add comment

There is the Model View ViewModel that comes from Microsoft. It was designed to be used with Windows Presentation Foundation. In this the ViewModel exposes the data objects from the Model in a way that is easier the manage/consume.

As a side note, by 'design pattern', you actually mean 'architectural pattern'.

share|improve this answer
    
Thanks for the term suggestion; I'll change the question accordingly. –  9000 Mar 9 '11 at 15:38
add comment

There's the naked objects architectural design pattern.

Your application is still made out of triads of discrete components that deal with data, presentation and behavior separately, as per MVC, but the model is more complex, able to specify it's business logic and presentation, typically implemented at the level of model attributes which are instances of complex types that can describe and customize business logic and presentation.

The idea is to have the view generated dynamically just by introspecting your models, so there's no coupling between the model and presentation, and that the controllers should manage models in a more abstract way, which in the end should allow you to define generic, reusable controllers and views, i.e. a controller and view that can handle and present a single instance of a model, a controller and view that can handle and present a collection of model instances.

share|improve this answer
add comment

I'm going to wind up farther afield than most of the other answers. But let me start with the obvious place. We all think we know the MVC pattern. But every framework uses it in different ways. And despite the fact that we all know it came from Smalltalk, very few people know that what we call MVC today looks very little like Smalltalk's version. (Old Smalltalk programmers have a common complaint that everyone thinks they have learned from Smalltalk, but everyone has missed the point.) Read http://st-www.cs.illinois.edu/users/smarch/st-docs/mvc.html for an overview of the original version. The next time that you're doing a complex AJAX application, stop and think. Perhaps a design with interacting components, each with their own model, view and controller, might make sense.


Moving to a different field, map-reduce is worth knowing about. This is a pattern that is used in distributed computing. The idea is very simple. Organize your thinking into stages that look like this:

  1. Have a mapper that takes a stream of facts, and emits a stream of key/value pairs. The emitted stream may be larger or smaller than the original facts.
  2. Magic happens. (I'll explain the magic in a second.)
  3. Have a reducer that gets a key followed by all values associated with that key, and does something. (It can, if it wishes, emit the data for use in another map-reduce.)

The trick is that all of this can be done in a completely distributed fashion. This technique was invented and popularized by Google, which uses it for such tasks as analyzing the whole web.

How does it work? Well generally you use a framework like Hadoop that takes care of the details. You write the map and the reduce, tell it how many mappers and reducers you want, and tell it where the work is to be done. It takes care of dividing up work for the mappers, uses a distributed sort in step 2 (usually this is a mergesort), then sends that data to the reducers who do what they want with it. Since all of these steps are distributed, you can scale across a large number of machines.

Everyone always uses text analysis for the example, so I won't. Instead I'll discuss generating all of the primes up to a trillion. You want to divide the work across many machines. First we generate a small amount of input to get started. One is the list of all primes under 1 million. The other is a list of pairs of ranges. The second might start with (2, 1000000), (1000001, 2000000), (2000001, 3000000), ... If a mapper gets a single number, it would emit key/value pairs with the keys being all of the multiples of that number starting at its square, and going up to 1 trillion, and the value just being the number. If the mapper gets a range it emits key/value pairs where the keys and the values are all the numbers in that range. The reducer is simpler, if it gets a key with only one value, that is a prime which is stored somewhere. (For instance you could use a distributed key/value store like Redis or Cassandra.) If finds multiple values, that's a composite number so do nothing.

This code is easy to write, and will run on anywhere from 1 to 10,000 machines, scaling pretty much linearly with the number of machines available to it. With practice the basic technique is adaptable to a surprisingly large variety of problems.


Moving on, a common design idea in functional programming is the idea of having a hash that maps keys to functions that then can do something. Many of the functions will have been generated as closures. The point of this may not be obvious to an OO programmer, because you can do this with OO as well. But the problem is that an OO approach to the same strategy gets painfully verbose, so that you can no longer make out the forest for the trees. See http://www.perlmonks.org/index.pl?node_id=34786 for an example of the technique in a situation that is realistically complicated. (The description there of what functional programming is, is somewhat wrong. But the technique demonstrated is widely used.)

Of course the fundamental problem for an OO programmer learning functional techniques is that you decompose problems in very different ways in the different styles. I like to claim that objects make good nouns, while functions make good verbs. If you have experienced both, that concisely sums up the difference. But if you've never done functional programming, it is hard to see how one would organize a program using verbs instead of nouns. Therefore I'm going to strongly recommend working your way through The Structure and Interpretation of Computer Programs, available online at http://mitpress.mit.edu/sicp/full-text/book/book.html.


And finally, there is the technique of writing complex programs by writing a DSL that simplifies writing the program you want to write. There is a lot of verbiage out there on DSLs, particularly from Ruby programmers, most of which is pretty bad. So I'm going to recommend an old Lisp book instead. On Lisp is a true classic by Paul Graham. It is available online at http://www.paulgraham.com/onlisptext.html. While on the surface it is a book about Lisp, if you scratch under that surface it is a book about how you could program if you had a set of tools that few languages have. If you scratch under that surface, it will let you dream of better approaches, and it is not that hard to build the tools that you need. There is an old joke that Any sufficiently complicated C or Fortran program contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of Common Lisp. After reading On Lisp you will understand why this is a useful thing to do, and know enough to be able to usefully do it yourself.

share|improve this answer
1  
In particular, MVC is not about supporting loose coupling, it is about supporting the Direct Manipulation Metaphor. –  Jörg W Mittag Mar 10 '11 at 0:42
add comment
  1. Layers It seems like most apis are built around a layering approach. The network stack comes to mind as an example.
  2. Events I have seen several apps built with event handling as the core architecture. Web servers come to mind here. Your web app might be MVC but all the web server does is handle request events and response events.
  3. pipes and filters You see this in functional programming the most. So much so I doubt they even have a name for it most of the time. F# even calls |> the pipe operator.
  4. Data Oriented design I have mostly seen this in reference to game development. It is a take focus off individual objects and puts it on groups approach.
share|improve this answer
add comment

You may want to take a look at Martin Fowler's book "Patterns of Enterprise Application Architecture": enter image description here

The online catalog of described patterns there can be found here: http://martinfowler.com/eaaCatalog/

The book pretty much describes all of the important patterns I've encountered so far. Beside that, IMHO in terms of architectural patterns, a programmer should know/understand about:

share|improve this answer
add comment

You see a lot of MVC/MVP examples, but they always seem to skip the part about inter-controller communication.

Event Bus is a good way of handling that:

http://stackoverflow.com/questions/6030202/how-to-use-the-gwt-eventbus

Also:

Navigation [see MS Prism Navigation]:

A view is in a region.
The user clicks a button to navigate to a new view.
The navigator asks the existing view to confirm the navigation (as it may have unsaved data)
The view confirms the navigation, is destroyed, and is replaced with the new view

Presentation [see iPhone navigation controller]:

A view is in a region.
The user clicks a button to open a new view that will return info to the prior view.
The new view is added on top of the old view with modified navigation buttons.
The user enters info on the new view and hits "done".
The new view notifies the prior view that it is done (via event or callback).
The prior view gets the new info and destroys the new view.

share|improve this answer
add comment

Not the answer you're looking for? Browse other questions tagged or ask your own question.