Let's consider an example where we need to create different sorting algorithms for a list of integers. Without using an abstract class, we might create individual classes for each sorting algorithm:
class BubbleSort:
def sort(self, data):
# Implementation of Bubble Sort
pass
class MergeSort:
def sort(self, data):
# Implementation of Merge Sort
pass
class QuickSort:
def sort(self, data):
# Implementation of Quick Sort
pass
In this approach, each sorting algorithm is defined in a separate class, resulting in code duplication, potential inconsistencies, and a lack of a clear common interface. Suppose we want to use these sorting algorithms in a pipeline. In that case, we would need to handle each class differently, leading to harder-to-maintain code and potential issues when adding new algorithms.
Let's improve the code by using an abstract class to define the common interface for sorting algorithms:
from abc import ABC, abstractmethod
class SortingAlgorithm(ABC):
@abstractmethod
def sort(self, data):
pass
class BubbleSort(SortingAlgorithm):
def sort(self, data):
# Implementation of Bubble Sort
pass
class MergeSort(SortingAlgorithm):
def sort(self, data):
# Implementation of Merge Sort
pass
class QuickSort(SortingAlgorithm):
def sort(self, data):
# Implementation of Quick Sort
pass
Using an abstract class ensures that all sorting algorithms adhere to a common interface, making the codebase more modular, easier to maintain, and scalable when adding new sorting algorithms in the future. It fosters code reuse, promotes consistency, and allows for polymorphic behavior, resulting in a more efficient and maintainable codebase.