Framework development is hard

Note: I intended to make this article only as draft or brainstorming article, however my idea maybe useful for some of the reader. This article will lack supporting source and theory, and maybe having un-arranged topic. I’ll try to publish another article after some time after this to re-arrange the writing.

Have you ever tried to develop framework, or even as simple as code library? Is it easy? Is it hard? Well yeah, the answer is it depends. It depends based on the complexity and size of framework/library you develop. But I think that it is fairly easy to develop at start. It will get harder to develop when the framework is already large enough, especially modifying existing features.

I can’t imagine how hard the developer at .Net / C# is when developing new version.

Backward Compatibilty

It’s hard. Jon Skeet also say that backward compatibility is hard. I have developed a medium-sized framework for Asp.Net MVC server side for around 1 year. In that elapsed time span, I have made around three breaking changes. Without good architect / planner, the library will be likely have bad structure and need to be refactored much.

I don’t think that if asp.net still support backward compatibility with asp classic, it will still have the utilities and flexibility as it have now. What will happen if the new C# version does not consider backward compatibility? What powerful feature that can be introduced by the breaking change? Here I will say that “without backward compatibility, the new version of a framework should be much more powerful”.

Defining name, namespace categorization

Defining name is not easy. Often I don’t know how to name a specific class / operation. In a worse case, the class name will be very long to express the operation.

Categorizing the operation is even harder. Will it be put under Excel namespace? App namespace? Web namespace? Javascript? etc. Most of the time I refactor is because the incorrect namespace category / project placement.

Flexible / Parameters definition

Developing framework / library is not easy. Developing flexible library is even harder. Most of the time, the breaking change will happen at different parameter definition. Mostly can be handled using default parameter, while the other need to be added or modified, introducing breaking change.

Another problem during developing library is the amount of parameter required for an operation (function / method). Often we find that the operation need many parameters. That kind of structure is not recommended, because it will make the operation harder to use. Encapsulating the parameters into one class may be useful, but again it introduce another model. Moreover, many parameters usage is a sign of “god object“, which is hard to maintain.

Parameter initialization / life cycle

Parameter initialization is another pain. Many times I find the case where when I want to use object A in class X, it haven’t been fully initialized yet. Or worse, you can only use object A in class X after you do operation Z.

The setup + parameter structure

Despite the limitation, I like the idea in some of .Net’s library structure. XmlSerializer is one of them. The process that is needed to use XmlSerializer is: instantiate object, define setup, do operation (serialize). Inside the class, there exists some “setup” object, where you can modify to change the operation behavior, instead of passing all the setup objects yourself. Moreover, it has “default” setup parameter, in which you will need less effort rather than constructing the setup parameter down from zero.

It has limitation though, the “mutability”. The mutability at service object is bad. You cannot use the same object over and over again. One object is used one operation, unless the same setup is required at the operation. Don’t use the setup + parameter structure when you are using long-lasting object (such as static object).

Separate context class with service class

I am the follower or Anemic Domain Model pattern despite being classified as anti pattern. I think ADM with POCO class (DTO-style) really supporting SRP, instead using RDM, in which we can easily fall into the god object anti pattern. It’s not that I say RDM tend to violates SRP, however I find that in most case, it is easier for RDM to violates SRP rather than ADM’s antipattern bring cause.

That’s why I usually like to separate context class (as data model) with service class (the operation). The context is an object that hold all the data required during one “operation life cycle”. Example: AppContext hold all data required during application running. Setup class is a context, it holds all the data required during the class’s operation. In Asp.Net, RequestContext holds all data required during the web request.

Meanwhile service class hold almost no data and only responsible to process the request passed from parameter (in exception to the setup class). StringBuilder is one of them. I also like to separate entity (domain model) class with it’s operations. That way, I can easily develop more class to handle different business rules and cases.

The separation is intended to scope and encapsulate the operation / context. That scoping will be useful to make the class’s modification easier. Any modification happen at one service class won’t break other operation in other service class.

Don’t refer to static context directly

I admit, I also like to do something like this:

public void Do(){
    string userId = App.Context.Current.User.UserId;
    if(userId == "....") { /*the operation*/ }
}

It is a bad design in general, because we cannot use the service without the context. However, passing the context into parameter is out of question. It will increase operation complexity. However, you can separate the context into class’s property and do lazy loading for default context.

private App.Context context;
public App.Context Context{
    set { this.context = value; }
    get { return (this.context ? (this.context = App.Context.Current)); }
}

public void Do(){
    string userId = this.Context.User.UserId;
    if(userId == "....") { /*the operation*/ }
}

Now you can mock the context easily and provide it to the class before processing. And it’s testable now.

Conclusion

Framework development is hard.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s