Showing posts with label Object Oriented. Show all posts
Showing posts with label Object Oriented. Show all posts

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.

Wednesday, 19 June 2013

Command Query Separation

Command Query Separation


In the past couple of months I have moved back to being a full time developer and as with anything that you do over the years you forget things. If you are anything like me you get excited about the concepts that you rediscover. This is how I felt with the concept of Command Query Separation.

The concept is quite simple and stated very well in wikipedia

It states that every method should either be a command that performs an action, or a query that returns data to the caller, but not both. In other words, asking a question should not change the answer. More formally, methods should return a value only if they are referentially transparent and hence possess no side effects.

Or simply in the book that coined the term:

Command-Query Separation principle - Functions should not produce abstract side effects.

Well why is it important. Well if you remember we write code for human beings.

I had a method that did the following:

def find_user
  User.find(@id).tap { |user|
     notify(user)
  }
end

Sure this code seems harmless, however this method violates a few principles:

  1. The Single Responsibility Principle
  2. It produces a Side Effect
Hopefully this serves as a good reminder to all of us OO programmers out there.

Thursday, 16 May 2013

The art of naming

There has been numerous debates about naming things. In general, I like most of you find it difficult to name things correctly. It has been said that this is the hardest thing to do in our profession.

I have never really gave it much thought until I met one of my bosses. One of his pet peeves was things that were named incorrectly. For some time I thought what is the big deal, it's just a name and his response to that was if you can't name it you probably don't understand the problem. That statement got me thinking however not enough to really care about it. I really did wish we spent more time at the code level as I knew he had a wealth of experience.

Today I had a very interesting conversation. It all started around a code review of a feature that I was working on. This feature was around a user which had a mobile phone number and we wanted to validate that number by sending a unique code to the phone. Once they received it they would just enter that code. Easy enough.

We already had a User model so I decided to introduce two modules that would be mixed in to the User  model. These two modules were CodeGenerator and MessageSender. I thought this is great and it conveys the message quite well. During this code review in a very humble way it was brought to my attention that I have obviously forgot about "Object Thinking" (I blame this on DevOps and writing all those release management scripts :))

These two great articles really drove the message:

  1. One of the Best Bits of Programming Advice I ever Got
  2. Your coding conventions are hurting you
I really urge you all to read these great posts. It basically outlines trying to avoid the following in your names:
  1. The -er suffix
  2. The -able suffix
  3. The -Object suffix
  4. The I- prefix
So know with my "Object Thinking" cap on how would I approach the problem that I stated above. So my thoughts are the we could have a class called UniqueCode which could have the methods generate, validate. For sending we could have a class called SmsOutBox with a method send. All these classes could be composed with the User class to give it life. There could be better ways.

This is really fascinating and I thought since I have come across this twice, my life was trying to tell me something. Like my dad said to me growing up you will eventually understand what I was trying to tell you and I think this is one of those moments.