Arseni Mourzenko
Founder and lead developer
November 9, 2014
Tags: refactoring 12

When mod­i­fy­ing a sys­tem (such as adding fea­tures), one should be con­cerned about the abil­i­ty of the sys­tem to be mod­i­fied. This im­plies the pres­ence of two ex­ten­si­bil­i­ty as­pects: ar­chi­tec­tur­al and qual­i­ty-cen­tered. I be­lieve it is es­sen­tial to un­der­stand the dif­fer­ence be­tween those two as­pects, es­pe­cial­ly in or­der to de­ter­mine what are the most ap­pro­pri­ate so­lu­tion.

Ar­chi­tec­tur­al ex­ten­si­bil­i­ty

The is­sue of­ten en­coun­tered when de­vel­op­ing a sys­tem larg­er than two men-months is that the orig­i­nal ar­chi­tec­ture is un­able to en­com­pass some new fea­ture. It just wasn't done for that, and now that the fea­ture ex­ists in the back­log, de­vel­op­ers are won­der­ing how could they bend the ex­is­tent prod­uct to be able to add the re­quest­ed fea­ture.

The im­me­di­ate so­lu­tion here is high-lev­el refac­tor­ing. By high-lev­el refac­tor­ing, I mean all those changes which deal pre­cise­ly with ei­ther ar­chi­tec­ture—if the team is able to change the ar­chi­tec­ture, or high-lev­el de­sign. By com­par­i­son, low-lev­el refac­tor­ing is about to re­name meth­ods or trans­form switch block into in­her­i­tance. Note that both are cru­cial, so high-lev­el refac­tor­ing is not more im­por­tant than low-lev­el one.

Also worth not­ing, two tech­niques help to ei­ther avoid is­sues with such ex­ten­si­bil­i­ty, or to re­duce the pain of do­ing ma­jor changes in ar­chi­tec­ture:

Qual­i­ty-cen­tered ex­ten­si­bil­i­ty

This is the is­sue which is en­coun­tered more when ex­tend­ing a lega­cy code base. For ex­am­ple, a de­vel­op­er is asked to add a sim­ple fea­ture to an ap­pli­ca­tion, but spends weeks im­ple­ment­ing it, be­cause a slight change to one part of the code base breaks some­thing in a dif­fer­ent part which looks com­plete­ly un­re­lat­ed. Here, the prob­lem is not the ar­chi­tec­ture—it can be to­tal­ly adapt­ed to the new change, but rather the qual­i­ty of the code it­self.

The is­sues can be mul­ti­ple: the lack of prop­er test­ing with enough code cov­er­age, the ab­sence of com­mon style, the lack of doc­u­men­ta­tion, etc.

The im­me­di­ate so­lu­tion is low-lev­el refac­tor­ing, as well as deal­ing with the real is­sue be­fore adding the fea­ture.

Again, two long-term tech­niques to avoid such is­sues: