(The talk starts at 4:45)
Alright you all hear me okay?
Way in the back up there you hear me alright? Well it's OK, good good good
Um what is an electron?
So part of atom, everybody knows that, I think
It's um.. (Screams from other room) yeah I think so, . I think that's royal ???
Electron is part of atom
It's carries a unit of electronic charge, negative charge, as oppose to a proton which carries a positive charge
It apparently has mass, though not very much, thousands of electron or something like that. Very very small amount of mass
And we think of it as a particle, although that's misleading. The electron actually behaves much more like a wave than like a particle
Why do we think of it as particle?
And the reason we do that is that when an electron interacts it interacts at a location like a particle would
But when electron is moving through the space it does not moves the way a particle would
It moves as a wave and the wave has no location
You look at an ocean wave, and ocean wave can be huge
It has no distinct location it has a well defined energy but no distinct location
This is how an electron moves
Electrons obey a principle and it's a mistruster principle
It's called the poly exclusion principle
Two electrons bound into the same system will not be in the same state
For whatever reason they cannot be in the same state
so if there are two electrons in an atom
those two electrons must be different somehow
Now they might different in the direction of their spin
An electron can spin to the left or spin to the right
Two electrons that have exactly same energy could fit together spinning one left and one right
There's no way to get a third one in there
So the next electron must have higher energy and then you can have two more
One spinning left one spinning right
But if you wanted to add another that would have to be something different about them
And you could arrange them differently in space
So you could have one group of two this way and another group of two this way and another group of two this way and one group of two in a sphere and that adds up the eight by the way.
Most of our atoms that we know of have this need to have 8 electrons in their shells
The reason for that is just this nice little geometry. the sphere and then three rows and each one of those can contain two
Have you ever thought about water?
I got some here. Fascinating substance
What's it made of?
Two hydrogen atoms one oxygen atom that's what makes a water molecule
And what's it shaped like?
Mickey mouse! yes, there is big oxygen in the middle and two little hydrogens forming the ears
The angle there is the result of (??) the shell arrangement.
What makes the hydrogen and oxygen stick together?
Think of two atoms, two atoms covered by electrons, two electrons are parallel each other
What would make two hydrogens and an oxygen stick together?
And it turns out that if you take these two hydrogens and big oxygen you lay them next to each other
And you think of the electrons as waves, not particles, then where those waves like to be?
And those waves would like to be mostly between protons. Protons in hydrogen atom and protons in oxygen atom
So they will congregate those electron waves will congregate more
Between two atoms, between three atoms actually, then everywhere else
They still go everywhere else that just that more likely to be between them
That means there's little extra negative charge between the atoms and that little extra negative charge to tracks the protons and that's covalent bonds
Now if you take this Mickey mouse atom and you divide it in half
You find there's more negative charge above the one and below the one
Cause all that negative charge likes to sit there between the two hydrogen atoms and oxygen atoms
So there's more negative charge on one side than the other which means that water molecule is a dipole
It is negative one side and positive on the other
This is why water is wet.
Water sticks to your hand because all the water molecules rotate to stick to the electrically charged surface of your skin
Even though it is not very electrically charged
This is why water makes it good solvent because the little water molecules would rotate to attract to the parts of the other molecule that they want want to stick to
This is why water makes it a good cleanser
And this is why water will do one of the most wonderful things you can do with water. Who's done this experiment?
You get a water faucet. You turn it on just so you get a really thin stream of water. Not very fast, just tiny stream of water
And then you get a balloon and you rub the balloon on your head. And then you hold the balloon close to that stream of water and watch the water bend towards the balloon
As all the water molecules turn around get it tracked the electric charge
Of course that's not what we supposed to be talking about
The name of the talk I'm about to give you is called "Architecture the lost years". It a talk I've been doing for several years.
It's about the next step after clean code after clean design.
This is about clean system structure
And it begins with that
This is a directory structure of an application I wrote close to ten years ago now
I was studying Rails. Anybody here Ruby programmer, Ruby on Rails programmer?
We got a guy over there, waving his hand around. OK.
I was learning Rails at that time. And I wrote this application
And it was I followed the book. You get the books out. You follow the book
Follow all the recommendations of the book and that's what I wound up with
And I was happy with that. I put the application away and I didn't look at it again for very long time.
Then about three years ago. My son, at my request, wrote an application.
And I looked it in and I saw that.
Same directory structure.
These are two completely different applications. It had nothing to do with each other.
But they had same directory structure. And I looked at it and I thought.
Wait why did these two applications have the same high level structure?
They are two completely different applications.
And it occured to me that they had same directory structure because they were both Rails applications.
And I asked my self, okay but why is that important?
Why is Rails or any framework so important that it would dominate the high level directory structure of an application?
And the reason I asset question of myself was because of this.
The web is a delivery mechanism. The web is an I/O channel.
The web is not architecturally significant.
We think of ourselves as writing web applications.
We are not writing web applications.
We are writing applications that happened to deliver their content over the I/O channel known as the web.
And why should that I/O channel dominate us?
Does anybody remember when the web became important? 1980? 1990?
Anybody remember what a change that was? How radically different everything was?
Except that it wasn't. Because we weren't really doing anything new?
We were just gathering input from an input source. Processing it and spitting it out to an output source.
That's all the web is.
Why would web dominate so much?
So I started to thinking about architecture. And I started to looking at blue prints.
There's blueprint. and if you didn't have the word library staring at you. it wouldn't take you long to figure out that it was a library.
Because it's obviously a library.
You got a bunch of book shelves in there. You got a bunch of reading tables.
There's little computers sitting on tables. There's an area upfront where you have the desk you can borrow or return books
It wouldn't take you long to look at that and think "Um.. that must be something like a library."
Or here's another one. That's a church. It's obviously a church.
Oh, you might mistake it for a theater. Theater and church do have certain synergy to them.
But no this is definitely a church. The puse(??), the altar, the classrooms on the outside, the greeting area around the front
This is clearly a church.
The architecture of this buildings is not telling you how they built. The architecture of this buildings is telling you what they are for.
Their intent. Architecture is about intent.
And the high level structures of those Rails apps were not communicating intent to me.
They were telling me that they were Rails apps. Something wrong with that.
And then it occurred to me.
This is known problem? It's a solved problem. It was recognized and solved by Iva Jacobson in 1992 when he wrote this book.
Who got this book? Anybody read this one? I got a guy here, anybody else?
Object-Oriented Software Engineering, if you have. Wonderful Book.
It's 1992 little bit old, but it doesn't matter. The principles inside still perfectly good.
Notice the subtitle, the subtitle says "A usecase driven approach"
Who remembers usecases? Uh.. See? It was very popular in the early 90s. big big deal.
In fact it was so popular that it was utterly destroyed by all the consultants who invaded the realm and ruined what usecases were supposed to be.
You may recall if you remember that era that one consultant after another would publish on the Internet their own particular format for usecase.
And the format became all important. We had PDFs all out there, force you to fill in the blanks of a standard usecase form.
Anyway the fill in the name of the usecase and the input to the usecase and the precondition and postconditions
and primary actor and secondary actors and the (???) actor. What the hell is the (???) actor?
You had to fill in all the stuff and the whole problem of usecases became one of form instead of one of function.
And right about the peak of the era, the agile movement began.
And we stop talking about usecases and we started talking about stories and whole usecase thing fell on the floor. Nobody talked about it again.
And so I brought it up again and I read through the manual again, the book again.
And I remembered what Jacobson wrote.
Here is a usecase. Typical of the kind of usecase that Jacobson would have written.
If you notice that it has very little form.
Oh a little bit. It's got a name up there created order. Imagine this is a usecase for order processing system.
And it's got some input data like the customer id and customer contact information and the shipment destination.
Notice that I'm not supplying any details. I'm not saying what the customer Id is.
Whether it is a number or string, I don't care.
I'm not saying what the customer contact info is, I assume it's got a name and a date and a address and few other things. But I don't care.
I'm not trying to specify the detail here.
And then you've got the primary course.
And the primary course is the set of steps that computer will undertake to satisfy the usecase. these're the processing steps. (??)
And the first one is the order clerk issues the create order command that's actually not something the computer does.
And the second step is the system validates all the data. Notice I don't say how. Just validate somehow it doesn't matter.
Third step is system creates the order and determines the order Id.
I presume that some kind of database operation but I'm not going to say that here.
And then fourth step is at the system delivers order id to the clerk. Probably a web page but I'm not going to say that.
In fact, this whole usecase says nothing about the web.
This usecase would work no matter what the input output channel was.
I can make this usecase work on a console app, a desktop app, a web app, a service oriented architecture app, I Phone app it doesn't matter.
Because the usecase is agnostic, it doesn't care about the I/O channel.
Jacobson said you can take that usecase and turn it into object.
He called the object a control object. I've changed the name to an interactor to avoid confusion with Model View Controller.
Maybe I should have change the name to usecase. But I didn't. Interactor is what I've written here.
The interactor object implements the usecase, it takes as its input, the usecase's input, it delivers as its output, the usecase's output.
And it implements at least the high level. The rules, the processing steps of the usecase
Notice there's the caption below there. It says interactors have application specific business rules
There are two kinds of business rules
There are the kinds of business rules that are global, they are true no matter what the application is. They are application independent business rules
And then there are other business rules that are tied to the application you're writing
So for example, let's say that we've got an order entry application and an order processing application. Two completely different applications
Both of them might have an order object and that order object might have common business rules
Regardless of which of the two applications you're inside, but only one of those applications would have insert order usecase
So usecases are application specific, they're bounded to the particular application they're in
Business rules that are not application specific are bound to entity objects, some people would call these business objects
I don't like the term, entity objects that's what Jacobson called them as well
You put all of the application independent business rules into your entities and the interactor will control the entities.
Then you have to figure out the way to get the input and the output out of the usecase into another usecase
We do that in this case with interfaces. I have drawn these as object-oriented interfaces
And notice that the interactor uses one of the interfaces and derives from the other.
The one it derives from is the input interface. The one it uses is the output interface
Notice that the arrows point the same direction, that's important
We'll come to why that's important in a minute
So these are the three objects the Jacobson identified as part of his architecture for applications
Now let's trace this through, let's see how it works.
There's typical application. I've got some user out there that's that little man standing there
That's actual real person and that real person is interacting with system through some delivery mechanism.
Maybe it's the web, maybe it's not, who cares.
The person, user, pushes some buttons or type on the keyboard or does something that stimulates the system to accept data.
The delivery mechanism, maybe it's the web, maybe it's something else, it doesn't matter
Translates that into the creation of something that called request model.
A Request Model is a pure data structure.
A Plain Old .Net Object(POCO) or Plain Old Java Object(POJO), a raw data structure it has no idea where data came from there's no trappings of the web
If there's the trappings of the web anywhere
It's just a plain old data structure, no methods on it. No nothing.
Bunch of public elements in a data structure, it contains all the input data
That gets passed into an interface, the input boundary interface which the interactor derives from
The interactor receives the requests model and reads it and interprets it
And turns it into set of smaller commands which it sends to the entities
All the little business objects out there, it controls the dense of all the methods calls to the entities.
And once the job is done, then it reverses the flow. And it queries those entities and says, 'OK what happened to you?'
And there's the result of that it builds up yet another data structure called Result Model.
Result model is still just a plain old data structure, nothing knew about it, just an old plain .Net or Java object bunch of public fields no methods
That result model gets passed through the output boundary to the delivery mechanism where gets displayed somehow to the user.
That's the flow of just any other application.
Could you test that interactor?
must be easy wouldn't it?
Create the input data structure, invoke the interactor look at the output data structure
Do you have to the web server running to do that?
No, because the interactor, just plain old Java object or plain old .Net object, so all the data structure
Do you have to the database running to do that? Well you might. But we'll deal with that in a minute.
I can test this without the delivery mechanism in place at all
If my delivery mechanism is the web? I don't care! I don't have to have the web server running?
I don't have to test it with the web pages.
I can test the functioning of the system without going all the way from the inputs to the outputs
What about MVC?
Isn't MVC the thing we all supposed to doing?
What is the MVC stands for? Model View Controller. Who invented it?
That guy. Now I'm going to completely mispronounce his name. You can probably say it better than I
But I'm gonna call him Trygve Reenskaug. You can probably say it better than me.
I met him once. This is the guy who invented model view controller in late 1970s.
I met him once. I met him here at this conference two years ago.
I was up in speakers lounge and I was hunting for a power outlet And this old guy walks up to me and hands me a power outlet
I looked up and... Trygve Reenskaug!
And as he handed me the power outlet our fingers touched!
I haven' washed that hand. Trygve Reenskaug.
Some people came up and took their picture with me today. I'm a fan boy too.
In the early 80s and late 70s, Trygve Reenskaug came up with this structure called model-view-controller.
He did this in the Smalltalk platform.
And the idea behind it is very simple.
You've got a model object, the model object contains the business rules.
It does not know how it's displayed. It does not know where the input comes from
It's pure business rules nothing more. There's a controller down there. The controller handles all the input.
The job of the controller is to look at whatever the input device is, keyboard doesn't matter. And translate the actions of the user into commands to the model.
Then you've got the View.
And I've drawn the view with the funny double arrow. That's an Observer relationship.
The View registers with the model. And whenever the Model is changed it calls back to the View, telling the View to re-display.
The job of the View is to display or represent or somehow convey the contents of the Model to something else.
It works nicely on a graphical user interface. It also works just as well on a console device or service oriented architecture or any other kind of application you wish.
You have something that controls the input, (Controller) something that controls the process (Model) something that controls the output (View)
This probably the very first named design pattern ever, was meant to be used in the SMALL.
You would have a model view controller for a button. You would have a model view controller for a checkbox. You would have a model view controller for a text field
We did not have model view controller for a screen
Since those early days, this has been twisted and warped and turned because like anything in the software.
If it turned out to be a good idea, everyone else would copy it. And use the same name for something completely different and call it good.
This happened with OO It happened with structure It happened with Objects It happened with Agile
This happened with anything if the name connected with something good, then someone else will connect the name with their stuff and try call it good.
And that's what happened with MVC now. Nowadays we have these MVC frameworks
They don't look anything like that. They are not model view controller in the sense of Trygve Reenskaug's model view controller
They are something very different. In fact, they're kind of look like this.
Here you've got a bunch of controllers up there. Now the controller, if we think of the web, the controller are somehow activated by the web framework in the sky
The web framework in the sky, whatever it is, who cares, Rails, Springs God know what
will somehow route the complicated and horrible URLs that come from the web to a set of functions that we call Controller.
And it will pass into those controllers the arguments and the data came from the web.
And those controllers will then reach over and start yelling at the business objects, telling business objects what to do
Then they'll gather the data from the business objects and talk to the Views. And Views will then reach back into business objects and gather a bunch of data out of them and represent them.
And what you wind up with are business objects that get polluted with Controller like functions and with View like functions.
It's hard to know where to put the different function sometime they go into the business objects when they really shouldn't.
How can we deal with the output side?
It's gathered the data from the entities the job of the usecases done. The response model has been built. We're about to pass the response model through the output boundary
Here I show you the interactor. The interactor has done its work
And what implements that output boundary? Something called Presenter.
The job of the presenter is to take that response model which, remember, is a pure data structure.
And translate it into yet another pure data structure, which we would call a View Model.
The view model is a model of the output, the representation of the output. It still a data structure.
But if there is a table on the screen, there will be a table in that data structure
If there is a text field on the screen, there'll be a text field in that data structure
If the numbers on the screen need to be trimmed to two decimal places, there will be TrimToTwoDecimalPlaces and ConvertIntToStrings in the view model.
If they have parenthesis around them if they're negative those parenthesis will have been put on them by the Presenter and put into the View Model.
If there are menu items, names of those menu items are in the View Model.
If some of those menu items need to be grayed out because they're inactive, there are booleans in the view model that tell you that they should grayed out
Anything displayable is represented in the view model data structure in a displayable but still abstract way.
And then that get feds the View.
And View is stupid. View doesn't have anything to do with, just takes all the fields from the View Model. Put somewhere they have to go. Boom Boom Boom
No processing, No if statement, it might be a while loop to load up a table. But that's about it.
The View is too dumb to worry about we don't usually even bother about testing the view. Because we gonna look at it with our eyes on it anyway.
Can you test that Presenter?
Yeah! You handed it the data structure with response model. And You look to get the View Model data structure out.
You can test that Presenter. Do you need the webserver up and running to test Presenter?
No, You can test all the stuff without webserver running.
You don't have to fire up Spring or whatever God knows all the container You've got
You don't know how to fire up all this goop.
You test all this stuff just like the little old objects
And by the way that's a goal. You wanna test as much as you can test without firing up anything.
You don't have to start the server, start that server, start this thing, start this thing which takes 30 seconds to a minute.
You don't have to any of that. You want to just be able to run your test Just like that boom boom boom boom, fast as you can.
There's the whole piece.
From the interactor out, you can see the interactor takes data in from the request model through the input boundary
delivers data through the output boundary through the response model into the Presenter
And now look at that black line. That black line is the line that divides the delivery mechanism from the application.
And notice that every arrow crosses that black line pointing towards the application.
The applications knows nothing about the controller or the presenter.
It knows nothing about the web, it knows nothing about what that I/O channel is.
The I/O channel knows about the application, the applications does not know about the I/O channel.
If you are to put them in the separate Jar files, there would be no dependence from the application jar file upon the web jar file
And that also ways to go. You'd like to be able to put them in the separate Jar files. So that you could have a Jar file for the web and a jar file for your application
And maybe another Jar file for some other I/O mechanism.
And the way that you would change I/O mechanism is simply swap out the jar files.
Think of the I/O mechanism, the web, as a plug-in. How many of you use .Net Sharp isn't it?
You guys all .Net are you? Who's .Net?
What IDE do you use? Do you have any plug-ins? So a plug-in
Which of the two authors, the author of the IDE and the author of the Plug-in. Which of the two authos knows about the other?
The plug-in authors know about the IDE authors. The IDE authors don't know anything about the plug-in authors.
Don't care.
Which of the two can harm the other? Can the plug-in author harm VisualStudio?
Who's using Resharper? Yeh. Can the Resharper guys, JetBrains guys can they harm VisualStudio?
- (Listeners) Yes, yes - (Robert Martin) Well, they can break it.
But can they harm it in the way that the authors of VisualStudio must respond to?
The software developers at Microsoft will they ever respond to JetBrains?
No, they don't care about JetBrains.
Can the developers at Microsoft force the developers at JetBrain to respond to them?
Yeh, Big time!
Now, think about that in your application's point of view.
Which parts of your application do you want to be protected from other parts?
Which parts do you want to be forced to respond the changes in the other and which ones do you not want to be forced to change in response to the other?
And the answer to the ought to be very very clear.
You would like to protect your business rules from changes to the web.
You don't wanna protect the web from changes to the business rules.
But changes on the web side should have no affect at all on the business rules side and that's what the architecture guarantees you.
All those dependencies point inward towards the application. Keep that in mind. That is the plug-in architecture.
Which leads us to the database.
What about the database?
Is that your view of the database?
Do you think of the database is the great god in the center with little minions around outside being applications?
Does anybody have a job function of DBA? Do we have DBAs in the room?
Aha I'm safe. Good.
Anybody know about the DBA? Rolled it over the applications. Panned out the schema. Make sure the database is right.
Is this how you think about the database?
Because here's my point.
The Database is a detail!
It's not architecturally significant!
The database is a bucket of bits!
It is not an architecturally significant element of you system.
It has nothing to do with business rules.
God help you if you are putting business rules in the stored procedure.
What goes in the stored procedure are enhanced queries, validations, integrity checks, but not business rules.
Why do we have databases?
Where did this whole database thing come from? Why is there Oracle?
Where did we store all that data?
We stored it on spinning disks. Is anybody written a disk driver?
Anybody written a software that controls memory in and out of spinning disk?
Nobody! Oh gosh. Oh... Yeah! disk driver!
What? Diskette? That's good enough!
So getting data in and off of a disk is hard. Why is it hard?
Because of the way the data is organized on the disk.
The way the data is organized on the disk in the circular tracks.
The circular tracks go around the surface of the platter. There can be many platters.
There are heads that move in and out to find the track, so you've got to move the head to the right track.
Then the disk spins around and you've got to read the data off the disk.
You try get to the sector you want. There might be fifty of sixty sectors around the surface of a track. Each of the sectors might have 4k bytes.
So you gotta wait for the disks spin around until your sector comes then you gotta read the sector.
And then you go into that sector and find the byte you want.
That's a pain. And it's slow.
And if you don't optimize it can take forever to get anything in and off the disk!
So we wrote the systems that optimize for that particular problem. We called them databases.
But somethings happened.
See my lap top there? My lap top has half of terabyte of Solid State Memory. Doesn't have a disk. That shouldn't be a surprise to you.
Is anybody have disk in the room?
Is there a spinning disk in this room?
Oh my god, really?
Huh, you know, nowadays we don't even think about spinning disks anymore. We think about Solid State Memory.
Oh we think back in the server room. There's probably spinning disks. But, there are going away too.
You watch over next few years. spinning disks begin to disappear. Everything gets replaced with RAM.
And I said RAM, didn't I?
RAM is directly addressable at a byte level.
What we are approaching is a virtually infinite amount of directly addressable RAM that is persistent.
That's where we are going to be storing our data.
And if that's where we are going to be storing our data, why in hell would we want to use SQL to access it?
SQL's pain. Tables are a pain.
Wouldn't you rather be following pointers around when you rather looking things up in hash tables?
Isn't that what you do anyway? You read all the tables into memory and then put the data into better organizations You can actually use it?
What if we just left it in that format that we want to use it?
If I were Oracle I would be scared to death.
Because the reason for my existence is disappearing out from underneath.
The notion of a big database system is beginning to go away.
How can I protect my application from this detail?
This detail of database tends to dominate everything and I can protect it the same way I protected my application against the web.
I draw another one of those nice big heavy black lines.
And I make sure all the dependencies cross that line going inward towards the applications.
I make the database a plug-in to the application.
So that I can swap out Oracle with MySQL
or I can yank out MySQL and put in CouchDB
or I can take out CouchDB and put in Datomic or whatever I wish.
I can plug in the database.
You may never change the database but it's nice to be able to. Even if you don't have to.
How do we do it? Well, fairly straight forward, there's another interface up there.
I called it here the Entity Gateway.
You probably have one per entity and the methods in the gateway are all the query methods.
Anything you might query, there's function for, method for
You implement that method down in the entity gateway implementation below the line.
And that implementation uses the database whatever it is.
Notice that no part of the database manages the leak into the application.
Where the entity objects come from. Well entity objects are probably fetched out of the database although got knows what crazy way they've been spread out in the tables.
The implementation of entity gateway will gather the data together.
Create entity objects and then pass them across the line.
So once you get them above the line, they are real entity objects.
Guys using something like Hibernate? Some ORM tool?
Who's using something like that?
Where would that be in this diagram?
In the implementation! Below the line!
No part of that ORM tool would be known above the line.
Are You using those funny little annotations and attributes in business objects? Get them out of your business objects.
You dont' want your business objects to know that there are built by Hibernate.
Let them be built below the line by somebody who's polluted already by the database concept.
Keep your business objects pure. Why?
What's an object?
I've got time for this.
What's an object? An object is a set of public methods
And well you are not allowed to know the rest, are you?
There might be data in there. But you're not allowed to see it. It's all private, isn't it?
From you point of view, object is bunch of methods. Not a bunch of data.
And object is a bunch of methods.
An object is about behavior.
An object is about business rules.
It is not about data.
We presume there's data in there somewhere, but we don't know where.
And we don't know what formats in it. We don't want to know.
What is a data structure?
A data structure is a grouping of well known data elements. Public. Visible to everybody.
And there's no methods in them.
Data structures don't have functions.
These two things are exact opposite of each other.
A data structure has visible data and no methods. An object has visible functions and no visible data.
Precisely the opposite.
There's no such thing as an ORM.
Object relational mapper? Can't do it.
Because what comes out of database is a data structure and you cannot map a data structure to an object.
Cause they are completely different things.
What's happening here is that the data needed by entities gets put somewhere. God knows where.
And somehow magically passed to an entity that uses it somehow. And I don't care how.
Those entities are not constructed by Hibernate.
Probably those entities use bunch of little data structures that Hibernate did construct but I don't care how.
I don't want any knowledge of Hibernate or any other framework to cross that black line.
Stuff below the line can be polluted.
Above the black line, those are my family jewels. I'm gonna keep them protected.
Those are my business rules. I'm not going to allow my business rules to be polluted with frameworks.
Frameworks. We like our frameworks. We think they're cool.
We think frameworks save us a lot of time and they do.
But the authors of frameworks entice us to bind to them.
They offer us base classes for us to inherit from.
When you inherit from a base class, you marry that class.
You bind yourself strongly to that base class. There's no relationship stronger than inheritance.
So by deriving from someone else's base class, you're making a huge commitment to them.
But they, on the other hand, are not making any kind of commitment to you.
So it's an asymmetrical relationship.
The framework author gets the benefit of your commitment. But the framework author makes no commitment to you at all.
I leave you to make that comparison to yourself.
A wise architect does not make that binding.
A wise architect looks at the framework cynically. Looks at and says that framework ought to screw me.
That framework wants me to bind to it. And I don't think I'm going to.
I think I'm gonna put boundaries between my business rules and that frameworks.
So that my business rules are not forever tied to Hibernate or Spring. God know what.
I'll use the framework. And I'll use the framework carefully.
Because the author of the framework does not have my best interest at heart.
Long ago, my son and I and several other people wrote a tool called Fitnesse.
Is anybody use Fitnesse? Oh bunch of you, good.
Fitnesse is a tool for writing customer acceptance test.
It's based on a Wiki and that's really all you need to know it's based on a Wiki.
Who invented Wiki?
Ward Cunningham. Who's Ward Cunningham?
Guy invented Wiki. Ah~ He's a lot more than that.
Ward Cunningham is one of those Gurus of Gurus. All the Gurus know who Ward Cunningham is.
All the guys who go around speaking at conferences, like me, we all know who Ward Cunningham is.
And we review him from on high.
He was the guy made phone call to Eric Gamma
Said "You know Eric, you gotta write a book called design patterns."
This is the guy mentored Ken Beck. Taught him things like Pair Programming and Test Driven Development and Agile Development.
Ward Cunningham is a one of those guys, if you know a lot about the history of software. You think "Wow he had his hands in everything!"
Fitnesse is based on two inventions of Ward, the Wiki and Fit.
I'm not going to describe Fit. I'll describe Wiki however.
My son and I and bunch of other folks decided to write this in Java about 12 years ago. 13 years ago something like that.
We knew we wanted make a Wiki.
And so we thought "Well we got a place to store the pages, let's store them in a database and what database would that be?"
Well back in those days the only opensource database was MySQL. So we decided put everything in MySQL.
And we were about to go fire up MySQL and start building a schema and somebody said.
"You know we don't really have to do that. Right yet"
"I mean we will later but not right now because we can get away right now with another problem"
And that problem was translating Wiki text to HTML. That's what Wiki does.
Takes the funny text you typed into the Wiki and turns it into HTML.
And there was a lot of that translation that we needed to do.
So about 3 month we just forgot about the database altogether.
And we translated Wiki text to HTML. We needed an object for this which we called WikiPage.
You can see it here.
We created an abstract class named WikiPage and we implemented it with something called MockWikiPage.
The methods of WikiPage had database like funtions such as Load and Save.
But they were unimplemented. The didn't do anything.
And for about three months we worked that way.
Once we had all the translation done. Then we said "Well it's time to fire up the database."
"Cause now we need to actually store these pages somewhere"
And somebody said "Well, we don't need to do that yet."
"Because what we could do instead is take this pages and store them in a hash tables in RAM."
"I mean we don't really need to store them on disk yet, do we?"
The answer to that was no. Cause all we were doing was writing unit test anyway.
So we decided to create a another version of the Wiki page called the InMemoryPage which stored all the data in hash tables.
And we continued to work for a year.
Continuing to write more and more Fitnesse keeping all the data in memory.
We actually got all of Fitnesse working.
Without ever putting it into a disk.
And it was very cool because all the test went really fast. No database.
On the other hand it was frustrating because we would created a bunch of tests and shut the computer down and then all be gone.
So it's some point we finally said "Well now it's the time for database, let's fire up MySQL."
And Michael Feathers was there at that time.
And Michael said "Well you don't really have to fire up MySQL yet."
"All you really need is persistence. And you can get that persistency really cheaply by taking the hash tables to be written into flat files."
And we thought that's kind of ugly but it'll work for the time being. And then later on we'll switch it all over MySQL. So we did that.
And for another 3 months we continued to develop more and more about Fitnesse.
And that was kind of cool. Cause we could take on the road. We could show it to people. We could save pages.
Started work like real Wiki.
About 3 months after that we said "We don't need that database"
"It's working fine! Flat files are fast enough."
"Works okay, that way."
We took that highly significant architectural decision and pushed it off to the end of planet.
We never put that database in. That's not quite true actually. Somebody else did.
A customer of ours came along little latter and said "I gotta have the data in database."
We said "But why? It's working fine in the flat file"
He said "Corporate policy, all corporate assets must be in a database."
I don't know who they'd been talking to. But these database salesman were pretty convincing.
So, we said "Well Look. If you really needed it in a database."
"Here's this structure all you have to do is create a new derivative called MySQL page. And everything ought to work fine."
And he came back a day latter and the whole thing running MySQL.
We used to ship that as a plug-in but nobody ever used it so we stopped.
Here's an architectural decision that we deferred and deferred and delayed and delayed.
We delayed right up to the end of project. Ne never did it.
Something that we thought we had to do it first, we never did it.
That leads to the final principle.
A good architecture is an architecture that allows major decisions to be delayed! Deferred!
The goal of an architect is to not make decisions.
To delay those decisions as long as possible so that you have the most information with which to make them.
You structure design and the high level structure of your code so that all these high level decisions can be pushed off.
Don't tell me that the architecture of your application is a bunch of frameworks.
"What's the architecture of your application? Yeah, we're using a SQL server and MVVM and blah.. "
You're not telling me anything.
You're telling me the tools.
That's not the architecture of your application.
The architecture of your applications are the usecases.
And you want your usecases to not know about those tools.
You wanna be able to defer the use of those tools for as long as possible.
You should be able to have the whole application running without ever firing up a database, without ever firing up the web.
Or maybe you fire up some gunky little web thing that you can toast together in a day or two.
Just so that you can see some pages without firing up some gigantic framework.
Maybe you fire up some dumb little database thing just so that you can see some persistence running.
Without ever having a license of Oracle and all the nonsense you have to go through to get that running.
Next time you have a application to write, think about what you can delay.
The application of a system should a plug-in architecture. The architecture of a system should be a plug-in architecture.
Well all of the details like the UI, the databse, the frameworks plug in to the usecases.
Which are the real core of your application.
Now of course, customers are gonna wanna see web pages.
Okay, you can stil make a plug-in architecture and show them web pages running.
You don't have to make a lot of commitments to the frameworks.
You don't have to make a lot of commitments to the web framework.
You can probably put something simple up it first.
Or if you want actually use a real framework, fine go ahead. But maintain the plug-in structure.
So that at a moment's notice you can unplug it and plug something else in.
And that probably brings to me the end of my talk.
I already talked about that earlier. (TDD)
So thank you all very much. are there any questions?
Very difficult to see, so I'm gonna come down here.
Oh that doesn't help at all.
Okay, anybody have any questions?
You gonna have to like hollow. Because I won't be able to see your hands up.
Yep.
(Someone is asking a question)
So I'm speculating the demise of Oracle and relational databases. What do I suggest to will replace them?
What an interesting question!
It could be nothing more than RAM. Why do you need anything to replace them?
If you gonna organize the data in RAM and if that RAM is persistent, what else do you need?
Oh but let's say you need something.
Okay what might it look like?
Well, who's heard of the CQRS?
Oh yeah, few of you.
CQRS, what an interesting idea?
If we have infinite amount of high speed memory. High speed RAM.
Or maybe it's even disk but who cares.
Why would we store the state of anything.
Why wouldn't we simply store the transactions?
Instead of storing a bank account, Why wouldn't we store the transactions that caused us to create the bank account.
The transactions that forced us to change the name in the bank account or the address of the bank account or the balance in the bank account.
Why wouldn't we store the transactions and reconstruct the state.
And you say to yourself "Well it will take a lot of time"
Yeah, but we've lots of processing power.
We can do that now, we have almost infinite amount of processing power and almost infinite amount RAM.
Why wouldn't we store just the events?
And I think that's an interesting idea.
If we store just events, then we would never delete anything.
We would never update anything.
You know CRUD? Create. Read. Update. Delete?
We'd loose the last 2 letters there. All our applications would be CR.
Create and Read. We would never update. We would never delete.
And when you don't update and you don't delete you don't need transactions.
There can't be any concurrent update problems if you're not updating.
That's interesting!
Are there frameworks out there that allow you to do things like that? There are.
There are number of them out there.
That are write only databases. Write once and read many times.
You can find them on the web. I'm not gonna tell you the names right now.
But you can go out there and look for them. There are out there.
You might replace them something like that.
You might replace them with Couch or Mongo. Or you might create some other thing.
It really doesn't matter. You don't have to have some massive vendor offering.
From some gigantic company in the sky.
That blesses you and says "Yes son, you may use my database system."
Maybe you can just make your own. Not that hard.
Anybody else?
Yeah, that actually helps a lot.
Okay, anybody else with questions?
(Someone is asking a question)
Differing decisions does not work very well when..
When you have a family? (People laughing)
You mean in general. There are decisions you can differ.
For example, what language we gonna write this thing in?
You gonna have to make that decision pretty early.
Right? Cause you know you gotta write some.
The fact that you're going to have a database, probably something you gonna have to make a decision on pretty early.
The fact that it's gonna be a web application, well you probably have to make that fairly early.
You have to commit to framework. No.
A family vacation that's what you were saying here.
We could plan out where we were going. Would we have to also plan out which car we would use?
If we're planning a six month in advance, we might decide buy whole new car just for the heck of it?
Maybe our car break down in the middle. Or before we go on the vacation.
The car itself is just a vehicle, it doesn't matter as long as our luggage fits in it. And our family.
We can still go on the vacation.
The database system is like the car. We don't need to make that decision as part of vacation plan.
That one can be differed to the last minute.
You could buy a new car the last minute, the day before you decide to go on vacation.
And why would you do that?
You might have gotten a race. You might have more money.
You might have a baby. Need more space.
A lot of reason you might wanna buy that car at the last minute.
Anybody else?
Yeah, way back there.
(Someone is asking question)
How do you deal with legacy architecture?
Okay, that's gonna take me more than a minute.
So I'm gonna use one word to answer that question and I'll explain that word.
Incrementalism.
Everybody faced with legacy code wants to throw it away and write it over.
Please don't do this.
They generally fails, Horribly you'll spend tremendous amount of money and waste a load of time.
Take little bits of it.
And rewrite those tiny little bits one at a time.
And get them working one little bit at a time.
That will leave you with a patch work. But the patch work will be cleaner than the original.
And then start over and start re-implementing the patch work.
Gradually cleaning it making it better and better. It'll take you long time, a lot of effort.
You wanna do that while you also adding new features.
In fact, that's just generally cleaning your code.
Please don't try the big re-design. You'll get hurt.
Thank you all for your attention. I'll see you another time.