经理/集装箱班,怎么办?

Rohi:

我目前正在设计需要管理特定硬件设置的软件。

硬件设置如下:

系统设计

系统-系统包含两个相同的设备,并且相对于整个系统具有某些功能。

设备-每个设备包含两个相同的子设备,并且相对于两个子设备具有某些功能。

子设备-每个子设备都有4个可配置的实体(通过相同的硬件命令控制-因此我不将它们视为子子设备)。

我要实现的目标:

我想通过系统管理器控制所有可配置的实体(实体以串行方式计数),这意味着我可以执行以下操作:

system_instance = system_manager_class(some_params)
system_instance.some_func(0) # configure device_manager[0].sub_device_manager[0].entity[0]
system_instance.some_func(5) # configure device_manager[0].sub_device_manager[1].entity[1]
system_instance.some_func(8) # configure device_manager[1].sub_device_manager[1].entity[0]

我想到要做什么:

我当时正在考虑创建一个抽象类,该类包含所有子设备功能(带有对转换功能的调用),并由system_manager,device_manager和sub_device_manager继承它。因此,所有类都将具有相同的函数名,并且我将能够通过系统管理器访问它们。这些线周围的东西:

class abs_sub_device():
    @staticmethod
    def convert_entity(self):
        sub_manager = None
        sub_entity_num = None
        pass

    def set_entity_to_2(entity_num):
        sub_manager, sub_manager_entity_num = self.convert_entity(entity_num)
        sub_manager.some_func(sub_manager_entity_num)


class system_manager(abs_sub_device):
    def __init__(self):
        self.device_manager_list = [] # Initiliaze device list
        self.device_manager_list.append(device_manager())
        self.device_manager_list.append(device_manager())

    def convert_entity(self, entity_num):
        relevant_device_manager = self.device_manager_list[entity_num // 4]
        relevant_entity         = entity_num % 4
        return relevant_device_manage, relevant_entity

class device_manager(abs_sub_device):
    def __init__(self):
        self.sub_device_manager_list = [] # Initiliaze sub device list
        self.sub_device_manager_list.append(sub_device_manager())
        self.sub_device_manager_list.append(sub_device_manager())        

    def convert_entity(self, entity_num):
        relevant_sub_device_manager = self.sub_device_manager_list[entity_num // 4]
        relevant_entity         = entity_num % 4
        return relevant_sub_device_manager, relevant_entity

class sub_device_manager(abs_sub_device):
    def __init__(self): 
        self.entity_list = [0] * 4

    def set_entity_to_2(self, entity_num):
        self.entity_list[entity_num] = 2
  • 该代码用于一般理解我的设计,而不是实际功能。

问题 :

在我看来,我要设计的系统确实是通用的,并且必须使用内置的python方法来执行此操作,否则我整个面向对象的观点都是错误的。

我真的很想知道是否有人有更好的方法来做到这一点。

Rohi:

经过深思熟虑,我认为我发现了一种非常通用的解决方法,可以结合使用装饰器,继承和动态函数创建。

主要思想如下:

1)每层为其自身动态创建所有与子层相关的功能(在init函数内部,使用init函数上的装饰器)

2)创建的每个函数根据转换函数(abs_container_class的静态函数)动态转换实体值,并使用相同的名称调用下层函数(请参见make_convert_function_method)。

3)这基本上导致所有子层功能在零代码重复的更高级别上实现。

def get_relevant_class_method_list(class_instance):
    method_list = [func for func in dir(class_instance) if callable(getattr(class_instance, func)) and not func.startswith("__") and not func.startswith("_")]
    return method_list

def make_convert_function_method(name):
    def _method(self, entity_num, *args):
        sub_manager, sub_manager_entity_num = self._convert_entity(entity_num)
        function_to_call = getattr(sub_manager, name)
        function_to_call(sub_manager_entity_num, *args)        
    return _method


def container_class_init_decorator(function_object):
    def new_init_function(self, *args):
        # Call the init function :
        function_object(self, *args)
        # Get all relevant methods (Of one sub class is enough)
        method_list = get_relevant_class_method_list(self.container_list[0])
        # Dynamically create all sub layer functions :
        for method_name in method_list:
            _method = make_convert_function_method(method_name)
            setattr(type(self), method_name, _method)

    return new_init_function


class abs_container_class():
    @staticmethod
    def _convert_entity(self):
        sub_manager = None
        sub_entity_num = None
        pass

class system_manager(abs_container_class):
    @container_class_init_decorator
    def __init__(self):
        self.device_manager_list = [] # Initiliaze device list
        self.device_manager_list.append(device_manager())
        self.device_manager_list.append(device_manager())
        self.container_list = self.device_manager_list

    def _convert_entity(self, entity_num):
        relevant_device_manager = self.device_manager_list[entity_num // 4]
        relevant_entity         = entity_num % 4
        return relevant_device_manager, relevant_entity

class device_manager(abs_container_class):
    @container_class_init_decorator
    def __init__(self):
        self.sub_device_manager_list = [] # Initiliaze sub device list
        self.sub_device_manager_list.append(sub_device_manager())
        self.sub_device_manager_list.append(sub_device_manager())    
        self.container_list = self.sub_device_manager_list

    def _convert_entity(self, entity_num):
        relevant_sub_device_manager = self.sub_device_manager_list[entity_num // 4]
        relevant_entity         = entity_num % 4
        return relevant_sub_device_manager, relevant_entity

class sub_device_manager():
    def __init__(self): 
        self.entity_list = [0] * 4

    def set_entity_to_value(self, entity_num, required_value):
        self.entity_list[entity_num] = required_value
        print("I set the entity to : {}".format(required_value))

# This is used for auto completion purposes (Using pep convention)
class auto_complete_class(system_manager, device_manager, sub_device_manager):
    pass


system_instance = system_manager() # type: auto_complete_class
system_instance.set_entity_to_value(0, 3)

该解决方案仍然存在一个小问题,因为最高级别的类几乎没有静态实现的功能,所以自动完成不会起作用。为了解决这个问题,我作了一些欺骗,我创建了一个空类,该类从所有层继承,并使用pep约定向IDE声明它是所创建实例的类型(#类型:auto_complete_class)。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章