Saturday, 7 September 2013

Simple Made Easy

Simple Made Easy


Recently I watched a great talk called Simple Made Easy by Rich Hickey. I was introduced to this video by a great developer. This talk covered some very interesting points. If you would like the slides they are here.

Simple


The definition of simple means one fold or braid. If you look it up on google I found composed of a single element; not compound. As he discusses one role, task, concept. I can see how we can relate this to SRP.

Easy


He describes easy as being near at hand or we can look at a different way not difficult to obtain. Another way he describes it is near our understanding / skill set / capabilities. This means that easy is relative.

What does this all mean. To me it clearly outlines that simple does not mean easy. Something that I think we get wrong from time to time, I know I do.

Change


Here is an interesting topic that he brings up. In order for us to make a change we need to be able to reason about our code. Often I had thought that because I had tests that I am free to change, I think there is some truth to it. However he made me think about the fact that we need to think about the change. He compares TDD to guard rail programming, meaning that tests will not always drive the right design. 

I was often told that you don't need to debug that the tests should be the only way to see what is wrong with your code. I really believe that is not possible all the time as there will be times where you just have no f**king idea of what is going on. This is because it is hard to reason about.

Anyway the point here is that nothing can replace the thought process.

Benefits of Simplicity


We have an ease of understanding, ease of change and debugging. If we are looking at a single thing it makes it simple as you don't have to think about other dependencies. Makes sense though I don't know how easy this is to achieve, no pun intended.

Conclusion


This is a very interesting presentation that I urge you watch and have a conversation with other people. Making things simple is extremely hard in my view and requires some upfront thinking

Tuesday, 3 September 2013

Law Of Demeter

Law of Demeter


When reading Practical Object-Oriented Design In Ruby, I got reminded of the Law of Demeter. To be honest I never knew it by that name. I always knew it by the name of Train Wreck, this is the way that it was explained to me.

So what is The Law of Demeter?

As described in this article:

The "Law of Demeter" (or LoD) as it is commonly called, is really more precisely the "Law of Demeter for Functions/Methods" (LoD-F). It is a design-style rule for object-oriented programs. Its essence is the "principle of least knowledge" regarding the object instances used within a method. The idea is to assume as little as possible about the structure and properties of instances and their subparts. Thus, it is okay for me to request a service of an objects instance, but if I reach into that object to access another sub-object and request a service of that sub-object, I am assuming knowledge of the deeper structure of the original object that was made available to me.

This basically says don't reach into objects that are internal to the object you are interacting with. For example, these violate the law:

customer.bicycle.wheel.tire
customer.bicycle.wheel.rotate

Fluent Interfaces


As described by wikipedia:

A fluent interface is normally implemented by using method chaining to relay the instruction context of a subsequent call (but a fluent interface entails more than just method chaining). Generally, the context is:
  • defined through the return value of a called method
  • self-referential, where the new context is equivalent to the last context
  • terminated through the return of a void context.

I often confused this as being a violation of the Law of Demeter, however it is not a violation as we are acting on the same object. The only downside is that this could lead to long lines which I would still recommend putting into a method with a descriptive name.

Further Reading  


To anyone that wants to further explore these concepts, please have a read of the following:

Monday, 2 September 2013

Practical Object-Oriented Design in Ruby

Practical Object-Oriented Design in Ruby

I got recommended to this book by a group of developers that I highly admire. I think they were politely telling me that it will help my code if I read it. For a long time I have been writing OO code, however have I been writing it correctly? Turns out like many of you I believed that I was writing code in a OO way. Turns out that good OO is very rare.

This book takes a very pragmatic approach on the subject. Many of the concepts you would have heard, however the way they are described makes them seem so obvious. That is when I know it is going to be a good book.

Designing Classes with Single Responsibility


