Abstraction
Key aspects of abstraction include:
- Simplification: Abstraction reduces complexity by hiding unnecessary details.
- Focusing on essential features: It emphasises what an object does rather than how it does it.
- Separation of concerns: It allows separating the interface of a class from its implementation.
- Modularity: Abstraction promotes modular design by defining clear boundaries between components.
Abstract classes and interfaces
In many object-oriented languages, abstraction is implemented through abstract classes and interfaces. While Python doesn’t have a built-in interface concept, we can achieve similar functionality using abstract base classes. Python’s abc
module provides infrastructure for defining abstract base classes:
from abc import ABC, abstractmethod
class Shape(ABC):
@abstractmethod
def area(self):
pass
@abstractmethod
def perimeter(self):
pass
class Rectangle(Shape):
def __init__(self, width, height):
self.width = width
self.height = height
def area(self):
return self.width * self.height
def perimeter(self):
return 2 * (self.width + self.height)
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def area(self):
return 3.14159 * self.radius ** 2
def perimeter(self):
return 2 * 3.14159 * self.radius
# Usage
# shapes = [Shape()] # This would raise TypeError
shapes = [Rectangle(5, 4), Circle(3)]
for shape in shapes:
print(f"Area: {shape.area()}, Perimeter: {shape.perimeter()}")
# Output:
# Area: 20, Perimeter: 18
# Area: 28.27431, Perimeter: 18.84954
In this example:
Shape
is an abstract base class that defines the interface for all shapes.Rectangle
andCircle
are concrete classes that implement theShape
interface.- We can’t instantiate
Shape
directly, but we can use it as a common type for all shapes.
Implementing abstraction in Python
While abstract base classes provide a formal way to define interfaces in Python, abstraction can also be achieved through convention and documentation. Here’s an example of abstraction without using ABC
:
class Database:
def connect(self):
raise NotImplementedError("Subclass must implement abstract method")
def execute(self, query):
raise NotImplementedError("Subclass must implement abstract method")
class MySQLDatabase(Database):
def connect(self):
print("Connecting to MySQL database...")
def execute(self, query):
print(f"Executing MySQL query: {query}")
class PostgreSQLDatabase(Database):
def connect(self):
print("Connecting to PostgreSQL database...")
def execute(self, query):
print(f"Executing PostgreSQL query: {query}")
def perform_database_operation(database):
database.connect()
database.execute("SELECT * FROM users")
# Usage
mysql_db = MySQLDatabase()
postgres_db = PostgreSQLDatabase()
perform_database_operation(mysql_db)
perform_database_operation(postgres_db)
# Output:
# Connecting to MySQL database...
# Executing MySQL query: SELECT * FROM users
# Connecting to PostgreSQL database...
# Executing PostgreSQL query: SELECT * FROM users
In this example:
Database
is an abstract base class (though not usingABC
) that defines the interface for all database types.MySQLDatabase
andPostgreSQLDatabase
are concrete implementations.perform_database_operation
works with any object that adheres to theDatabase
interface.
Design principles and patterns
Abstraction is a key component of several important design principles and patterns:
SOLID Principles:
- Single Responsibility Principle (SRP).
- Open/Closed Principle (OCP).
- Liskov Substitution Principle (LSP).
- Interface Segregation Principle (ISP).
- Dependency Inversion Principle (DIP).
Design Patterns:
- Factory method pattern.
- Abstract factory pattern.
- Strategy pattern.
- Template method pattern.
Let’s implement the Strategy Pattern as an example:
from abc import ABC, abstractmethod
class SortStrategy(ABC):
@abstractmethod
def sort(self, data):
pass
class BubbleSort(SortStrategy):
def sort(self, data):
print("Performing bubble sort")
return sorted(data) # Using Python's built-in sort for simplicity
class QuickSort(SortStrategy):
def sort(self, data):
print("Performing quick sort")
return sorted(data) # Using Python's built-in sort for simplicity
class Sorter:
def __init__(self, strategy):
self.strategy = strategy
def sort(self, data):
return self.strategy.sort(data)
# Usage
data = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5]
bubble_sorter = Sorter(BubbleSort())
print(bubble_sorter.sort(data))
quick_sorter = Sorter(QuickSort())
print(quick_sorter.sort(data))
# Output:
# Performing bubble sort
# [1, 1, 2, 3, 3, 4, 5, 5, 5, 6, 9]
# Performing quick sort
# [1, 1, 2, 3, 3, 4, 5, 5, 5, 6, 9]
This Strategy Pattern example demonstrates how abstraction allows us to define a family of algorithms, encapsulate each one, and make them interchangeable. The Sorter
class doesn’t need to know the details of how each sorting algorithm works; it just knows that it can call the sort
method on any SortStrategy
object.
References
- Gamma, E., Helm, R., Johnson, R., & Vlissides, J. (1994). Design Patterns: Elements of Reusable Object-Oriented Software. Addison-Wesley.
- Martin, R. C. (2017). Clean Architecture: A Craftsman’s Guide to Software Structure and Design. Prentice Hall.
- Phillips, D. (2010). Python 3 Object Oriented Programming. Packt Publishing.
- Lutz, M. (2013). Learning Python: Powerful Object-Oriented Programming. O’Reilly Media.
- Ramalho, L. (2015). Fluent Python: Clear, Concise, and Effective Programming. O’Reilly Media.
- Van Rossum, G., Warsaw, B., & Coghlan, N. (2001). PEP 8 – Style Guide for Python Code. Python.org. https://www.python.org/dev/peps/pep-0008/
- Python Software Foundation. (n.d.). The Python Standard Library. Python.org. https://docs.python.org/3/library/
Cheers for making it this far! I hope this journey through the programming universe has been as fascinating for you as it was for me to write down.
We’re keen to hear your thoughts, so don’t be shy – drop your comments, suggestions, and those bright ideas you’re bound to have.
Also, to delve deeper than these lines, take a stroll through the practical examples we’ve cooked up for you. You’ll find all the code and projects in our GitHub repository learn-software-engineering/examples-programming.
Thanks for being part of this learning community. Keep coding and exploring new territories in this captivating world of software!
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.