How Special Cases make Software Development harder?

How Special Cases make Software Development harder?

What is a Special Case?

In Software Development, we can refer a Special Case as a unique situation in our process that makes us modify our codes or general process just to cover it even though it might overall represent a tiny portion of the codebase. This term is often referred as Edge Case. However, the latter is different as explained below. Special cases don't necessarily involve values at extreme ends.

Edge Case - occurs at extreme ends, minimum or maximum.

Corner Case - usually a mix of parameters operating at extreme levels.

When we develop an application, we usually code generic classes and methods to encapsulate most of the processes and business logic.

Example

For example, let's say in a CRUD application, we have models that are mapped to database schema. We can therefore use a model to have a database operation. If we want to add a new record, we can use a generic method such as AddModel. Same for the remaining operations.

Most modern backend or full stack frameworks comes with in built mappers called Object Relational Mappers (ORM). We can directly use these tools to perform CRUD operations.

An example of a special case is to cater for a feature enabling searching data in a specific table by multiple attributes through natural language whenever applicable. By default, we only have a generic getEntity(model, attributes_values), which takes the model and search by the attributes we pass on. Now we need to modify or extend this functionality so that we can search by natural language. There are plenty of ways of achieving such goal; but the main idea is this special case drastically increases our codebase complexity.

This should not be a surprise though as Modern Applications nowadays require a lot of complexity.

Recent Scenario:

2 Phones
Photo by Hardik Sharma / Unsplash

Coming back to the Mobile Automation project I'm working on, I'm trying to add the iOS tests in the same codebase as the Android one. I only need a way to differentiate them and run them independently. However, the elements path are distinct.

So I code a class and its methods that determines whether to retrieve the path for Android or iOS. For each element, I have one path value stored in a spreadsheet.

Example

So far, everything works well. The structure for iOS sometimes differ. But relatively straight forward to adapt.

Other times though, to get an element without a proper path value, even in Android, becomes a hassle. You might have to check the parent value. So my design breaks because I only cater for one element's value. Now I need another one.

My method that determines how to return the MobileElement value suddenly increases tenfold in complexity. Not only do I need to manage this logic, but also refactor existing cases so that they don't break.

Quick solution

Without going into depth, I'm going to simply replace the element path wherever possible and write separate codes just to tackle the additional logic. This represents more work, especially in making sure the new case works while the previous existing ones are still good.


References

https://softwareengineering.stackexchange.com/questions/125587/what-are-the-difference-between-an-edge-case-a-corner-case-a-base-case-and-a-b