The rest of this chapter provides you with a set of tools to use when you go searching for and identifying areas of volatility. While these techniques are valuable and effective in their own right, they are somewhat loose. The next chapter introduces structure and constraints that allow for quicker and repeatable identification of areas of volatility. However, that discussion merely fine-tunes and specializes the ideas in this section.
Volatile Versus Variable
A key question many novices struggle with is the difference between things that change and things that are volatile. Not everything that is variable is also volatile. You resort to encapsulating a volatility at the system design level only when it is open-ended and, unless encapsulated in a component of the architecture, would be very expensive to contain. Variability, on the other hand, describes those aspects that you can easily handle in your code using conditional logic. When searching for volatility, you should be on the lookout for the kind of changes or risks that would have ripple effects across the system. Changes must not invalidate the architecture.
Axes Of Volatility
Finding areas of volatility is a process of discovery that takes place during requirements analysis and interviews with the project stakeholders.
There is a simple technique I call axes of volatility. This technique examines the ways the system is used by customers. Customer in this context refers to a consumer of the system, which could be a single user or a whole other business entity.
In any business, there are only two ways your system could face change: the first axis is at the same customer over time. Even if presently the system is perfectly aligned with a particular customer’s needs, over time, that customer’s business context will change. Even the use of the system by the customer will often change the requirements against which it was written in the first place.3 Over time, the customer’s requirements and expectation of the system will change.
3. The tendency of a solution to change the requirements against which it was developed was first observed by the 19th-century English economist William Jevons with regard to coal production, and it is referred to since as the Jevons paradox. Other manifestations are the increase in paper consumption with the digital office and the worsening traffic congestion following an increase in road capacity.
The second way change could come is at the same time across customers. If you could freeze time and examine your customer base, are all your customers now using the system in exactly the same way? What are some of them doing that is different from the others? Do you have to accommodate such differences? All such changes define the second axis of volatility.
When searching for potential volatility in interviews, you will find it very helpful to phrase the questions in terms of the axes of volatility (same customer over time, all customers at the same point in time). Framing the questions in this way helps you identify the volatilities. If something does not map to the axes of volatility, you should not encapsulate it at all, and there should be no building block in your system to which it is mapped. Creating such a block would likely indicate functional decomposition.
Often, the act of looking for areas of volatility using the axes of volatility is an iterative process interleaved with the factoring of the design itself. Consider, for example, the progression of design iterations in Figure 2-10.
FIGURE 2-10 Design iterations along axes of volatility
Your first take of the proposed architecture might look like diagram A—one big thing, one single component. Ask yourself, Could you use the same component, as is, with a particular customer, forever? If the answer is no, then why? Often, it is because you know that customer will, over time, want to change a specific thing. In that case, you must encapsulate that thing, yielding diagram B. Ask yourself now, Could you use diagram B across all customers now? If the answer is no, then identify the thing that the customers want to do differently, encapsulate it, and produce diagram C. You keep factoring the design that way until all possible points on the axes of volatility are encapsulated.
Independence of the Axes
Almost always, the axes should be independent. Something that changes for one customer over time should not change as much across all customers at the same point in time, and vice versa. If areas of change cannot be isolated to one of the axes, it often indicates a functional decomposition in disguise.
Example: Volatility-Based Decomposition of a House
You can use the axes of volatility to encapsulate the volatility of a house. Start by looking at your own house and observe how it changes over time. For example, consider furniture. Over time, you may rearrange the furniture in the living room and occasionally add new pieces or replace old ones. The conclusion is that furniture in a house is volatile. Next consider appliances. Over time, you may switch to energy-efficient appliances. You likely have already replaced the old CRT with flat plasma screen and that with a large, wafer-thin OLED TV. This is a strong indication that at your house, appliances are volatile. How about the occupants of the house? Is that aspect static? Do you ever have guests come over? Can the house be empty of people? The occupants of the house are volatile. What about appearance? Do you ever paint the house, change the draperies or landscaping? The appearance of a house is volatile. The house is likely connected to some utilities, from Internet to power and security. Previously, I pointed out the power volatility in a house, but what about Internet? In years past, you may have used dial-up for Internet, then moved to DSL, then cable, and now fiber optics or a satellite connection. While these options are drastically different, you would not want to change the way you send emails based on the type of connectivity. You should encapsulate the volatilities of all utilities. Figure 2-11 shows this possible decomposition along the first axis of volatility (same customer over time).
FIGURE 2-11 Same house over time
Now, even at the same point in time, is your house the same as every other house? Other houses have a different structure, so the structure of the house is volatile. Even if you were to copy and paste your house to another city, would it be the same house?4 The answer is clearly negative. The house will have different neighbors and be subjected to different city regulations, building codes, and taxes. Figure 2-12 shows this possible decomposition along the second axis of volatility (different customers at the same point in time).
FIGURE 2-12 At the same time across houses
Note the independence of the axis. The city where you live over time does change its regulations, but the changes come at a slow pace. Similarly, the likelihood of new neighbors is fairly low as long as you live in the same house but is a certainty if you compare your house to another at the same point in time. The assignment of a volatility to one of the axes is therefore not an absolute exclusion but more one of disproportional probability.
Note also that the Neighbors Volatility component can deal with volatility of neighbors at the same house over time as easily as it can do that across different houses at the same point in time. Assigning the component to an axis helps to discover the volatility in the first place; the volatility is just more apparent across different houses at the same point in time.
Finally, in sharp contrast to the decompositions of Figure 2-6 and Figure 2-7, in Figure 2-11 and Figure 2-12 there is no component in the decomposition for cooking or kitchen. In a volatility-based decomposition, the required behavior is accomplished by an interaction between the various encapsulated areas of volatility. Cooking dinner may be the product of an interaction between the occupants, the appliances, the structure, and the utilities. Since something still needs to manage that interaction, the design is not complete. The axes of volatility are a great starting point, but it is not the only tool to bring to bear on the problem.
Solutions Masquerading As Requirements
Consider again the functional requirement for the house to support the cooking feature. Such requirements are quite common in requirements specs, and many developers will simply map that to a Cooking component in their architecture. Cooking, however, is not a requirement (even though it was in the requirement spec). Cooking is a possible solution for the requirement of feeding the people in the house. You can satisfy the feeding requirement by ordering pizza or taking the family out for dinner.
It is exceedingly common for customers to provide solutions masquerading as requirements. With functional decomposition, once you deploy the system with only Cooking, the customer will ask for the pizza option, resulting in either another component in your system or bloating of another component. The “going out to dinner” requirement will soon follow, leading to a never-ending cycle of features going around and around the real requirement. With volatility-based decomposition, during requirements analysis, you should identify the volatility in feeding the occupants and provide for it. The volatility of feeding is encapsulated within the Feeding, component and as the feeding options change, your design does not.
However, while feeding is a better requirement than cooking, it is still a solution masquerading as a requirement. What if in the interest of diet, the people in the house should go to bed hungry tonight? A feeding requirement and diet requirement might be mutually exclusive. You can do either one, but not both. Mutually exclusive requirements are also quite common.
The real requirement for any house is to take care of the well-being of the occupants, not just their caloric intake. The house should not be too cold or too warm or too humid or too dry. While the customers may only discuss cooking and never discuss temperature control, you should recognize the real volatility, well-being, and encapsulate that in the Wellbeing component of your architecture.
Since most requirements specifications are chock-full of solutions masquerading as requirements, functional decomposition absolutely maximizes your pain. You will forever be chasing the ever-evolving solutions, never recognizing the true underlying requirements.
The fact that requirements specifications have all those solutions masquerading as requirements is actually a blessing in disguise because you can generalize the example of cooking in the house into a bona fide analysis technique for discovering areas of volatility. Start by pointing out the solutions masquerading as requirements, and ask if there are other possible solutions? If so, then what were the real requirements and the underlying volatility? Once you identify the volatility, you must determine if the need to address that volatility is a true requirement or is still a solution masquerading as a requirement. Once you have finished scrubbing away all the solutions, what you are left with are likely great candidates for volatility-based decomposition.
Prior to decomposing a system and creating an architecture, you should simply compile a list of the candidate areas of volatility as a natural part of requirements gathering and analysis. You should approach the list with an open mind. Ask what could change along the axes of volatility. Identify solutions masquerading as requirements, and apply the additional techniques described later in this chapter. The list is a powerful instrument for keeping track of your observations and organizing your thoughts. Do not commit yet to the actual design. All you are doing is maintaining a list. Note that while the design of the system should not take more than a few days, identifying the correct areas of volatility may take considerably longer.
Example: Volatility-Based Trading System
Using the previous requirements for the stock trading system, you should start by preparing a list of possible areas of volatility, capturing also the rationale behind each:
User volatility. The traders serve end customers on whose portfolios they operate. The end customers are also likely interested in the current state of their funds. While they could write the trader a letter or call, a more appropriate means would be for the end customers to log into the system to see the current balance and the ongoing trades. Even though the requirements never stated anything about end customer access (the requirements were for professional traders), you should contemplate such access. While the end customers may not be able to trade, they should be able to see the status of their accounts. There could also be system administrators. There is volatility in the type of user.
Client application volatility. Volatility in users often manifests in volatility in the type of client application and technology. A simple web page may suffice for external end customers looking up their balance. However, professional traders will prefer a multi-monitor, rich desktop application with market trends, account details, market tickers, newsfeed, spreadsheet projection, and proprietary data. Other users may want to review the trades on mobile devices of various types.
Security volatility. Volatility in users implies volatility in how the users authenticate themselves against the system. The number of in-house traders could be small, from a few dozens to a few hundred. The system, however, could have millions of end customers. The in-house traders could rely on domain accounts for authentication, but this is a poor choice for the millions of customers accessing information through the Internet. For Internet users, perhaps a simple user name and password will do, or maybe some sophisticated federated security single sign-on option is needed. Similar volatility exists with authorization options. Security is volatile.
Notification volatility. The requirements specify that the system is to send an email after every request. However, what if the email bounces? Should the system fall back to a paper letter? How about a text message or a fax instead of an email? The requirement to send an email is a solution masquerading as a requirement. The real requirement is to notify the users, but the notification transport is volatile. There is also volatility in who receives the notification: a single user or a broadcast to several users receiving the same notification and over whichever transport. Perhaps the end customer prefers an email while the end customer’s tax lawyer prefers a documented paper statement. There is also volatility in who publishes the notification in the first place.
Storage volatility. The requirements specify the use of a local database. However, over time, more and more systems migrate to the cloud. There is nothing inherent in stock trading that precludes benefiting from the cost and economy of scale of the cloud. The requirement to use a local database is actually another solution masquerading as a requirement. A better requirement is data persistence, which accommodates the volatility in the persistence options. However, the majority of users are end customers, and those users actually perform read-only requests. This implies the system will benefit greatly from the use of an in-memory cache. Furthermore, some cloud offerings utilize a distributed in-memory hash table that offers the same resiliency as traditional file-based durable storage. Requiring data persistence would exclude these last two options because data persistence is still a solution masquerading as a requirement. The real requirement is simply that the system must not lose the data, or that the system is required to store the data. How that is accomplished is an implementation detail, with a great deal of volatility, from a local database to a remote in-memory cache in the cloud.
Connection and synchronization volatility. The current requirements call for a connected, synchronous, lock-step manner of completing a web form and submitting it in-order. This implies that the traders can do only one request at a time. However, the more trades the traders execute, the more money they make. If the requests are independent, why not issue them asynchronously? If the requests are deferred in time (trades in the future), why not queue up the calls to the system to reduce the load? When performing asynchronous calls (including queued calls), the requests can execute out of order. Connectivity and synchronicity are volatile.
Duration and device volatility. Some users will complete a trade in one short session. However, traders earn their keep and maximize their income when they perform complicated trades that distribute and hedge risk, involving multiple stocks and sectors, domestic or foreign markets, and so on. Constructing such a trade can be time-consuming, lasting anywhere from several hours to several days. Such a long-running interaction will likely span multiple system sessions and possibly multiple physical devices. There is volatility in the duration of the interaction, which in turn triggers volatility in the devices and connections involved.
Trade item volatility. As discussed previously, over time, the end customers may want to trade not just stocks but also commodities, bonds, currencies, and maybe even future contracts. The trade item itself is volatile.
Workflow volatility. If the trade item is volatile, processing of the steps involved in the trade will be volatile too. Buying and selling stocks, scheduling their orders, and so on are very different from selling commodities, bonds, or currencies. The workflow of the trade is therefore volatile. Similarly, the workflow of trade analysis is volatile.
Locale and regulations volatility. Over time, the system may be deployed into different locales. Volatility in the locale has drastic implications on the trading rules, UI localization, the listing of trade items, taxation, and regulatory compliance. The locale and the regulations that apply therein are volatile.
Market feed volatility. The source of market data could change over time. Various feeds have a different format, cost, update rate, communication protocols, and so on. Different feeds may show slightly different value for the same stock at the same point in time. The feeds can be external (e.g., Bloomberg or Reuters) or internal (e.g., simulated market data for testing, diagnostics, or trading algorithms research). The market feed is volatile.
A Key Observation
The preceding list is by no means an exhaustive list of all the things that could change in a stock trading system. Its objective is to point out what could change and the mindset you need to adopt when searching for volatility. Some of the volatile areas may be out of scope for the project. They may be ruled out by domain experts as improbable or may relate too much to the nature of the business (such as branching out of stocks into currencies or foreign markets). My experience, however, is that it is vital to call out the areas of volatility and map them in your decomposition as early as possible. Designating a component in the architecture costs you next to nothing. Later, you must decide whether or not to allocate the effort to designing and constructing it. However, at least now you are aware how to handle that eventuality.
Once you have settled on the areas of volatility, you need to encapsulate them in components of the architecture. One such possible decomposition is depicted in Figure 2-13.
FIGURE 2-13 Volatility-based decomposition of a trading system
The transition from the list of volatile areas to components of the architecture is hardly ever one to one. Sometimes a single component can encapsulate more than one area of volatility. Some areas of volatility may not be mapped directly to a component but rather to an operational concept such as queuing or publishing an event. At other times, the volatility of an area may be encapsulated in a third-party service.
With design, always start with the simple and easy decisions. Those decisions constrain the system, making subsequent decisions easier. In this example, some mapping is easy to do. The volatility in the data storage is encapsulated behind data access components, which do not betray where the storage is and what technology is used to access it. Note in Figure 2-13 the key abstraction of referring to the storage as Storage and not as Database. While the implementation (according to the requirements) is a local database, there is nothing in the architecture that precludes other options, such as the raw file system, a cache, or the cloud. If a change to the storage takes place, it is encapsulated in the respective access component (such as the Trades Access) and does not affect the other components, including any other access component. This enables you to change the storage with minimal consequences.
The volatility in notifying the clients is encapsulated in the Notification component. This component knows how to notify each client and which clients subscribe to which event. For simple scenarios, you can manage sufficiently with a general-purpose events publishing and subscription service (Pub/Sub) instead of a custom Notification component. However, in this case, there are likely some business rules on the type of transport and nature of the broadcast. The Notification component may still use some Pub/Sub service underneath it, but that is an internal implementation detail whose volatility is also encapsulated in the Notification component.
The volatility in the trading workflow is encapsulated in the Trade Workflow component. That component encapsulates the volatility of what is being traded (stocks or currencies), the specific steps involved in buying or selling a trade item, the required customization for local markets, the details for the required reports, and so on. Note that even if the trade items are fixed (not volatile), the workflow of trading stocks can change, justifying the use of Trade Workflow to encapsulate the volatility. The design also relies on the operational concept of storing the workflows (this should be implemented using some third-party workflow tool). Trade Workflow retrieves the appropriate workflow instance for each session, operates on it, and stores it back in the Workflow Storage. This concept helps encapsulate several volatilities. First, different trade items can now have distinct trading workflows. Second, different locales can have different workflows. Third, this enables supporting long-running workflows spanning multiple devices and sessions. The system does not care if two calls are seconds apart or days apart. In each case, the system loads the workflow instance to process the next step. The design treats connected, single-session trades exactly the same as a long-running distributed trade. Symmetry and consistency are good qualities in system architecture. Note also that the workflow storage access is encapsulated in the same fashion as the trades storage access.
You can use the same pattern for the stock trading workflow and the analysis workflows. The dedicated Analysis Workflow component encapsulated the volatility in the analysis workflows, and it can use the same Workflow Storage.
The volatility of accessing the market feed is encapsulated in the Feed Access. This component encapsulates how to access the feed and whether the feed itself is internal or external. The volatility in the format or even value of the various market data coming from the different feeds is encapsulated in the Feed Transformation component. Both of these components decouple the other components from the feeds by providing a uniform interface and format regardless of the origin of the data.
The Security component encapsulates the volatility of the possible ways of authenticating and authorizing the users. Internally, it may look up credentials from a local storage or interact with some distributed provider.
The clients of the system can be the trading application (Trader App A) or a mobile app (Trader App B). The end customers can use their own website (Customer Portal). Each client application also encapsulates the details and the best way of rendering the information on the target device.
Resist The Siren Song
Note in Figure 2-13 the absence of a dedicated reporting component. For demonstration purposes, reporting was not listed as a volatile area (from the business perspective). Therefore, there is nothing to encapsulate with a component. Adding such a component manifests functional decomposition. However, if functional decomposition is all you have ever done, you will likely hear an irresistible siren song calling you to add a reporting block. Just because you always have had a reporting block, or even because you have an existing reporting block, does not mean you need a reporting block.
In Homer’s Odyssey, a story that is more than 2500 years old, Odysseus sails home via the Straights of the Sirens. The Sirens are beautiful winged fairy-like creatures who have the voices of angels. They sing a song that no man can resist. The sailors jump to their arms, and the Sirens drown the men under the waves and eat them. Before encountering the deadly allure of the Sirens’ songs, Odysseus (you, the architect) is advised to plug with beeswax the ears of his sailors (the rank and file software developers) and tie them to the oars. The sailors’ job is to row (write code), and they are not even at liberty to listen to the Sirens. Odysseus himself, on the other hand, as the leader, does not have the luxury of plugging his ears (e.g., maybe you do need that reporting block). Odysseus ties himself to the mast of the ship so that he cannot succumb to the Sirens even if he wanted to do so (see Figure 2-14, depicting the scene on a period vase). You are Odysseus, and volatility-based decomposition is your mast. Resist the siren song of your previous bad habits.
FIGURE 2-14 Tied to the mast (Image: Werner Forman Archive/Shutterstock)
Volatility And The Business
While you must encapsulate the volatile areas, not everything that could change should be encapsulated. Put differently, things that could change are not necessarily volatile. A classic example is the nature of the business, and you should not attempt to encapsulate the nature of the business. With almost all business applications, the applications exist to serve some need of the business or its customers. However, the nature of the business, and by extension, each application, tends to be fairly constant. A company that has been in a business for a long time will likely stay in that business. For example, Federal Express has been, is, and will be in the shipment and delivery business. While in theory it is possible for Federal Express to branch into healthcare, such a potential change is not something you should encapsulate.
During system decomposition, you must identify both the areas of volatility to encapsulate and those not to encapsulate (e.g., the nature of the business). Sometimes, you will have initial difficulty in telling these apart. There are two simple indicators if something that could change is indeed part of the nature of the business. The first indicator is that the possible change is rare. Yes, it could happen, but the likelihood of it happening is very low. The second indicator is that any attempt to encapsulate the change can only be done poorly. No practical amount of investment in time or effort will properly encapsulate the aspect in a way of which you can be proud.
For example, consider designing a simple residential house on a plot of land. At some point in the future, the homeowner may decide to extend the home into a 50-story skyscraper. Encapsulating that possible change in your house design produces a very different design than that of your typical residential house design. Instead of a shallow form-poured foundation, the house foundation must include dozens of friction pylons, driven down to maybe hundreds of feet to support the weight of the building. This will allow the foundation to support both a single family residential and a skyscraper. Next, the power panel must be able to distribute thousands of amps and likely requires the house to have its own transformer. While the water company can bring water to the house, you must devote a room for a large water pump that can push the water up 50 floors. The sewer line must be able to handle 50 floors of inhabitants. You will have to do all that tremendous investment for a single-family home.
When you are finished, the foundation will encapsulate the change to the weight of the building, the power panel will encapsulate the demands of both a single home and 50 stories, and so on. However, the two indicators are now violated. First, how many homeowners in your city annually do convert their home to a skyscraper? How common is that? In a large metropolitan area with a million homes, it may happen once every few years, making the change very rare, once in a million if that. Second, do you really have the funds (allocated initially for a single home) to properly execute all these encapsulations? A single pylon may cost more than the single-family building. Any attempt to encapsulate the future transition to a skyscraper will be done poorly and will be neither useful nor cost-effective.
Converting the single-family home to a 50-story building is a change to the nature of the business. No longer is the building in the business of housing a family. Now it is in the business of being a hotel or an office building. When a land developer purchases that plot of land for the purpose of such conversion, the developer usually chooses to raze the building, dig out the old foundation, and start afresh. A change to the nature of the business permits you to kill the old system and start from scratch. It is important to note that the context of the nature of the business is somewhat fractal. The context can be the business of the company, the business of a department or a division in a company, or even the business added value of a specific application. All these represent things that you should not encapsulate.
Speculative design is a variation on trying to encapsulate the nature of the business. Once you subscribe to the principle of volatility-based decomposition, you will start seeing possible volatilities everywhere and can easily overdo it. When taken to the extreme, you run the risk of trying to encapsulate anything and everywhere. Your design will have numerous building blocks, a clear sign of a bad design.
Consider for example the item in Figure 2-15.
FIGURE 2-15 Speculative design (Image: Gercen/Shutterstock)
The item is a pair of SCUBA-ready lady’s high heels. While a lady adorned in a fine evening gown could entertain her guests at the party wearing these, how likely is it that she will excuse herself, proceed immediately to the porch, draw on SCUBA gear, and dive into the reef? Are these shoes as elegant as conventional high heels? Are these as effective as regular flippers when it comes to swimming or stepping on sharp coral? While the use of the items in Figure 2-15 is possible, it is extremely unlikely. In addition, everything they try to provide is done very poorly because of the attempt to encapsulate a change to the nature of the shoe, from a fashion accessory to a diving accessory, something you should never attempt. If you try this, you have fallen into the speculative design trap. Most such designs are simply frivolous speculation on a future change to your system (i.e., a change to the nature of the business).
Design For Your Competitors
Another useful technique for identifying volatilities is to try to design a system for your competitor (or another division in your company). For example, suppose you are the lead architect for Federal Express’s next-generation system. Your main competitor is UPS. Both Federal Express and UPS ship packages. Both collect funds, schedule pickup and delivery, track packages, insure content, and manage trucks and airplane fleets. Ask yourself the following question: Can Federal Express use the software system UPS is using? Can UPS use the system Federal Express wants to build? If the likely answer is no, start listing all the barriers for such a reuse or extensibility. While both companies perform in the abstract the same service, the way they conduct their business is different. For example, Federal Express may plan shipment routes one way, while UPS may plan them another. In that case, shipment planning is probably volatile because if there are two ways of doing something, there may be many more. You must encapsulate the shipment planning and designate a component in your architecture for that purpose. If Federal Express starts planning shipments the same as UPS at some future time, the change is now contained in a single component, making the change easy and affecting only the implementation of that component, not the decomposition. You have future-proofed your system.
The opposite case is also true. If you and your competitor (and even better, all competitors) do some activity or sequence the same way, and there is no chance of your system doing it any other way, then there is no need to allocate a component in the architecture for that activity. To do so would create a functional decomposition. When you encounter something your competitors do identically, more likely than not, it represents the nature of the business, and as discussed previously, you should not encapsulate it.
Volatility And Longevity
Volatility is intimately related to longevity. The longer the company or the application has been doing something the same way, the higher the likelihood the company will keep doing it the same way. Put differently, the longer things do not change, the longer they have until they do change or are replaced. You must put forward a design that accommodates such changes, even if at first glance such changes are independent of the current requirements.
You can even guesstimate how long it will be until such a change is likely to take place using a simple heuristic: the ability of the organization (or the customer or the market) to instigate or absorb a change is more or less constant because it is tied to the nature of the business. For example, a hospital IT department is more conservative and has less tolerance for change than a nascent blockchain startup. Thus, the more frequently things change, the more likely they will change in the future, but at the same rate. For example, if every 2 years the company changes its payroll system, it is likely the company will change the payroll system within the next 2 years. If the system you design needs to interface with the payroll system and the horizon for using your system is longer than 2 years, then you must encapsulate the volatility in the payroll system and plan to contain the expected change. You must take into account the effect of a payroll system change even if the change was never given to you as an explicit requirement. You should strive to encapsulate changes that occur within the life of the system. If that projected lifespan is 5 to 7 years, a good starting point is identifying all the things that have changed in the application domain over the past 7 years. It is likely similar changes will occur within a similar timespan.
You should examine this way the longevity of all involved systems and subsystems with which your design interacts. For example, if the enterprise resource planning (ERP) system changes every 10 years, the last ERP change was 8 years ago, and the horizon for your new system is 5 years, then it is a good bet the ERP will change during the life of your system.
The Importance Of Practicing
If you only spend 2% of the time on anything, you will never be any good at it, regardless of your built-in intellect or methodology used. An amazing level of hubris is required to believe that once every few years someone can approach a whiteboard, draw a few lines, and nail the architecture. The basic expectation of professionals, be they doctors, pilots, welders or lawyers, is that they master their craft by training for it. You would not wish to be the passenger aboard a plane where the pilot has only a handful of flying hours. You would not wish to be the first patient of a doctor. Commercial airline pilots spend years (plural) in simulators and are trained through hundreds of flights by veteran pilots. Doctors dissect countless cadavers before they can touch the first patient, and even then, they are closely supervised.
Identifying areas of volatility is an acquired skill. Hardly any software architect is initially trained in volatility-based decomposition, and the vast majority of systems and projects use functional decomposition (with abysmal results). The best way of going about mastering volatility-based decomposition is to practice. This is the only way to address the 2% problem. Here are several ways you can start:
Practice on an everyday software system with which you are familiar, such as your typical insurance company, a mobile app, a bank, or an online store.
Examine your own past projects. In hindsight, you already know what the pain points were. Was that architecture of that past project done functionally? What things did change? What were the ripple effects of those changes? If you had encapsulated that volatility, would you have been able to deal with that change better?
Look at your current project. It may not be too late to save it: Is it designed functionally? Can you list the areas of volatility and propose a superior architecture?
Look at non-software systems such as a bicycle, a laptop, a house, and identify in those the areas of volatility.
Then do it again and do it some more. Practice and practice. After you have analyzed three to five systems, you should get the general technique. Sadly, learning to identify areas of volatility is not something you get to master by watching others. You cannot learn to ride a bicycle from a book. You have to mount a bicycle (and fall) a few times. The same is true with volatility-based decomposition. It is, however, preferable to fall during practice than to experiment on live subjects.