How to make your c# code more OOP with delegates pt 2

Implement the strategy pattern with delegates

Changing the default behavior of a method under testing (or any other specific circumstance)

Given the following code:

class EmailSender{
    
    public void Send (string recipient, string subject, string body) {//invoke 3rd party}
    
}

class Email{
    
    public EmailSender _sender = new EmailSender();

    public Send(){_sender.Send(recipient, subject, body);}
    
}

Imagine that you cannot change the Email class. How would you unit test it without making a call to a 3rd party service?

Answer: inject a delegate with the desired behavior.

class EmailSender{
    
    Action<string,string,string> _sendAction = _send; //default action
    
    public void Send (string recipient, string subject, string body) {
     _send.Invoke(recipient, subject, body);
    }
    
    public void _send (string recipient, string subject, string body) {//invoke 3rd party}

    internal void ActivateTestMode(  Action<string,string,string> testAction){
     _send = testAction;
    }

}

 

Specializing the rules of a domain object without inheritance

Given the following code:

public class BonusCalculator()
{
  List<Bonus> bonuses = new List<Bonus>();

  public BonusCalculator(ICollection<Bonus> bonus)
  {
    bonuses.AddRange(bonus);
  }

  public decimal CalcBonus(Vendor vendor)
  {
   var amount = 0;
   bonuses.foreach(bonus=>amount += bonus.Invoke(vendor, amount));
   return amount;
  }

}

public class BonusCalculatorFactory()
{

   public BonusCalculator GetSouthernBonusCalculator()
   {
    var bonuses = new List<Bonus>();
    bonuses.Add(new WashMachineSellingBonus()); 
    bonuses.Add(new BlenderSellingBonus ()); 
    bonuses.Add(new StoveSellingBonus ());

    return new BonusCalculator(bonuses);    
   }

}

If we want to add a new bonus that increments the 15% we would have to create a new class just to do that multiplication… So let’s try something different.

public class BonusCalculator()
{
  List<Func<Vendor, Decimal>> bonuses = new List<Func<Vendor, Decimal>>();

  public BonusCalculator(ICollection<Bonus> bonus)
  {
    bonuses.AddRange(bonus);
  }

  public decimal CalcBonus(Vendor vendor)
  {
   var amount = 0;
   bonuses.foreach(bonus=>amount += bonus.Apply(vendor, amount));
   return amount;
  }

}

Now we have to modify the factory

public class BonusCalculatorFactory()
{

   public BonusCalculator GetSouthernBonusCalculator()
   {
    var bonuses = new List();
    bonuses.Add(new WashMachineSellingBonus().Apply); 
    bonuses.Add(new BlenderSellingBonus().Apply); 
    bonuses.Add(new StoveSellingBonus().Apply);
    bonuses.Add((vendor,amount)=> amount * 1.15); 
    return new BonusCalculator(bonuses);    
   }
}

 

Easy peasy. Now depending on how it is implemented, we could start thinking about turning some of the rules into singletons.

Moving the control flow into objects

How many times have you started an operation where you want to know 1) if the operation was successful and 2) the return value. A lot of times this leads to code like:

class OperationResult{
    public bool IsSuccess{get;set;}
    public object ResultValue {get;set;}
}

interface IDataGateway{
    OperationResult UpdateName(string name);
}

class NameUpdaterCommand{
    string _name;
    IDataGateway _data;
    Log _log;

    public NameUpdaterCommand(string name, IDataGateway data, Log log){
       _data = data;
       _name = name;
       _log = log;
    }
    
    public void Execute(){
        var result = _data.UpdateName(_name);

        if(result.IsSuccess)
            _log.Write("Name updated to:" + Result.Value.ToString());
        else
            _log.Write("Something went wrong:" + + Result.Value.ToString());
    }
}

Come on, don’t be shy about it. I’ve done it myself too…

So what’s wrong with it?

Let’s see, the intention behind this code it’s to decide on a course of action based on the result of an operation. In order to carry on these actions, we need some additional info for each situation. A problem with this code is that you can’t handle an additional scenario. For that to happen instead of a boolean IsSuccess you would have to create an enumerator of sorts. Like:

