Are you experiencing these Design issues?
- Your application code is so rigid to accommodate new changes! making it difficult to modify the system as a whole
- If you make changes to one part of the system it can have unexpected and far-reaching consequences in other parts of the system!
- You are unable to write Unit tests or if you can but those are not enough to cover the complete component functionality!
- You are not able to reuse the common code base across your code base due to tight coupling!
If you are facing all or any such issues in your day-to-day life then this is
the right place to find the solution to your problem. Lack of modularity
and loose-coupling can lead to software that is difficult to understand,
maintain, and extend, and can limit its potential for reuse and
scalability.
An answer is: Component-Based Software Design
Breaking down the Software system into smaller, independent components and
designing the individual components as part of your software design helps to
ensure that your system is modular, flexible, and maintainable.
By designing a software system as a collection of loosely-coupled components,
software developers can more easily manage complexity, improve
maintainability, and support scalability and reusability.
Overall, effective component design is a key aspect of creating a successful
and robust software architecture.
Component Could Be
- Just a single class
- A Class Library
- A Package or DLL
- Executable or Plug-in
- Microservices
Component Should Be/Have
- A well-defined input and output interfaces
- It should be modular and flexible
- It should be loosely coupled with other components
- Can be developed, tested, and maintained independently
Let's design a simple Component
Typically, it is recommended to devote sufficient time to design the
individual components of a software system, so that we have a clear picture of
its internal construct and how it can be easily integrated with other
components.
In this exercise, you will see how to design a File Watcher Component, please
note the following before you start the design
- First, you should identify the interface(s) that it provides to the client to operate it with the desired configuration.
- Then, you will identify the dependencies that are required by the component to perform its tasks, in this case, it would need PeriodicTimer and File classes for asynchronously reading the file's last modified date and time after a configurable interval.
Then using the UML you can draw a diagram similar to the one given below.
- FileWatcher: It uses the PeriodicTimer class to repeatedly read file properties and raise the event if a change is detected
- FileSysRepo: It uses the underlying File system for IO operation.
- IFileWatcher: An interface provided for the client to use this component
- IFilesysRepo: An interface required by IFileWatcher to interact with the underlying system. This interface would allow you to implement the File IO operation for various other sources i.e. Cloud storage services, FTP, etc.
Use
Let's create a small console app to demonstrate how you can use this
component.
Key Notes
- The software system should be broken down into smaller, independent components that can be developed and maintained separately
- The component should have well-defined responsibilities/purposes and interfaces
- It is recommended to devote sufficient time to design the individual components to have a clear picture of how your component with interact with other components
- In the next blog post, I will show how to write the automated test for your component along with some unit test tips and tricks
Comments