The Lean Thinking Movement
The primary goal in Lean software development is to eliminate waste and optimize flow. This is accomplished by applying the theory of constraints and reducing the time it takes to produce artifacts in areas of a process that take the most time.
Lean ideology is critical for private organizations who cannot survive unless they optimize their business. Customers who give an organization money choose to do so solely because the organization provides the best product or service for a fair price.
As soon as another organization can produce something better, or cheaper, or a combination of the two, customers’ loyalty will promptly shift to the better organization. Capitalism thrives off of this concept: better products and services are created and refined due to competition.
Capitalism can be a beautiful thing, allowing free-enterprise to provide us with a high-tech culture, provides phenomenal products and services, creates jobs, and allows our economy to thrive. However, some organizations do not thrive off of competition.
Thriving off of Waste
Some organizations actually thrive off of being wasteful. Margins are improved by overproducing or extending the amount of time it takes to provide value.
For example, in his talk on Scrumban at the 2009 Austin Code Camp, Joe Ocampo described an insurance company who took longer to process claims because they made more money by doing so.
I am not exactly sure how they profit from this condition; perhaps it reduces their risk, or allows their investments to squeeze out more interest before they pay for a claim.
Milk The Government
The federal government has been doing business like this for years. The government encourages wasteful contractors. It is no secret that major contractors underbid government projects on purpose in order to get the contract. Once out of money, the contractor simply asks for more.
Since everybody in the sector knows that the government operates like this, they are free to underbid by great margins, fully understanding they will not be able to complete the project with the original bid.
Contractors will extend time lines, get paid to create features that add no value, and perform a number of other tricks to squeeze as much milk from the government utter as possible. How is this possible? The answer is the opposite of way capitalism thrives: lack of competition.
Since contractors only have one customer to satisfy, and they all know how that customer operates, they work together to pry as much cash out of government hands as possible. One major contractor does the majority of the underbidding, while subcontractors negotiate for their slice of the pie.
Under these circumstances, efficiency, optimization, adding value, eliminating waste, and all of the other tenants of Lean thinking do not make any sense. If a contractor changes to embrace Lean thinking, they provide a more valuable product but are not rewarded for it.
A Lean contractor would get paid less because the competition would underbid them. The competition receives more money to create more waste and less value. This type of business model has to stop!
“Change We Can Believe In” - President Obama’s Campaign Slogan?
Companies who thrive off of waste destroy what is best about a capitalistic society. The bigger a wasteful industry is, the more it hampers the economy, and sets back the great achievements of a culture. Does anyone know how to change these industries? Has anyone had success?
The biggest problem I am aware of is the Federal Government. We have got to get them to change their ways. President Obama has stated that he wants to improve the government’s way of doing business.
How do we start?
Posted by Michael Brennan on Saturday, May 30, 2009
I started off watching Jimmy Bogart introduce C# 4.0. I had watched a video last year where Anders Hejlsberg introduced C# 4.0 more in depth. Jimmy’s presentation was quite good, but seeing an introduction to C# 4.0 prior to the code camp, I wish I would have gone to Joe Ocampo’s “Git For People.”
The talk on S.O.L.I.D. principles by Derick Bailey was great. However, I only attended half the talk, and left after the explanation of the open-closed principle. I have done a lot of reading on S.O.L.I.D. principles, and this was more of a recap for me.
I went to Scott Bellware’s “A Handful of Things You Can Do in Ruby That Scares the Pants Off of C# Developers.” This was one of the most entertaining talks of the day.
Ruby was fighting to be my favorite language in the past couple of months; after today it definitely is now my favorite. Scott showed some meta-programming that had a few C# developers’ jaws dropping.
I think the best talk of the day was Joe Ocampo’s discussion on Scrumban. I had yet to see how to implement Lean principles into an actual process. Joe showed his process and went into great detail. Not only was the presentation informative, but Joe, as a speaker, is very entertaining!
Finally, Chad Myers gave a very detailed presentation on how to use FubuMVC. Chad delivered exactly what I’d been hoping for: how exactly to get started with it. Prior to today, I had a hard time getting started with FubuMVC. Chad presented great documentation on how to do just that.
The schedule for the 2009 Austin Code Camp has been posted, and I have picked which sessions I will be attending. The Code Camp is this Saturday, May 30th.
It was very tough to pick which classes I wanted to attend due to the great content. Here is what I picked, with the class I would have attended had the main pick not been available:
09:00am - 10:00am
Room 103, Sneak Peek at C# 4.0 by Jimmy Bogard
Runner up: Git for People by Joe Ocampo
10:00am - 12:00pm
Room 103, S.O.L.I.D. Software Development: Achieving Object Oriented Principles, One Step At A Time by Derick Bailey
Runner up: Introduction to Web testing with Watir and Ruby by Jim Mathews
12:45pm - 02:45pm
Room 103, Enterprise Architecture Patterns: Presentation, Business Logic, and Persistence by Chad Myers & John Teague
Runner up: Intro to Scrumban by Joe Ocampo
02:45pm - 04:45pm
Room 207, Introduction to FubuMVC by Chad Myers
Runner up: Practical Inversion of Control by Matt Hinze
I hope to see you or meet you there!
For those familiar with Domain Driven Design (DDD), this may seem like common sense. However, as more people adopt DDD concepts, this subtlety is definitely something to pay attention to.
Quick Overview of Entities
In DDD, an entity is a design pattern used to describe an object in the domain model that is truly unique; it has its own identity and distinctive behavior. An easy way to identify entities is to ask yourself, “If I duplicate an instance of this object, will it cause data integrity issues or other problems within my domain?”
For example, an address might be a value object or an entity, depending upon how it is used in your domain. If an address can be duplicated and substituted in places where an address is needed without a problem, then it is a value object.
However, if an address is truly unique, as it might be in a post office application, a duplicate address would cause data integrity problems. If a package needed to be dispatched to a specific address, and two of those addresses existed with the same identity, this condition would cause problems; a package can only be delivered to one address.
An Example of Incorrectly Implementing Entities
Entities should be expressed with as much simplicity as possible. An entity should only contain business logic specific to itself. This concept is defined as plain-old CLR objects in C#/VB.NET, etc. (POCO), POJO in Java, PORO in Ruby, etc.
If you find your entities are dependent on other objects, this is usually a design smell calling for the use of the service DDD pattern. Let’s use the canonical customer/order example:
Look at the following sample dialog with a domain expert. This person is an expert in some sort of online retailing business you might be contracted to write software for:
You: So tell me a little bit more about your business, who are your customers?
Expert: We sell groceries online to people living in the New York City area. We are fairly new in the market and are are looking to automate our business a little more, that’s why we’re hiring you!
You: Great! I’ll do my best to improve your automation. Let’s start with your customers, how do they place orders?
Expert: First, they browse around our online store, adding items to their shopping cart. Once they are ready to checkout, they hit the checkout button. We get an email from the customer containing a list of items from our inventory, and the quantity of those items that they want to purchase.
Your brain starts to flash with ideas on how to improve their current system. First, you might make a value object to encapsulate line items in an order as follows:
Next, let’s focus on the representation of the customer in the domain model. The customer is definitely an entity; it cannot be duplicated and substituted for another customer, because this would result in the order being processed for the wrong person.
A representation of a customer in a domain model needs an address, and the ability to change that address. The domain expert stated that they do not service areas outside of New York City. One way of expressing that in the entity is to throw an exception whenever the customer tries to change their address to a city other than New York City.
Recall the domain expert stated, “We get an email from the customer containing a list of items from our inventory, and the quantity of those items that they want to purchase.” This statement might lead you to think that you need to encapsulate this behavior on the Customer class itself.
What the expert was really trying to communicate was that their current system compiles the customer information along with the order information and packages it up into an email. Regardless, you go along with it, and start thinking about how to implement that behavior within the customer class.
To handle the orders, you might have an order generator that serves as a DDD factory to create an order, along with an order processor that actually places the order in the system.
Enough analysis, we now have a pretty good idea of what the first iteration of the Customer class should look like:
With this implementation, it seems very easy to place an order with code like this:
The Correct Way of Implementing Entities
The problem with the Customer implementation is that it is coupled to an order generator and an order processor. This implies that in the real domain, customers have knowledge of these two services.
The way a customer is expressed in this domain model is fundamentally flawed. Customers do not know of such things; I frequently shop on Amazon.com, and I have no knowledge of an order generator, nor a processor.
In DDD, the order generator is an example of the factory pattern. Factories are only used to support a domain model, not to define the domain model. There are exceptions where the domain actually has some concept of creating something new, such as real factories.
The order processor is an example of the DDD service pattern, encapsulating interactions between other entities and value objects. Other services or a higher layer should be consuming the order processor, not entities or value objects.
A more appropriate implementation of the Customer class can be defined by stripping dependencies on the two services from the class, distilling what is truly important to a customer in this domain model. In this example, all that would remain is the validation that occurs when setting a new address.
This greatly simplifies the Customer class, and allows the definition to be a POCO:
Notice how simpler the class is? It contains business logic only. The messiness of invoking the services has been removed. The removed behavior is an excellent candidate for another service, due to its interaction with entities and value objects. Let’s create an OrderService class:
The OrderService class adheres to the dependency inversion principle and can be configured with an IoC container to inject default implementations of the constructor dependencies. This service allows for interaction of the customer entity, line item value objects, an order generation service, and an order processing service.
It is quite common to have services be dependent upon other services. Services, factories, and repositories can have dependencies on other other pieces in the domain model or on infrastructure level objects.
We can now write a line of code to place an order similar to the previous line, without making direct calls on the Customer instance:
You should be weary of a design smell whenever your entities depend on other objects. These dependencies are typically domain model services or infrastructure pieces, such as logging or database support classes (ActiveRecord anyone?).
Keep your entities as simple and pure as possible. Leaving out threading, logging, and all of the other impurities that can muck up the class. Use services to encapsulate interaction between entities and value objects.
For further information, I recommend reading Eric Evans’ Domain Driven Design.
|Domain-Driven Design: Tackling Complexity in the Heart of Software|
Elegance is a refined quality of gracefulness and good taste. An elegant solution to a problem is defined by an ingenious simplicity and neatness. Elegance demands an unusual effectiveness, and allows for complexity to be illustrated in a beautiful and fascinating way.
We should all strive for elegance in our code. Elegance is what allows clear communication of a solution, no matter how complex the problem may be.
Utterly expressive code conveys its intent explicitly, and facilitates an ease of acceptance for new features or changes to existing behaviors. In this way, illustrative code becomes the documentation of itself, eliminating the need for other artifacts to crack the code into more readable terms.
Haphazardly writing code, without a struggle for elegance, breeds endless cycles of sloppiness, “hacks,” maintenance nightmares, and confusing pieces to an endless puzzle.
Are you familiar with the broken window effect? The idea was first published in March of 1982 inside The Atlantic Monthly entitled, “Broken Windows,” by James Q. Wilson and George L. Kelling. An excerpt reads as follows:
Consider a building with a few broken windows. If the windows are not repaired, the tendency is for vandals to break a few more windows. Eventually, they may even break into the building, and if it’s unoccupied, perhaps become squatters light fires inside. Or consider a sidewalk. Some litter accumulates. Soon, more litter accumulates. Eventually, people start leaving bags of trash from take-out restaurants there or break into cars.
The broken window effect was used to cleanup the great city of New York in the 1990’s. Code can also have “broken windows” in the form of haphazardness, sloppiness, incompleteness, and hacks.
These broken windows can be fixed in an effort to strive toward elegance. The more the struggle toward elegance is cultivated, the easier maintenance becomes and new features are accepted with simplicity.
Bad architectural design of software that cannot be changed forces those who strive for elegance to bang their head against a wall repeatedly. Architectural changes are not cheap, and often perpetuate their cost as time goes by.
A bad architecture is like having a three-legged mule. The cost of hacking a solution up in order to ride on top of the three-legged mule will eventually compound until the mule trips and everything it was carrying crashes down with it.
Exceptional architectural design should be fanatically sought after by the people able to change it. Designers ought to be the masters of elegance; without an elegant design, the code which supports it is truly doomed.
Developers often misunderstand elegance and reduce its meaning to simplicity alone. Simplicity by itself is in no way elegant. Simplicity is not bad, but complete simplicity in a complex system is not possible; the complexities simply cannot be made simple. Elegance is required in these situations.
For example, a toaster is a simple contraption. You put an item in the slot, push the button down, and in a few minutes your toasted wishes come true. Functionally, this is a simple procedure.
However, attractive looking kitchens demand attractive looking toasters. A functional, beautiful toaster requires a bit of elegance:
A functional, inelegant toaster
A functional, beautiful, simple toaster
How can we be elegant developers? Unfortunately, there is no simple answer; elegance is not a design pattern. Usage of the proper design patterns in the proper place, and at the proper time, can positively affect the elegance of code.
Conversely, overuse or misuse of design patterns can quickly destroy any existent elegance. A continuous study of architectural design, code design, and experience while keeping elegance in mind will produce a great developer.
Therefore, the greatest developers can express complex ideas in a superior and fascinating way, explicitly communicate intent, and produce code that is surprisingly easy to read and maintain.
For further study, I would recommend reading Eric Evans’ Domain Driven Design. Eric is one of the most eloquent expressive writers I have ever read, and I am sure his code reads the same way. I would also recommend Robert C. Martin's Clean Code, as he is one of the most outspoken legends on the matter.
|Domain-Driven Design||Clean Code: A Handbook of Agile Software Craftsmanship (Robert C. Martin Series)|
What happens when you change a struct to a class in .NET if you don’t recompile the type’s dependencies?
An interesting issue arose out of a recent code review I was conducting. If you change a type from a struct to a class, do you have to recompile all modules that are dependent on that type?
Let’s use a simple example. The following diagram illustrates several packages that are dependent on a “Geometry” package, with the Geometry package containing a struct called “Point”:
Point is defined as follows:
In the dependent module, I’ve defined a class called “Consumer” and created a constructor that references the Point struct:
Let’s examine this constructor in IL:
Pay attention to lines 5 through 7; the “valuetype” instruction declares an instance variable as a value type. This is important, because it means that the memory that the variable “point” occupies will be passed by value, not by reference. Also notice line 13; this call’s the Point struct’s constructor.
If the Point struct changes to a class, the IL in lines 5 through 7 will throw an exception, because classes can’t be declared as value types. If we change, the Point struct to a class and recompile the Geometry and dependent modules, the constructor’s init block looks like this:
Notice how the point variable is now being defined with the “class” instruction, telling the native-compiler to treat this variable as a reference type. Also, the call to initialize the variable has changed:
Instead of using the “initobj” instruction, the “newobj” instruction is being used.
The impact of this nuance is very small, because everybody is either using a continuous-integration server to build their solutions (I hope). However, when you’re attempting to perform local changes on your development box this problem can manifest itself.