enum ResultEnum{
    FullNameUpdated,
    FirstNameUpdated,
    UpdateFailed
}

class OperationResult{
    public ResultEnum Result {get;set;}
    public object ResultValue {get;set;}
}

interface IDataGateway{
    OperationResult UpdateName(string name);
}

class NameUpdaterCommand{
    string _name;
    IDataGateway _data;
    Log _log;

    public NameUpdaterCommand(string name, IDataGateway data, Log log){
       _data = data;
       _name = name;
       _log = log;
    }
    
    public void Execute(){
        var result = _data.UpdateName(_name);

        switch(result.Result){
             case ResultEnum.FullNameUpdated:
               _log.Write("Full name updated to:" + Result.Value.ToString());
               break;
             case ResultEnum.FirstNameUpdated:
               _log.Write("First name updated to:" + Result.Value.ToString());
               break;
             case ResultEnum.UpdateFailed:
               _log.Write("Something went wrong:" + + Result.Value.ToString());
               break;
        }  
    }
}

So now every time you want to add a new scenario you have to add a new enum value and a new case on the switch. This is more flexible than before but a little more laborious than it should be. Let’s try to replace this enum based code with objects that represent each case:

interface IDataGateway{
    void UpdateName(string name, Action<string> firstNameUpdated, Action<string> fullNameUpdated, Action<string> updateFailed);
}

class NameUpdaterCommand{
    string _name;
    IDataGateway _data;
    Log _log;

    public NameUpdaterCommand(string name, IDataGateway data, Log log){
       _data = data;
       _name = name;
       _log = log;
    }
    
    public void Execute(){
       _data.UpdateName(_name,
                     fullNameUpdated: name  => _log.Write("Full name updated to: " + name),
                    firstNameUpdated: name  => _log.Write("First name updated to: " + name),
                        updateFailed: error => _log.Write("Something went wrong: " + error )
        );
    }
}

So now we have a shorter code. We have also moved the responsibility to control the flow to the object implementing IDataGateway. How it does it is just an implementation detail. We don’t care if it’s using an enumerator or any other mechanism as long as it works.

Phew! I think that’s enough for now. Now go improve your code!

 

The OOP wars

Some time ago I had an interesting discussion with Tony Marston. Suddenly I found myself on the middle of what seems to be an ongoing war related to what’s OOP. It seems to (still) be a heated debated on some circles, so I want to share some thoughts on the topic.

The origins

So around 1962, 2 guys from Norway (Ole Johan Dahl and Kristen Nygaard) extended the Algol programming language to easily create simulations. They called the new language Simula. The idea was that “A discrete event system is viewed as a collection of processes whose actions and interactions completely describe the operation of the system”. Little did they know that they work would create a revolution in the programming community.

The calm before the storm

Sometime after the invention of Simula, in 1966, a newly graduated from the University of Utah came in contact with it. As he tried to understand the concepts behind this newborn language something made click in his mind. His name was Alan Kay and he was the one who coined the object-oriented programming term. His vision was profound yet simple: a net of interconnected software computing units called objects sending messages to each other. His idea was the software equivalent of the internet. He also had the idea of a network of interconnected computers by either a wired or wireless mean by the way.

Around 1979 a Danish man called Bjarne Stroustrup was working for AT&T Bell Labs, where he had the problem of analyzing the Unix Kernel with respect to distributed computing. The problem was that C was way too low level for a large system. It was then that memories from his Ph.D. thesis, which has been written using Simula, came back. Using Simula as a base, Bjourne extended C to support classes, which he called “C with Classes” and later “C++”.

The smalltalk faction

Smalltalk it’s the brainchild of Alan Kay. It’s the reification of his vision. The language itself it’s pretty compact.

Smalltalk sports a dynamic typing system, that is, the type is not enforced at compile time.

An object is a computing unit that sends and receives messages. The user defines which actions must take place when a given message is received by a specific object. If there’s not action defined for a particular message, then the object notifies the system with a ‘message not understood’ message.

