2016/01/26

3 obvious rules in software system design

Wait what? 

If you are working with systems that are transparent or applies failfast then dig into the following rules that will turn that system into a hard to understand/explain/extend/upgrade/debug/maintain/... thing.
With these rules you can keep working on the system for years in a less and less productive dialog with your users.

#1: Don't log/measure/debug/comment


Make the code speak for itself. Elegance is the key. The simplicity of elegant code makes it easy and fast to read and write. Just like Math. Either you get or you don't. 
Logging is a performance drain.
Measuring is not needed for optimal code.
Debugging sessions are never needed, if the code is like Math. 
Comments are noisy and redundant information. 

#2: Always catch - Never throw - 200 FTW


You are a competent programmer that can easily catch all possible exceptions from every possible path in the call hierarchy - so do it. You know what your code should do and you, if any, can turn every obstacle into a success-path in your code. 
Why should anyone that calls your code be bothered with exceptions when they can be avoided?
Why should a user ever see an error message in a properly coded system? Never!
Imagine how disruptive it would be to have a unit in a distributed system sometimes returning http response code 401? Obviously, it is much more preferable to have any unit that always just gets the job done!

#3: Customize every function/service


Avoid simple atomic parts like CRUD and functions with only 1 purpose. The key is to understand what is needed and make that 1 function/service to do just that and nothing more. It gives the optimal calling code and the best performance. CRUD-like operations causes the calling code to have branches, control code and multiple calls. Good examples are AddIfNotAlreadyAdded, DeleteIfExisting, BulkEditIfExisting.
Please note that rule#2 and rule#3 complement each other. Only with rule#2 can we make a service called LogInQueryBestAndCheapestPrinterAddToBasketAddCreditCardInfoPurchaseLogOut.

Don't believe it!


CRUD and single purpose operations do exactly 1 thing or returns an error. This implies that conditionals, retries and error handling must be established at the calling side. In an application this causes the control points to move upwards in the call hierarchy and in a distributed system this causes the control points to move closer to the client. Some people claim that such an infrastructure can be re-used for multiple applications, but that is a poor solution compared to a custom-tailored high-performance solution.
    Another silly idea is to engage the users by making the system transparent. In that school of thought a database error is displayed to the user, so that the user may issue the problem with a root cause, so it can be fixed quickly. Obviously, rule#2 - and you - will make sure that your users do not need to concern themselves with system errors. 
  

2015/05/03

Almost 2 years later: FailFast v. 1.0 released

Waz dhis 'bout?

My previous post - http://starkcoder.blogspot.dk/2013/06/how-could-failfast-library-work.html - was an idea to a simple and easy to use failfast library design. Here almost 2 years later that idea - and some more - has been turned into a JAVA library. Whether it useful is really up to you to decide. If you want to know more about the library (and I hope you do) go have a look: https://github.com/KeldOelykke/FailFast. This post, however, is about the process of making such an open source library.

A Need was building up

"Wouldn't is be cool if..." and "all we then had to do" but "sounds simple but I don't think we have the time right now". Sounds familiar?
There seldom is a paid project where you can go all in on something so basic as a failfast library. The reality is that we do some assert methods on the fly in a central or abstract class... and that is it. The next project we might make a copy ... or might just as well write a new one.
This is kind of silly, since failfast is a relative important matter. One may argue that failfast is just as important as logging. Why is it then we have multiple logging libraries but no failfast library?

The Idea

Some experience with a team resulted in what I ended up calling the spot contractor software pattern - http://yoawsconsult.blogspot.dk/2012/11/spot-contractor-software-pattern.html. It was pretty natural that this pattern would be the core of failfast library, why it was used - without any presentation - in the previous post - http://starkcoder.blogspot.dk/2013/06/how-could-failfast-library-work.html.
It is still a mystery to me why this enforced approach is not used in every logging or performance measurement framework.

The Job Change

It took almost a year for me to go from the Idea to the beginning of the library. The first commit was 5th of May 2014 - https://github.com/KeldOelykke/FailFast/commit/177d979e0ce4fee03c252b74091f0a50b695bdc5. The reason was a job change 1st of January 2014.
I did that job change with an awareness about the Idea, so I could enable it without asking anyone for permission.
If you are a developer don't ever sign a contract that gives the Employer all rights to software that you create during your employment. This is almost an industry default phrase in contracts, but you need to ask for it to be more specific (work related in some manner). Otherwise, who owns the right to your spare time software? and is it at all possible for you to make software open source?
If you are hiring a developer it may be that you would love to hire a developer that has experience from the open source community. That probably will not happen, if you won't let developer stay in open source community.
With all intellectual property obstacles away, I could start coding.

