Monday, March 19, 2012

The Interface Segregation Principle in Dynamically Typed Languages

When I first heard that 'duck-typing is the interface' it only meant one thing to me; it meant that I could not explicitly use an interface. The ramifications of this were not immediately apparent, but what did that matter? I had duck-typing! Later on I started to understand what it meant to have implicit interfaces. Only after did I have a few 'fix this forward facing class and watch everything break' refactorings did it start to sink in. I needed to really treat certain classes and modules differently than the rest of my code. I needed to create pieces that I could depend on. I needed pieces that were static because they encapsulated ideas that should not be changing often. I wanted to switch the implementation at will and the only way I was going to accomplish this was to really understand that duck-typing is the interface.
When I say create a class to depend on it means a couple of things. First, it means that the class is for the client and not for the implementer. This if often said of interfaces in a statically typed language so of course it holds true for an implicit interface. An example would be any gem worth using (pick your favorite). They provide a forward facing interace that is not meant to change rapidly and does not change for weak reasons. Gems are to be used by clients and are meant to be predictable with each release. Imagine if you had to rewrite your code with each gem version because the implementer had a new idea for code arrangement. You would not do it, you would stick with the version you were previously using, missing out on the new tweaks and features. For this reason the interface we provide in dynamically typed languages needs to be static and only change for a very well thought out reason. This way the client can have a high confidence in their expectations of the code. Remember that pulling a method out from under a client in a dynamically types language causes run time exceptions (although, they ought to be testing).

What if the implicit interface being provided is staring to feel bloated and too big. It started out as one coherent idea but is now many fragmented ideas? Then, it is time to break it up into smaller interfaces. We do not want to sacrifice the dependability, but we also do want to bring our classes and modules back to a coherent state. It is then time to refactor to smaller classes, however, it is important to keep the client of the interfaces in mind. It is entirely possible for classes to 'implement' two or more interfaces keeping in mind that our implicit interfaces are forward facing for the client's use. Moving forward, however, it is important to remember that we have two or more ideas being implemented in this module and that these ideas do not always need to be implemented together.

When we provide a public API to our code we allow ourselves to change the implementation at will. What if, for example, we provide a class that talks to an external service. Behind this interface we manipulate the data we receive from the service and return only what is necessary to the client. We expose this to our client through an implicit interface. Then, one day, the backend service changes completely. We can still receive and use the same data but how we retrieve this data is completely different. So, of course, the implementation changes. But, our client of our interface never has to know about the implementation changing. We can pass a completely different class around, but since it conforms to the interface the client never knows, and frankly, never needs to. The client never noticed a disruption in service because the client's expectations of the interface were always met.

Uncle Bob writes about a copy program when discussing the Dependency Inversion Principle. I think it is a great read and it really helped me understand what it meant to invert dependencies when I was still struggling with the idea. What I wanted to highlight is not really the dependency inversion, but the interface segregation that also takes place. I'll rewrite the system in ruby to show what I mean.


When we look at this it looks trivial. Why not just call gets and puts directly instead of putting them in a class? Well, let's see what this looks like when the implementations change.


We want the client to use the file read and write instead of the standard IO read and write that we were using before. Notice that the client's implementation (the copy method) did not have to change at all. This is only accomplishable because we hid both implementations behind the Reader and Writer interfaces respectively. This is the power of thinking with interfaces in a dynamically types language.

Although it is not explicitly declared, it is important to remember the Interface Segregation Principle. With ISP we can create dependable interfaces for our clients. We can also switch implementations at will without having to wait and see what breaks. These are powerful tools to use and they ought to use them in our dynamic languages. Even if interfaces are not explicit we still have access to the idea.

Wednesday, March 7, 2012

Day In Review

We started the morning off with an iteration planning meeting. I was able to demo the nearly complete workflow which was good. After the meeting I was able to pin down the workflow, with all acceptance tests, integration tests, regression tests, and unit tests for the feature around the payments. I was able to delineate between system errors (exceptions) and user input errors (sad paths that lead to error messages) which is good because it allows the user interface to provide a feedback loop for the user while blowing up loudly if the system does not work as expected.