Alan Kay was heavily influenced by LISP. In LISP everything is a list: code, data, everything. This allows powerful metaprogramming techniques. Kay build upon that metaphor: everything in smalltalk is an object. Everything. A number is just an object which knows how to respond to messages like “+ 3”. A string is an object that knows how to respond to messages like “reverse”. Even inline functions/closures are objects (known as blocks) that respond to a “value” message. That’s all there is to it. This is the reason why static typing is unnecessary: you just care whether the object can respond to a message or not.

The C++ camp

C++ was designed with systems creation in mind. As such it deals with stuff like performance and memory footprint. If you are familiar with C, C++ it’s a natural evolution. It can be tricky, however, to get the most out of the object extension. This is due to C++ being a multiparadigm language, meaning that you may still resort to solutions in a different paradigm that could be implemented in a cleaner way using OOP. Stroustrup talked about this in his 1995 OOPSLA paper (see the concrete types section).

It uses a static type system, so the compiler validates every type and related operation.

An object is a structure of data along with methods to manipulate that data. You directly invoke the methods on the object.

Classes are a type extension mechanism, allowing the developer to create a DSL on top of C while still having access to all the lower level features. In order to circumvent some of the problems that arise from a static type system, it introduces templating, which allows a higher reusability.

The eternal bashing warfare

So, the eternal discussion about OOP stems from these 2 schools of thought. To some, OOP is nothing more than procedural programming plus encapsulation, inheritance and polymorphism. To others (myself included) it involves a completely different mindset. The reality is that C++ is indeed an object-oriented extension on top of a procedural language whereas smalltalk is a completely new language that heavily draws from the functional realm. Therefore, the claims from each group are valid depending on the point of view. As someone who learned OOP using C++ I have found very beneficial to learn smalltalk later. Really, having nothing else than objects to work, helped me understand the boundaries between OOP and Procedural programming, helping me shape my approach to OOP design and decomposition.

Peace to the world

So, whether you belong to the smalltalk or the C++ party, remember to be tolerant to other people point of view. It’s an absolute benefit to learn to see from another perspective. So next time you find yourself on another OOP battle camp remember that the ultimate value comes from learning to work together, despite differences, than to demonstrate that you’re right and everybody else is not.

Happy Holidays!

Software developer profiles

In my last post I talked about how a developer could improve his skillset by breaking it down in 3 areas: Principles, Technology and Industry knowledge. So depending on how the time is invested, chances are that he will fall in any of the following stereotypes (T=Technology, I= Industry, P= Principles. Order indicates depth of expertise):

T+I+P

This is by far the most common type of software developer that I have found on my interviewing experience. These are students that graduated from school using visual basic (or any other RAD) and then went on to create forms over data kind of software with not really complex rules. Even when they move to JAVA, they’re still coding with a VB mindset. They can create something out of thing air quickly, but often it’s a BBOM and very hard to maintain. Depending on the time and the kind of projects he/she can start to evolve towards a more principles focused practice. Or just continue doing the same thing for the next 10 years. I usually try to figure out where on the spectrum between these 2 poles is the candidate.

I+T+P

I have seen more and more developers of this kind lately. They are usually people like the accountant that learnt SQL on it’s own. As the final user of the software, he can create and tweak the software to adjust to his necessities. Since they lack any formal engineering education the resulting code is often no better than that of a student. I have worked with this kind of developer but have never interviewed one.

P+I+T

These typically are software developers that spend a lot of time on an enterprise, creating level enterprise software. This forced them to look to better ways to create software that’s stable, maintainable and robust ultimately leading to a better understanding of the principles, patterns and practices. However the rate of adoption of new technologies in the enterprise is rather slow (some are still running on AS400) so they are behind the technological wave. Nevertheless they understanding of the more general principles allows them to pick up quickly on new technologies and languages. Whenever I came across this kind of candidate I usually recommend him/her on the spot.

P+T+I

