The Open/Closed Principle: A Gateway to Flexible Mobile Development

Maxim Gorin
6 min readMay 7, 2024

--

Welcome to the eighth installment of our series on Clean Architecture, where we dive deeper into the core principles shaping robust mobile app development. Following our discussion on the “Single Responsibility Principle: Building Better Mobile Apps with SOLID Foundations”, we now explore another crucial concept: the Open/Closed Principle (OCP). Introduced by Bertrand Meyer, this principle plays a vital role in enabling software systems to be extendable yet remain modification-free in their existing forms.

‘OCP in mobile app development’, generated by DALL-E

In this article, we’ll dissect the OCP to understand how it applies specifically to the mobile development sphere, enhancing our capabilities to build apps that not only meet current demands but are also prepared for future expansion and adaptation. By the end of this exploration, you’ll gain insights into implementing OCP effectively within your projects, ensuring that your mobile applications are both resilient against and adaptable to the ever-evolving landscape of user needs and technological advancements.

Introduction to the Open/Closed Principle (OCP)

The Open/Closed Principle (OCP), first articulated by Bertrand Meyer in 1988, is a fundamental design tenet in software engineering. It dictates that software components should be extendable without necessitating modifications to existing code. This principle is particularly pivotal in fostering software that can evolve over time without compromising existing functionality, which minimizes the introduction of bugs during updates.

Open/Closed Principle in Software Design

In mobile development, the OCP is critical due to the constant need for apps to adapt quickly to new requirements and user feedback without overhauling the established codebase. By embracing the OCP, developers can enhance and expand mobile applications by integrating new modules that work seamlessly with the old ones, rather than altering the original components. This approach not only speeds up the development process but also helps maintain the stability and reliability of the application as it grows. Adhering to the OCP allows for a smoother expansion of features and adjustment to functionalities, ensuring mobile applications are both resilient and agile.

Thought Experiment

Scenario of Changing Requirements

Imagine a scenario where a mobile app currently provides users with the ability to browse and purchase items. As the app evolves, there’s a new requirement: the addition of a feature that allows users to also sell their items, similar to a marketplace. This new functionality requires changes to the user interface, database access, and perhaps even the payment system.

“O” for the Open/Closed Principle — OpenClassrooms

Impact Analysis of Changes

If the app’s architecture isn’t aligned with the Open/Closed Principle (OCP), introducing this new feature could necessitate significant modifications to existing code. For instance, the original app might have a single module handling all user transactions, including both purchases and sales. Without OCP, developers might find themselves altering this module to incorporate selling capabilities, which could introduce bugs in the purchase process that was already working perfectly.

Moreover, every time the app needs an update or a new feature, the developers would have to modify the same modules again and again, increasing the risk of errors each time. This not only makes the development process cumbersome and slow but also affects the overall stability of the app.

On the contrary, if the app were designed following the OCP, it would have distinct modules for handling different aspects of user transactions, with clear interfaces for expanding functionalities without altering existing code. For instance, adding the selling feature could simply involve creating a new module that interacts with the existing transaction system. This modular approach ensures that changes for new requirements have minimal impact on the existing, stable functionalities, thereby reducing the risk of introducing bugs and decreasing the time required for development.

Managing Change Direction with the Open/Closed Principle

O is for Open/Closed Principle

Designing for OCP in Mobile Development

In mobile development, adopting the Open/Closed Principle (OCP) ensures that applications can grow and adapt without the constant need to modify existing code. This principle is crucial in environments where business requirements change frequently and rapidly.

A core strategy for adhering to the OCP is the use of abstraction and polymorphism, which allows behaviors to be extended without altering the code that uses those behaviors. This can be effectively demonstrated through design patterns such as Strategy, Decorator, and Factory, which separate the behavior (what changes) from the client code (what stays the same).

Practical Examples from Mobile Development

