Software Design for adaptability is important in some deployment scenarios where a lot of envioronment related dependencies can change. Its a common requirement encountered during the software maintenance lifecycle. Infact IEEE calls it Adaptive Maintainability, one of the four types of maintainability attributes.
As a general rule, software can depend on one or more of the following:
(1) A Target hardware (CPU) architecture or family (unless you are writing Java code)
(2) OS Services
(3) Middleware services (like Database, Logging, Tracing, Alarms, etc)
(4) 3rd Party ISV supplied libraries or software modules
(5) Open Source software
(6) Another internal software from within your organization which belongs to a different business unit and simply not your competency wrt to developing that (you only are a user)
(7) Network and Peers
I would assume that you are programming in C/C++ which are particularly sensitive to environment changes being closer to the hardware and OS. Though (3)-(6) are language independent issues.
These dependencies change over a period of time and a well written software is able to forsee this change (probably on the basis of probability or even domain experience) and safegaurd to core functionality against this change. The agile folks would argue aginst that non-existing requirement, but I am fine if you conciously taking this debt and prepared to pay it down the line when required, whatever may be the cost. Otherwise, you may read ahead. Some strategies which can mitigate the impact of chnage can be:
(1) Do not use assembly language snippets in code. Keep your code endian aware for data formats or better make it endian independent. Avoid depending on CPU specific optimizations in such a way that they become critical to the operation of the software. If possible the code should be 64 bit ready (32 bit are dying out slowly. Now they are invaliding the mobile space also as DRAM sizes increase). Avoid excessive optimization for a particukar CPU architecture (it may not work equally well on other).
(2) Previously the sheer multitude of OS were mind-boggling (UNIXes, Windows, Linux, RTOSes). Each had its own APIs with miinor or major differences in APIs. Now they have rationalized to linux and windows (unix and RTOSare dying out). Try sticking POSIX APIs if you are making OS calls directly. Avoid kernel specific feature usage (like Linux kernel synchronization options) as they are non-POSIX and will make your code dependent on the Linux kernel. Consider wrapping all OS APIs with a wrapper layer (or Proxy), so that the business logic is kept independent of the OS. Have a dedicated test suite for adaptation. When porting just chnage & test the adapatation first and this will get rid of the big issues. Take care of instances where the API signature is same but partamter values and/or behavior is slightly different (Ideally the OS adpatation layer should mask signature, paramter range and behavior to be truly an adaptation layer). Similarly your buildscripts (makefiles) should be written in a manner that they can work for any OS, CPU and with any compiler tool.
(3) Usually the database which one uses is one candidate which changes regularly (licensing, performnace, customer preferencing etc are typical reasons) and therefore it makes sense to have an addaption layer for database access. Similarly in another deployment scenario the middleware componnets of SMP like log, trace, stats, etc might be different and therfore the adaptation will help shield the business logic components from this change.
(4) 3rd Party ISV software is another risk item. that company may shut down due to changing business environment (or get acquired) making support impossible and also trigger a changing licensing terms/prices that in turn will create a demnd to move to another ISV's component or OSS. They may not support the new OSes you want to use. Its equally likely it plays a critical part in your product's competitive advantage and their is a new ISV component which is much better than what you are using, triggering again a MUST-MIGRATE situation to retain the competitive advantage.
(5) Open Source Software can also be subsituted by better OSS which you would like to use or the open source community for that piece of software may shut down, or refuse to develop the component in the direction you want, or simply be bought over & go commercial. It could also happen that as you move to a different OS/CPU environment, this OSS component may not be available to that platform, triggering a substitition in worst case.
(6) This business unit may shut down or down size such that they may not eb able to meet your requirements of enhancement & suppotrt in future. It will leave you the option of either taking over and doing those changes yourself (if you can & have the bandwidfth to do it) or in worst case go for a replacement.
(7) Network and Peers - Their could be cases where the same software-intensive system can interact with multiple peers and on varying types of networks which can upset the application's timer . A tuning facility if provided (even masked under "slow peer" or "slow networks") on a per peer or per network interface basis, can help the product adapt well in the environment. Even if we extend this to any other type of service configuration (ports, behavior, etc), then they can be looked upon as items that aid adaptability (hard-coding in general restricts adaptability). The idea is to have a power-user or advanced configuration hidden from a general user, but available to support staff or tweakers ...
If we extend Murphy's pessimism to change, it will just read "Anything that can change (& need to be adapted) will probably change" or in the worst form"everything will change (need to be adapted)". So take your own call on where and how much you see the risk and implement accordingly.
By no means above is an exhaustive list of things that may require to be adapted or actions that can be taken. But the idea should be clear. If your design & coding is taking care of these type of change patterns, you are designing your software for the "Adaptability" quality attribute. What it does it allows the system to adapt and evolve independently in pieces by keep a componentized architecture withput resorting to necessrily using a component programming framework. Its implementing loose coupling between components. Its an emphirical observation that the more (in places and volume) the software chnages, the more is the risk that defects will be injected. Minimizing this also has a +ive impact of the reliability of future versions facing adapative changes.
No comments:
Post a Comment