This is the typical software developer that graduates school and enter to work in a software workshop, creating software for other clients. He understands the importance of creating good software and try to improve his skills as time goes. However unless he/she is assigned to a customer for a very long time, his understanding of the industry is limited to the scope of the projects assigned to him. Whenever I came across this kind of candidate I usually recommend him/her on the spot.

where are you now and where are you heading?

Final thoughts

In my experience the seniority of a software developer is dictated by the deep of his understanding of the principles, patterns and practices. The reason being that the quality of the overall software is deeply affected by this. You can always correct a DOM manipulation done by JQuery to use the Angular mechanisms, but correcting an faulty architecture or a leaking abstraction is a far more complex matter. That is why is important to take these decisions with a solid understanding of its consequences.
So you can have a developer with a good understanding of principles and 0 experience using Angular and expect him to write better software than a developer with 5 years of Angular and a poor understanding of the principles. The latter may be quicker, but the former will create something of a higher quality. Uncle Bob has reiterated this more than once and asked for us as software developers to raise the bar. If you follow on his works (talks and books) you’ll see that his emphasis is on the principles, not the technology.

As always, let me know what you think.

Knowledge management for software developers

There are 3 different kinds of knowledge that a software developer has to manage on his professional career. I called them principles, technology and industry knowledge. There is other relevant stuff such as soft skills but today I’m focusing on knowledge not skill sets.

Principles

Before continuing I want to clarify what I mean by principles: borrowing the title from uncle bob’s famous book I’m referring to principles, patterns and practices (with a little twist from the book’s meaning).

Principles are technology agnostic. They can be applied generally on a wide set of circumstances. An example would be the DRY principle which is universally recognized as a good practice in software engineering (no matter if you work in an OOP or a functional paradigm).

Patterns are often limited to a specific mindset, a paradigm.

A good example here could be the null object pattern. It makes sense in an OOP context, but it lacks when used in procedural programming.

Patterns are usually a trade of simplicity for flexibility the latter being derived of some of the paradigm traits. You could say that it maximize some of the paradigm benefits at the cost of simplicity: the code may be complex to understand to someone not familiarized with the paradigm but at the same time is easier to change once understood. The secret here lies in one’s ability to use the paradigm thinking process. As with everything else, practice leads to mastery.

You can find a compilation of these patterns in almost every development paradigm, with names that make it easy to refer to them when talking with other developers.

Practices refer to the way we develop code. It includes stuff like refactoring, testing, incremental delivery and so on. They’re usually outlined in a software development methodologies and some are expressed as conventions. While they can be widely applied, we are usually use and learn them in the context of a team or project’s specific configuration.

All of us have a certain a familiarity degree with each of these concepts. However, not all of us are conscious that they are interrelated to each other i.e. comprehension of some principles can help us decide when to apply certain patterns. This kind of knowledge ultimately leads to better code and designs.

Technology

This is probably the kind of knowledge that most developers spend the most time learning. This makes sense: with so many new technologies every other week, we must try to keep up or we’ll be at the risk of becoming obsolete. In a sense technology is like a fashion trend: we have something new this summer, but as soon as autumn arrives a new framework that promises help us code faster takes the lead. Unless someone deliberately chooses to ignore the latest trends, there is just not enough time to become really proficient with a single technology. I usually think of technology as software platforms, libraries and frameworks.

Software platforms are the environments on which the code is executed (.net, nodejs, Java). I like to think about software and not hardware platforms because software platforms are often able to run on different hardware platforms i.e. java can run on a mobile, desktop or server platform.

Software libraries provide a very specific functionality that can be used in multiple projects i.e. JQuery purpose is manipulation of the DOM. They are methodology agnostic which means they’re really flexible when it comes to workflow types. This property makes them easy to be reused and ported between team, jobs and industries.

Frameworks often provide a set of libraries to accomplish something more complex. We even have application frameworks such as Spring, which handles everything from retrieving data to displaying it. Or Angular which provide us with the tools to create a presentation layer and communicate with the backend. One difference between a framework and a library is that a library provides just you with the tools to do things while the framework also enforces a (often highly opinionated) way to do things. This makes it harder to integrates them on an ongoing project (as opposed to a library) but are a great choice if you are starting from the ground up.

Most of the time, software libraries and frameworks are tied to a software platform, so you naturally learn the ones that run on your platform of choice (like Java or nodejs). Sometimes ports of these libraries and frameworks can be made (like hibernate to nHibernate), but most often than not they will make some adjustments to take advantage of the platform particular characteristics (meaning there are changes on the API).

Industry

This is often a byproduct from working on a project. As a software developer you really don’t study accounting unless you are creating an accounting software. Or banking. Even worse, sometimes we just limit ourselves to create what the customer requirements document says, without even trying to understand the purpose of the software or the needs of its users. Eric Evans pointed this out and explains that the reason is because this kind of knowledge is not useful to us unless we intend to keep on the same industry (like manufacturing). In other words, its reusability scope is very limited when compared with the other kinds of knowledge. However as Evans also explains, a deep understanding of the industry it’s necessary if we really want to create not only a good thing but the right thing.

Mix and match

The time you spend on each of these kinds of knowledge leads to a different set of abilities. Try it out!

  1. Evaluate yourself on each of these kinds of knowledge
  2. Select the area you’re lacking the most (principles, Frameworks, you pick)
  3. Make a 3 month plan to improve
  4. Start over 🙂

As always, your comments are welcome!

Leaky abstractions and how to deal with them

Leaky abstractions is a term given to a faulty model, that is a model that fails to express some domain concepts. I found this to be a natural step on the process of creating a rich domain model. The problem comes when we stop refining the model, ending up with an incomplete work.

The school example

John was tasked to create a system to replace a legacy school administration system. His initial approach was to review the old systems database to extract the underlying entities. If not the code, at least he could reuse the abstractions. So, he ended up with the following abstractions:

Then he proceeded to work with the first use case/ user story: student registration. When finished, it looked something like:

“So far so good”- John thought – and he went to work on another use case. However, as he progressed he notice that the student object was over bloated: it contained info no only related to the student performance but also financial and historical data. Can you guess why?

Hunting a missing abstraction

Turns out that since every career has its own set of requirements, the student object had to accommodate all the data needed by every career prospect evaluator object.

The problem with John’s model it’s that is missing an abstraction. Thus, he is reusing another abstraction in place. Unfortunately, that’s a COMMON mistake. And one with a HUGE impact. The missing part here is the application the student submits. Let’s introduce this into the model.

This frees the student object to represent an actual student and nothing more. Now we can have the AccountingEvaluator evaluate an AccountingApplication.

By doing this we have:

  1. Reduced coupling since the student object is not dependent on the requirements of the program evaluators.
  2. Made the code SRP compliant, hence easier to maintain.

Keeping it simple

By this point some may be thinking that we increased the cyclomatic complexity since now we have to figure out the right evaluator for each application. Something like this:

 

Public void Submit (ProgramApplication app){
    var type = app.ToString();
    switch(type){
    …Code to select the right evaluator…
    }
}

But this can easily be fixed by putting the responsibility into the application objects themselves:

public interface ProgramApplication{
   bool IsApproved();
}

public class EngineeringApplication: ProgramApplication{
  decimal _mathScore;
  public EngineeringApplication(mathScore){
     _mathScore = mathScore;
  }
 public bool IsApproved(){ return _mathScore > 90} 
}
public class AccountingApplication: ProgramApplication{
  decimal _mathScore;
  public AccountingApplication(mathScore){
     _mathScore = mathScore;
  }

   public bool IsApproved(){ return _mathScore > 80}
}

//call on the client side

Public void Submit (ProgramApplication app){
 if(app.IsApproved()) ...
}

This is good design as it encapsulates the application evaluation details.

Closing thoughts

John’s is a typical scenario of leaking abstractions. The problem here is that he believed the domain model of the legacy system to be complete. This is a common mistake when starting a new project (either green or migrating any obsolete piece of code). We must remember that the moment we know less about the business is at the beginning. It’s naïve to expect the domain model to be complete on this stage. I learned at school that aversion to change is a human trait, but don’t hung up to faulty model. If it’s too complex, we’re doing it wrong.