Let’s examine two practical examples that highlight the implementation of OCP in mobile development using Swift and Dart. These examples will include both a non-OCP-compliant version and its refactored, OCP-compliant counterpart.

Swift Example: Handling Different Payment Methods

Initially, an iOS app might only support credit card payments. As the app grows, support for new payment types like PayPal or cryptocurrencies might be necessary.

Non-OCP-Compliant Version:

class PaymentProcessor {
func processPayment(amount: Double, method: String) {
if method == "creditCard" {
processCreditCardPayment(amount: amount)
} // Adding a new payment method requires modifying this class
}

private func processCreditCardPayment(amount: Double) {
// Process credit card payment
}
}

OCP-Compliant Refactoring:

protocol PaymentMethod {
func processPayment(amount: Double)
}

class CreditCardPayment: PaymentMethod {
func processPayment(amount: Double) {
// Process credit card payment
}
}

class PayPalPayment: PaymentMethod {
func processPayment(amount: Double) {
// Process PayPal payment
}
}

class PaymentProcessor {
func processPayment(amount: Double, method: PaymentMethod) {
method.processPayment(amount: amount)
}
}

Dart Example: Displaying Different Page Types

A Flutter app may need to display different types of content pages, such as text or image pages.

Non-OCP-Compliant Version:

class ContentPage {
String type;

Widget buildPage() {
if (type == 'text') {
return Text("Text Content");
} else if (type == 'image') {
return Image.asset("path/to/image.png");
} // Adding a new page type requires adding more conditions here
}
}

OCP-Compliant Refactoring:

abstract class ContentPage {
Widget buildPage();
}

class TextPage implements ContentPage {
@override
Widget buildPage() => Text("Text Content");
}

class ImagePage implements ContentPage {
@override
Widget buildPage() => Image.asset("path/to/image.png");
}

class ContentFactory {
static ContentPage getPage(String contentType) {
switch (contentType) {
case 'text':
return TextPage();
case 'image':
return ImagePage();
default:
throw Exception('Content type not supported');
}
}
}

These examples demonstrate how mobile applications can be designed to incorporate changes smoothly, without necessitating alterations to existing code, thus adhering to the Open/Closed Principle. By applying such design principles, mobile apps become more modular, easier to maintain, and quicker to adapt to new requirements or technologies.

Conclusion

In this exploration of the Open/Closed Principle (OCP), we’ve delved into how its disciplined application can significantly enhance the adaptability and scalability of mobile applications in a technology landscape that is perpetually evolving. As we have seen, adhering to OCP not only facilitates the integration of new functionalities without disrupting existing code but also shields applications from potential instabilities that can arise from frequent modifications.

The practical benefits of implementing OCP are manifold. By designing mobile apps that are open to extension but closed to modification, developers can significantly reduce the cost and effort associated with maintaining and upgrading their software. This approach minimizes the risk of introducing defects during updates, thus maintaining a high standard of quality and ensuring a superior user experience. Furthermore, OCP-compliant systems are inherently more modular, which simplifies understanding and enhances the collaborative capabilities within development teams.

As the mobile technology domain continues to advance rapidly, the importance of a principle like OCP becomes even more pronounced. It empowers mobile applications to stay competitive and responsive, swiftly adapting to new market demands and user preferences without necessitating complete overhauls of their foundational code.

We encourage you to integrate the Open/Closed Principle into your development practices, witnessing firsthand how it can transform the lifecycle of your mobile applications. Share your experiences and insights in the comments below, and join the discussion to help cultivate a community rich in knowledge and innovation. If you’ve found this article beneficial, consider sharing it with your peers and subscribe for more insightful discussions as we continue to uncover the remaining SOLID principles in upcoming articles. Together, let’s keep pushing the boundaries of what’s possible in software development!

--

--

Maxim Gorin
Maxim Gorin

Written by Maxim Gorin

Team lead in mobile development with a passion for Fintech and Flutter. Sharing insights and stories from the tech and dev world on this blog.

No responses yet