educative.io

SOLID Principle

In the example given, I see Invoice as a member variable in InvoicePrinter and InvoiceStorage. Why can we have reference to these class in Invoice? The other way around?


Course: Grokking the Low Level Design Interview Using OOD Principles - Learn Interactively
Lesson: SOLID: Single Responsibility Principle - Grokking the Low Level Design Interview Using OOD Principles

Hi @Prabhat_Mishra !!
The Invoice class is present as a member variable in the InvoicePrinter and InvoiceStorage classes because the InvoicePrinter and InvoiceStorage classes have references to the Invoice class as member variables because they need access to the invoice data in order to perform their respective functionalities.

The InvoicePrinter class needs access to the invoice data to generate and print the invoice. By having a reference to the Invoice class, the InvoicePrinter can access the necessary invoice information, such as the quantity, and total.

Similarly, the InvoiceStorage class needs access to the invoice data to save it into a database or perform any other storage-related operations. Having a reference to the Invoice class allows the InvoiceStorage class to access the invoice properties and persist them appropriately.

While having these references may seem to violate the SRP on the surface, it’s important to note that the purpose of the SRP is to ensure that a class has a single responsibility and a single reason to change. In this case, the responsibilities of the InvoicePrinter and InvoiceStorage classes align with their specific functionalities of printing and storage, respectively. The Invoice class, on the other hand, remains responsible for representing the invoice data.

The goal of adhering to the SRP is to avoid situations where a single class becomes bloated with multiple responsibilities that may change for different reasons. By separating the printing and storage functionalities into separate classes, we achieve better modularity and maintainability.

However, it’s worth noting that in a more ideal design, the InvoicePrinter and InvoiceStorage classes could work with interfaces or abstractions instead of directly referencing the concrete Invoice class. This would further decouple the classes and allow for more flexibility and extensibility.

In summary, while the example shows the Invoice class as a member variable in the InvoicePrinter and InvoiceStorage classes, it’s important to consider the context and ensure that each class has a clear responsibility and a single reason to change.
I hope it helps. Happy Learning :blush: