dimanche 23 février 2020

Implemention question for a template/framework method design pattern in python

I'm implementing a template method design pattern in python, and have a question about whether a helper function in the abstract class' template method should be an instance or static function. Both would work, but I'm not sure on the pros and cons of both approaches.

Background

I'm writing a framework to support testing images, where I can plugin different test methods depending on the type of image etc, hence I'm using a template method design pattern.

The abstract class template method to do the testing will need to support testing images in parallel, and will support doing this either using Multiprocessing (if running locally) or via AWS lambdas if running on AWS.

I want to encapsulate the details of the 'run_tests_locally' and the 'run_tests_lambda' into helper functions to avoid cluttering the main template method.

Question

My question is whether it's best to make the above 'run_tests' functions as A) instance methods, or B) static methods in my abstract class definition. ...See below

Both would seem to work, but not sure which is best, and would love some guidance/thoughts

from abc import ABC, abstractmethod

import util.misc as misc

class TestFramework(ABC):
    """
    Abstract class for executing tests
    """

    @abstractmethod
    def filter(self, objs):
        """Take list of objects, and return filtered list of those to test"""
        pass

    @abstractmethod
    def do_test(self, obj):
        """Take a single object, test it, and return dict of results"""
        pass


    def execute_test(self, file_list):
        """Execute test"""

        # library function
        all_objs = misc.load_files(file_list)

        # instance template function - shortlist objects
        to_test_objs = self.filter(all_objs)

        # now test objects

        # how is it best to implment the 'run_tests' functions?
        #    A) instance methods?
        #    B) static methods?

        # if running on aws, do tests across multiple lambda
        # if local, use MP to run in parallel

        if env = 'aws':
            # as an instance method
            test_results = self.run_tests_lambda(to_test_objs)
            # as static:
            test_results = run_tests_lambda_STATIC(to_test_objs, self.do_test)

        else:       
            # instance form:
            test_results = self.run_tests_local(to_test_objs)
            # static form:     
            test_results = run_tests_local_STATIC(to_test_objs, self.do_test)


        return test_results


    # instance method implementation
    def run_tests_local(self, to_test_objs):

        all_results = {}

        with ProcessPoolExecutor as e:

            procs = [e.submit(self.do_test, obj) for obj in to_test_objs]

            for proc in as_completed(procs):
                all_results.update(proc.result())

        return all_results


    # static method implementation
    @staticmethod
    def run_tests_local_STATIC(to_test_objs, test_fn):

        all_results = {}

        with ProcessPoolExecutor as e:

            procs = [e.submit(test_fn, obj) for obj in to_test_objs]

            for proc in as_completed(procs):
                all_results.update(proc.result())

        return all_results


Aucun commentaire:

Enregistrer un commentaire