The book talks about 4 properties that will make your code easy to change:
  1. Transparent - The consequence of change should be obvious in the code that is changing and in distant code that relies upon it. 
  2. Reasonable - The cost of any change should be proportional to the benefits the change achieves.
  3. Usable - Existing code should be usable in the new and unexpected contexts.
  4. Exemplary - The code itself should encourage those who change it to perpetuate these qualities.
Creating code that is TRUE will guarantee that your class has a single responsibility. 


Why does this matter? 


A class that has more than one responsibility is harder to reuse.


How can we determine if a class has single responsibility? 


A way to find if the class should define the behaviour is to interrogate it. Ask your self "Please Mr/Mrs Class what is your behaviour?" If the question sounds odd, more than likely it is the wrong class. 

We can also try to describe what the class does. Pay attention to words like "and/or" these words are a giveaway that your class is doing too much. This applies to messages as well.


Writing Code That Embraces Change


  1. Hide instance variables in a method - Don't use instance variables throughout your class.
  2. Hide data structures - As data changes depending on data structures can become leaky. It is best to make sure that we return an object with well defined interface. In ruby we can use the Struct class.
  3. Extract Extra responsibilities from Methods - For example if you are performing something in a loop, more than likely what is in the loop could be a method (or a few). Make sure move the smallest responsibility to a method.
  4. Isolate extra responsibilities to classes - Have a look at your class and interrogate it. Chances are that some of your methods don't belong in that class.


Managing Dependencies


Well designed objects have a single responsibility, their very nature requires that they collaborate to accomplish complex tasks. To collaborate, an object must know about other objects. This knowing is what creates dependencies. Here is where we can get into trouble as some of these dependencies can strangle out application.


Understanding Dependencies


An object depends on another object if, when another object changes, the other might be forced to change in turn. 

How can we recognise dependencies:
  • A name of another class is in your class
  • Your class sends messages to other objects.
  • The arguments that a message requires and the order.
Dependencies are inevitable. However we can keep them under control.


Writing Loosely Couple Code 


Every dependency is like a little dot of glue that causes your class to stick to the things it touches. How can we write loosely couple code?

Inject Dependencies

Having a name of a class causes a dependency in your class. By including a name of a class we introduce a static type in our class. The beauty of Ruby is that we don't need to depend on a type. What we want is to depend on a message. By injecting a dependency all we care about is the message the object can respond to.

Isolate Dependencies

Think of every dependency as an alien bacterium that's trying to infect your class. Give your class a vigorous immune system; quarantine every dependency.

How do we accomplish this?

  • Isolate instance creation. Move the creation to its own method using ||= operator.
  • Isolate vulnerable external messages. It is best to encapsulate an external message in its own method. If anything changes you isolate the change. 

Remove Argument-Order Dependencies

Knowing an object or message parameters and their order causes a dependency. It is best to try to avoid this order. In Ruby this can be achieved by the following. It is important to make sure that we provide sensible defaults. This can be achieved by using the following.

If you have a class that you can't control. It is best to create a small adapter class that makes sure there is no order dependency.

Creating Flexible Interfaces

Design is concerned with the messages that pass between objects. The conversation between objects takes place using interfaces.

Starting is hard, this is why TDD is hard to get right. The important thing to remember is to not focus so much on the domain objects, however focus on the messages. This means that rather than focus on the class focus on the behaviour. These messages are guides that lead you to discover other objects, ones that are just as necessary but far lest obvious.

How can we discover discover these messages:

  • Use sequence diagrams. These diagrams provide a simple and lightweight way to experiment with different object arrangements and message passing schemes. This allows us to try a few things before committing to them.
  • Asking for "what" instead of telling the "how". There is a big distinction between a message that asks for what the sender wants and a message that tells the receiver how to behave.

This is where I have found TDD to fail me as I did not put much thought into what the interface should look like. It is important to put some upfront analysis (thought). This helps us create a message-based application, which is the essence of an OO application

Conclusion


These are the messages from the book that I have found to be the most interesting. There are more however I didn't want to spoil it all. Some of the other topics I think warrant a blog post of their own. I urge you to get a copy of this awesome book.