Commit yourself often

My poison is playing League of Legends - http://leagueoflegends.wikia.com/wiki/League_of_Legends. It is in so many ways right. So how does my hobby coding project compete with a game of LoL? For every X hours of LoL it is reasonable to spend Y hours on my hobby. You probably know this deal from exams or similar. X/Y is kind of a trade factor for your motivation. It doesn't really matter what X and Y are or what you poison is. What matters is that your motivation for the hobby project is acknowledged by you (and your spouse).
In practice I usually use Monday (and/or Sunday) evening on my hobby project - https://github.com/KeldOelykke/FailFast/graphs/punch-card.

Get your code into a form

Like a kid I like when things gets repeated. It gives me sense of normality. If every piece of code I open is unique in some way, my pattern recognition says no. I know when coding is getting repetitive the design is somewhat stable. The amount of the next X features is getting predictable. All is good.
For the FailFast library the form is the usual co-operation between the 3 main classes - Checker, Failer and CallContractor, it is the check-fail interface pairs that defines a feature, it is each unit test, etc. The form is so important for the next commit, because it takes much less time the better form your code has.

Define 2 major milestones

This is where you scope your 1st release. You need the 1st reason to celebrate - the 1st release. To get to that 1st release you have to push some features to a future release. That is why you need a 2nd milestone. It is a dump for your thoughts and ideas. It may be that the next major milestone has a theme that you plan for - that is a great way to group some features that you needed out of your first major milestone.

Many minor milestones - because you can

You are the Boss. Whatever you feel like cool improvements - make them. This is your work paying of for you. Your hobby project motivation is rising and your library gets worth. Embrace an idea for improvement with a minor version release.

Users where art Thou?

I wish I could tell you something clever here, but the Truth is that I need Users. I that you?
  • No? Why not? 
  • Maybe? Great let me know what you need to get started? 
  • Yes? Super. You might be the first. I would love to hear you thoughts and experience.
In any case Thank You for reading this post.

2013/06/17

How could a FailFast-library work?

What is Fail Fast? 


Why a FailFast-library?

  • It could leverage a lot of nice checks that you don't bother writing your self (think NUnit Assert-method).
  • It could throw a FailFastException that is different from exception types that are normal catched e.g. argument and state exceptions.
  • It could have sanity checks... e.g. was that a field null that you turned into a NullArgumentException?
  • It could help standardize the fail-fast principle.
  • It could extendable for you to add your own types, checks and fails.
  • It could be performance tested.
  • It could be well-tested.
  • It will be open source.
  • ...

How would I use it?


Your Feedback

Any feedback is greatly appreciated! 
  1. Did you know about the fail-fast principle?
  2. Do you or would you use the principle?
  3. Are you interested in using a FailFast-library as outlined above?
  4. Do you have any ideas or concerns?

... and thank you for reading!

2012/12/27

Append OrNull to a method that returns null

Introduction

  1. "A boy is told to buy a green Apple. He returns with a yellow Apple."
  2. "A boy is told to buy a green Apple. He returns with null."
  3. "A boy is told to buy a green Apple, if available. He returns with null."
  4. "A boy is told to buy a green Apple. He calls back from the Store to tell that a green Apple is not available."
Add#1: 
Do not return something else than asked for... unless the method name indicates so. 

Add#2: 
The return value null is an unexpected value. Returning it requires extra code on the calling side of a method call. If the extra code is missing, the null value may lead to errors that cannot easily be traced back to the method-call that returned null.

Add#3:
It is so easy to get this right. Simply append OrNull to your method name and return null. 
An alternative could be to have a bool argument e.g. allowNull or something, but that is much more cumbersome.

Add#4:
This is the default way of a method. Do what it is told or throw an exception. 
The method cannot solve this case, so the best thing is to tell the calling side so. In development this leads to run-time exceptions that should be avoided by modifying the code on the calling side. 


Description

The default way of making a method is to make it as simple as possible in such a way that it always fulfills its task. By default a method should return a non-null value or throw an exception. 

This rule is for the cases where null is an expected value. Returning null does not fulfill a task unless the method implies so. Hence, append OrNull to the name of method if it returns null. 

Returning null also requires the calling side to something extra. Therefore, when creating an OrNull method make sure to create a default version of the method too - one that throws an exception. If the calling side expects a non-null value, it will use this method instead.

Example

Default method TakeApple and TakeAppleOrNull alternative. CountApple is a related helper property.

Misc.:

- Use the FailFast principle (http://www.martinfowler.com/ieeeSoftware/failFast.pdf) whenever possible.
- When creating a method, consider if other related methods can help the calling side e.g. a Check/Exists/Count method.