How to Abstract Common Code

Time: Column:Python views:209

Example: Handling the Upload and Processing of Different File Types

Suppose we have an application that needs to handle uploads of various file types (e.g., text files, images, and videos). Each file type requires specific processing and validation. In such cases, the code may contain significant redundancy, especially in validation and saving logic.

Non-Abstracted Code Example

The following example demonstrates handling each file type separately. While functional, this approach results in repetitive logic that could benefit from abstraction:

def upload_text_file(file):
    if not file.endswith('.txt'):
        raise ValueError("Invalid file format")
    # Logic to save the file
    print("Text file saved")

def upload_image_file(file):
    if not file.endswith(('.png', '.jpg', '.jpeg')):
        raise ValueError("Invalid file format")
    # Logic to save the file
    print("Image file saved")

def upload_video_file(file):
    if not file.endswith(('.mp4', '.avi', '.mov')):
        raise ValueError("Invalid file format")
    # Logic to save the file
    print("Video file saved")

Refactoring with Abstraction

Generally, abstracting common code involves the following steps:

  1. Identify Repetitive Code: Locate similar logic repeated across different parts of the codebase.

  2. Define Generalized Operations: Convert repetitive logic into one or more functions that accept parameters for specific details.

  3. Parameterize Variations: Identify the parts that vary and make them parameters of the generalized function.

  4. Integrate and Test: Replace the original code with calls to the abstracted function and test to ensure everything works as expected.


Refactored Abstract Code

Using the above principles, we can refactor the code to make it more abstract and reusable:

def upload_file(file, valid_extensions):
    if not file.endswith(valid_extensions):
        raise ValueError("Invalid file format")
    # Logic to save the file
    print(f"File saved: {file}")

def main():
    upload_file("example.txt", ('.txt',))
    upload_file("example.png", ('.png', '.jpg', '.jpeg'))
    upload_file("example.mp4", ('.mp4', '.avi', '.mov'))

Benefits of the Refactored Version

  1. Reduced Redundancy:

    • The common logic for file validation and saving is now centralized in the upload_file function.

  2. Improved Maintainability:

    • Changes to the validation or save logic need to be made in only one place.

  3. Enhanced Extensibility:

    • Adding support for new file types requires only passing the appropriate file extension(s) as parameters to the function.

By using abstraction, we extracted the common logic for file uploads and validations into a single, reusable function. This approach makes the codebase more concise, manageable, and adaptable to future requirements.