I was also able to pair with Brian today and do some really nice refactorings. The controller action for payment went from 19 lines to 7 lines, which was great. We were also able to build a validations module for the input in order to move some of that responsibility away from the controller. I started working with the UI and plan on continuing UI work and hopefully be finished before lunch tomorrow.

Tuesday, March 6, 2012

Day In Review

Today I put a workflow in place to go end to end and back with a payment. It felt good since this story was so large and took so long to accomplish. I am not, however, finished and I still have a good amount of refactoring to complete. There are a few abstractions left to make this code feel nice and clean. Specifically, my controller actions feels very procedural and it should be delegating a lot of what it does to other modules. Once I refactor and tighten up the workflow (ie: make the UI feel less clunky) then I will be able to call this done.

I feel happy with my code so far since it put in place modules that will be able to support all kinds of future (and unknown) transactions. That means that the development time for future types of payments should be shortened. We have our IPM tomorrow morning and I plan on demoing what I have available at this time.

Monday, March 5, 2012

Day In Review

This morning was spent working with pulling a gem from a git repository and having it work within the current project. Specifically, the gem was the payment API wrapper that I had been working on recently. We need to pull this gem from a private git repository since the code is not intended to be open sourced. Once I was able to have the gem pulled, resolving its dependencies, and working in the current environment I started writing a workflow to accomodate the gem.

When a user submits their banking information it will hit a payments controller. This controller will pass off to a payments interactor that will send a call to the payment API. Once it receives a response it will create a Transaction object to encapsulate all of the important payment data. This data will then be persisted for future use and reference.

Sunday, March 4, 2012

Hot Swapping In Java

When one thinks of Java they might think of monolithic systems with components that are compiled together and linked against each other. A typical class might import some element from other packages (include packages in jars) but all of those files, packages, and jars, are known at compilation time. This is largely true, however, it is not set in stone. The Java Classloader is the magic responsible for pulling .class files into the current virtual machine's environment for use. By overriding the Classloader it is possible to change the available .class files at run time.

Overriding the Classloader is non-trivial, but fear not because there are open source libraries to accomplish this hotness for us. The one I will be using today can be found here. I'll present the code first and then we will go over a few points.


The interface Message and its two implementers are simple enough. It allows use to call a single method on each instance we load dynamically.

The main method will sit in a loop and wait for stdin input. When the main method is first invoked it takes the base path containing .java and .class files. This base path can even be dynamically changed with the library we are using, but I will avoid that for now. The main method will take input, inspect it, and call the corresponding method in Example.

Example is where we use the library to hot swap our Message Implementation. We hold one Class object named impl. Java Class objects hold information on a compiled class and allow us to make new instances of that compiled class. The Class object can hold any type of compiled Java class which is useful for the type of reflection we are going to do. The method changeImpl will look around from the basepath to try and find a match and will then change impl to hold the Class data for what it has found. The method speak uses the Class object to make a new instance and call the method Speak which the class has by implementing Message.

When we run this application we can change between HelloWorld and HelloHotswap and call speak accordingly. The code provided has no knowledge of HelloWorld and HelloHotswap, yet it can make use of it! In fact, if we wrote another Message implementation, compiled it and put it in the basepath's directory then we could load our new implementation without restarting the application. When we must have zero downtime this is a very powerful tool in the java tool belt.

Many open source libraries for dynamic loading exist and they can be useful for situations where we want to add functionality without shutting down our application. The ClassLoader and its underlying connection to the virtual machine allow these libraries to exist. By over riding the ClassLoader we can control the virtual machine's access to .class files. With this type of control we open the door to hot swapping at run time, which useful and a great dynamic-oriented addition to Java.

(Retro) Day In Review

Friday morning I continued on working ACH payments. The gem is a separate entity so at this point it's a matter of setting the up for the workflow that will lead up to the use of the gem. I plan on continuing this into next week and then adding functionality to the gem as the customer requests it.

For waza in the afternoon I worked on jukebox. I had started the like aggregation needed for the song like weighting algorithm that I hope to implement sometime in the future. Unfortunately, I stalled on jukebox work because I ran into problems with Protocols and Defreords.