Keep refining your model and have fun!

How to handle dependent observable calls in an async call in Angular 2/4

Recently I’ve been working with Angular 2/4. One day I came across with something like this:

public getCustomersOnArea(zip:string):Observable<Customer>{..}

The problem was that we had to make 2 calls to get the data. Even more one call depended on the data fetched from the other. How to solve this? One way it’s to encapsulate the 2 calls into a third one and return that to be subscribed.

public getCustomersOn(zip:string):Observable<Customer>{

return new Observable<Customer>(subscriber => {
            this.http.post(zip)
                .subscribe(res => {
                    this.http.post(res)
                        .subscribe(r => {
                            subscriber.next(r);                           
                        },
                          e=>  subscriber.error(e),
                          ()=>  subscriber.complete());
                });
}

And that’s it. Do you know another way? Leave it in the comments section

Are you a bad programmer?

I believe that knowing where are you lacking will make you a better programmer. At least a more aware programmer. However, having someone to point out what we are doing wrong is something not everyone can handle. That’s why self evaluations are so valuable. But you need some sort of standard in order to do so. I found an old (but still valid) post interesting enough to share. I gained some insights about the stuff that I need to improve from it. You can find it here. Do the exercise and let me know how it goes.

DDD vs Clean architecture: hosting the business logic

In my previous post I mentioned that there are 2 types of code: business and plumbing. I pointed out that business code is not meant to be reusable in as much as plumbing code. The reason is simple: business code is business specific, which means is tailored to a specific business way of doing things. But even more, this code can be sub domain specific; i.e. think of a pencil factory: it has several departments such as Marketing and Engineering. To them, the word “product” can mean something very different.

Are business objects sub domain exclusive?

So the question here is: how do we dealt with scenarios where the same concept has a different meaning to different people in different departments? Let’s see how 2 fabulous architectures approach this problem: Domain Driven Design by Eric Evans and Clear Architecture by Robert C. Martin.

Make the context explicit

So Eric Evans makes a clear declaration on the matter: objects are context bound. By context we mean sub domain/department. He makes the context explicit so the behavior of the objects it’s defined by the context they live in. Going back to our first example we would declare 2 contexts: one for marketing and one for engineering. This could be easily represented as namespaces or packages. So now we can have a product object in the Engineering context which can determine how many pieces of itself can be build with the raw materials in stock. Something like:

var product = new Engineering.Product();
int qty = product.BuildWith(currentStock);

While the product object on the marketing context may look something like:

var product = new Marketing.Product();
decimal price = product.PriceFor(aGoldCustomer);

DDD is not afraid of having 2 different classes with the same name in their own context each. Truth be told, trying to have a single object to represent the different concepts in each domain is the result of a wrong abstraction process.

Make the objects gluten free

The alternative proposed by Clean Architecture is to create business objects with the most basic behavior, which allows for them to be reused in different contexts.These business objects are then used by use case objects. The context here doesn’t need to be explicitly defined. It can be implicit in the use case object. So while the business objects feature enterprise wide behavior, the use cases objects contain the application specific behavior, that is, the rules used by the context on which the use case is defined.

CreateNewCustomerOrder{
 ...
 Execute(){
  var product = new Product();
  decimal price = product.GetCost() *1.5; 
  ...
 }
}

CreateNewProductionOrder{
 ...
 Execute(){
  var product = new Product();
  decimal totalOperationCost = product.GetCost() * qty;
 ...
 }
}

The answer lies in the abstraction

So as you can see both DDD and Clean Architecture are very similar. They both put emphasis on the business objects. Both decouple the domain from any external dependency. Both have objects to represent use cases and accomplish their mission coordinating the business objects. The difference lies in that while DDD puts all the business rules in the business objects in as much as possible using a level of abstraction closer to the context, the clean architecture uses higher level of abstraction on the business objects and a level of abstraction closer to the context on the use case objects. In the end all comes down to the degree of abstraction that you choose your domain to be on. So which style do you found most attractive?

Let me know your thoughts.

Generic code vs flexible code

It was on one of those rare occasions: We we’re starting a new system from scratch. The excitement was palpable. As some devs(myself included) started using TDD, some other where busy trying to figure out an architecture to hold everything in place. We decide to hold some code reviews to keep everyone on the loop. And that’s how the clash happened. I was astonished when another developer suggested that our code wasn’t generic and so it was unable to cope with the changing requirements. It was true that our code wasn’t overly generic. But it was flexible.

The quest for adaptability

Adaptability is a desired trait in software because it helps us cope with changes without having to rewrite everything from scratch. Typically you deal with this by 1) making the software so generic that there’s no need to change it, just configure it and you are done, or 2) by making the code easy to change.

