Wednesday, 18 March 2015

Remote Meetings - Balancing the Act

Meetings are hard when some team members are remote and are physically based in the same location.

It is easy for the remote user to feel second class in terms of the meeting. Remote workers can find it hard to add to the meeting without interrupting or getting left behind.

One practice to balance the process of remote meeting is to ensure that if one or more parties are remote, all participants remote into meeting.

Benefits

  • Levels playing field - everyone should have equal opportunity to contribute.
  • Removes lag - everyone has the same experience of time/delay.
  • Includes online benefits such as message logs, sharing of screen.
  • Comfort of own desk/environment.

This idea was taken from Stack Exchange's post detailing why they still believe in remote working.

Wednesday, 11 March 2015

Dependency Elimination Principle

This is the third, and final part of my series on abstractions.

I've wrote about what good dependencies are before, and the benefits if you can limit and remove them where possible.

You can take this idea further though, by applying concepts from functional programming such as "depend on values rather than dependencies".

A wise colleague started me down this path of passing values, rather than dependencies on collaborators after we repeatedly found ourselves depending on implementation details. This meant our high level domain logic was tightly coupled to low level implementation details.

Brian Geihsler reminded me of this concept with an excellent demonstration of this in practice and has allowed me to put a name to this practice.

Additionally J.B. Rainsberger's example is with a virtual clock, another common dependency we often need. In this case, ask for the time, not how you get the time. The example also highlights another common problem with conventions when using a framework or library.

Here we can handle commands but only those that match the signature of taking a single command, and returning no response. In order to apply the Dependency Elimination Principle (DEP) and remove the clock wrapper we can introduce an overload. Our tests will be expressed using the overload, while the production code will make use of the standard method. If the class in question has a relevant set of interfaces, the overload would be omitted from this to ensure that consumers have a clean, focused API to consume.

When the DEP is applied to other dependencies such as configuration details, flexibility is achieved by the ability to provide these values from any source. As a side effect, coupling has been reduced, while also removing an unnecessary abstraction from the codebase.

Try to apply the DEP where possible. Remove as many dependencies as possible for flexible, maintainable code. Not all dependencies can be eliminated, but unless the dependency is a valid abstraction it may be worth considering removing or reducing use.

Tuesday, 3 March 2015

Reused Abstraction Principle

This is the second part of my series on abstractions.


The Reused Abstraction Principle is a simple in concept in practice, but oddly rarely followed in typical enterprise development. I myself have been incredibly guilty of this in the past.

Most code bases have a 1:1 mapping of interfaces to implementations. Usually this is the sign of TDD or automated testing being applied badly. The majority of these interfaces are wrong. 1:1 mappings between interfaces and implementations is a code smell.

Such situations are usually the result of extracting an interface from an implementation, rather than having the client drive behaviour.

These interfaces are also often bad abstractions, known as "leaky abstractions". As I've discussed previously, these abstractions tend to offer nothing more than simple indirection.

Example

Apply the "rule of three". If there is only ever one implementation, then you don't need the interface/base class. If you do need to introduce an interface, have the client provide it. Try to resist the urge to extract from an implementation. Any stubs or testing implementations should be treated as valid implementations, despite no use within the production code directly.

In the first example there is a 1:1 mapping. This is clutter and needless indirection. As we have nothing to replace FooService with, the interface offers no value. The second example shows multiple implementations of IFoo. Here different implementations have unique responsibilities. We could use a test stub, or use the decorator pattern whenever we use IFoo. The abstraction is valuable.

If you can introduce a composite or decorator this is probably a sign of a good abstraction at work. Likewise the ability to replace your implementation and have the code still function is a good sign. Such an example would be SqlRepository replaced with MongoRepository when IRepository is required.

Additionally just because you opt to use dependency injection, there is no rule stating said dependency must be an interface or base class.

The final point is to remember what good dependencies are, everything else can be an implementation detail leading to more flexible and resilient code.

Friday, 27 February 2015

Abstractions

This is the first part of my series on abstractions.


Coupling is one of the enemies of a healthy code base. One way to combat high coupling is to introduce abstractions.

Too few abstractions is bad. Your code can become coupled. Some of the worst code I've worked with was highly coupled to either the database, UI or both. Working with such code is difficult.

Too many abstractions is equally as bad. Abstraction behind abstraction can become so difficult to work with the benefit of abstracting in the first place is lost. Some of the worst code I've worked with was so convoluted with needless abstractions it made any development a tricky process.

Most abstractions are not really abstractions at all, but nothing more than simple indirection. Indirection is sometimes required, though it is wrong to confuse with abstraction. IFileWriter is not an abstraction. IReciept that happens to write to the file system when implemented as FileSystemReceipt is an abstraction. IFileWriter could be an abstraction if the software we were writing involved working directly with the file system, such as a text editor. In the case of printing receipts, where they are printed is simply an implementation detail.

Finding a balance between the right level of abstraction can be tricky. From my experience there a few techniques that can be used.

Techniques

Embrace Coupling

Udi Dahan makes this point in his presentations. If you have a traditional application with a UI, domain and data layer why bother adding further layers to abstract these? If we wish to retrieve a new field from the database and display the value we have three places to change, adding further models and mapping layers does nothing but increase coupling. Applying namespaces correctly can also help here, if everything that needs to change at the same time is logically grouped, such changes are easier.

Apply YAGNI

Do you truly need a database model mapped into a domain model, mapped into a view model and back? Applying YAGNI can limit many abstractions by simply not worrying about "what if" scenarios until they actually occur.

CQRS

Command Query Responsibility Separation or CQRS deserves an explanation on its own, but for now applying CQRS reduces unnecessary coupling by embracing it. For querying data and displaying it on a screen my default choice is to use CQRS to simply read from the database and populate a view model. This limits abstractions and helps keep the code focused, flexible and open to change. I will expand on CQRS in a future post.

Tuesday, 17 February 2015

Guard Clauses and Assertions

Two simple techniques to increase code quality, resilience, and ease debugging scenarios is to use guard clauses effectively and ensure that assertions are used liberally.

Guard Clauses

  • Any public method should perform guard clauses to ensure pre conditions are met.
  • Ensures the code's invariants are not broken.
  • Throw exceptions, because these are exceptional issues.
  • Developer and user assistance as it is possible for these clauses to fail at runtime.

Here we enforce that any PersonalDetails instance has a forename and surname. A forename must also be at least one character long. As long as these conditions are met, we finally assign the values internally. Guard clauses should also be used on dependencies that are services, checking that a service is not a null instance for example.

Assertions

  • Used within private methods/functions where required.
  • Should be used for situations that should never happen, e.g the presence of a bug or invalid scenario.
  • Developer only assistance, the user should never see these ideally because automated/manual testing should have detected them.
  • Usually removed for release builds, though open to debate, best to judge on context. Is it better for the program to crash and inform the user, or carry on in an invalid state?
  • Great for documenting assumptions, e.g. code a level above ensures object is in a certain state.

While this method is private, we have essentially stated that we take no responsibility for validating that a name has been provided. This is the concern of another part of the code (the constructor in this case). However this simple assert statement means that if the method is used in a different manner, it will fail spectacularly at runtime. This will point at the incorrect use of the method and allow the developer to make the required changes.

Summary

Code quality will improve because less invalid scenarios should be allowed to happen. Due to clauses and assertions always being present they go hand in hand with automated tests, often catching scenarios that automated tests may miss. Debugging is easier because the stack trace points you at the source of the problem, rather than an initial problem hidden in layers of exceptions caused by invalid state. While applying clauses and assertions increases lines of code, they are easy to implement, and the return on investment is high. There are no excuses not to use them.