The difference between the 2 strives on the abstraction level.

Generic code

Generic code embraces the idea that you can have one code base to rule them all. All you need to do is make it highly reusable. The key is to work at a high level of abstraction. Doing this has the benefit that a lot of customers can use the system as long as they don’t have specific requirements. Let’s consider an Agenda application. You could use an AgendaItem to represent anything from an appointment with your boss to a reminder to pick the laundry before sunday. So let’s say you want to introduce project management. How would you tackle that? You could modify the AgendaItem to include another AgendaItems. So now every AgendaItem can represent an appointment, a reminder or a project. Can you see what the problem is? By working at a higher level of abstraction you can represent a lot of the stuff that can be put on an Agenda but this will become increasingly harder to maintain as changes required by the different concepts it represents will force the AgendaItem object to grow complex over time. Even so you’ll be fine if you don’t need to manage projects or if you create a list somewhere else to relate certain AgendaItems to a project.

Flexible Code

On the other hand of the adaptability spectrum, we have flexible code. Flexible code in this context means code that is easy to change to accommodate new features.

The big question

So let’s say you are starting a new project, should you go for a Generic or Flexible code base? Well… it depends. Are you working on a Line Of Business application? Are you making a framework for others to use?

On a Line Of Business application

There’s 2 kinds of code: business specific and what I call plumbing code.

Business specific code is the code we are paid to write. It adds value to the business. It contains it’s particular rules. The business doesn’t care about the database choice, the technology stack or the OS on which the application runs. And the code that contains their rules and logic shouldn’t either. Don’t be afraid to model your objects to reflect your specific business even if it’s a bit different from the rest of the industry. This code is no meant to be reused outside your application.

Plumbing code refer to all the code that is common in almost every application: things like mail sender objects, ORM, frameworks… that sort of stuff. Void of logic, highly reusable.

A LOB application contains both kinds of code, but the plumbing code must serve the needs of the business code.

On an application framework

Think of code like Angular, the javascript framework. That’s stuff designed to be used by other developers to create web applications. As such it’s void of any application specific code which makes it highly reusable. It also uses highly abstracts concepts, such as that of a component which can represent pretty much anything on the screen: from a link to a complete page.

The trap of reusability

The problem arise when we want to reuse everything on a LOB application; that’s a crazy idea! The moment you decide to reuse the business specific code, you force yourself to start thinking on a higher level of abstraction thus leading to a very generic code and as we have already seen, that makes it hard to implement specific business rules. Do not fall into the trap that everything has to be reusable. Odds are that the next project you work on the same domain, you won’t be able to reuse your domain objects due to the specific client/business rules. When it comes to LOB applications, is the knowledge and not the business specific code what’s reusable.

Closing thoughts

If you are working on a LOB application, go for a generic style on the plumbing code, but take a flexible approach for the business specific code, that is do not go too abstract on this. If you are working on an Restaurant application, don’t create a “dish” object with an ingredients collection that represents everything you can serve there. Instead make explicit representations for each dish. Is that an Italian restaurant? Chinese? Thai? Then make a “spaghetti” object, or a “dumpling” object. They all may inherit from a “dish” object and contain an ingredients collection but they are not generic dishes. They are the restaurant dishes, the business products, and you want to identify them as that. Don’t be afraid to be specific.

This all may sound like common sense and it is! It’s just that in my experience, common sense is not always common practice.

Let me know your thoughts.