基于OOP和S.O.L.I.D的硬编码替代方案

问题描述 投票:0回答:1

我必须重构此代码,因为从SOLID的角度来看这不是一个好习惯(不可扩展),有哪些替代方案?

我有一个文本文件,可以从中读取命令,其格式如下:

ADD_CHILD name1 name2性别

GET_RELATIONSHIP name1关系..

我认为这里的问题是当我将words传递给函数时,因为如果文本文件的格式更改,我的代码将中断。我想到的一件事是使用if-elif语句,但是开闭原则不建议使用它们。还有哪些其他可能的方法?

    path_str=input("Enter the path of input file ")
    fileinput=open(path_str,"r")
    for line in fileinput:
        words=line.split()
        function=set1solution.function_select_map.get(words[0])
        result=function(family,words)

    function_select_map={
        "ADD_CHILD":add_child,
        "GET_RELATIONSHIP":get_relationship
    }

    relation_map={
        "Paternal-Uncle":Family.get_Paternal_Uncle,
         ......}

    def add_child(family,words):
        #find person just returns an object of person class
        parent=family.find_person(words[1])
        new_addition=Person(words[2],words[3],words[1])
 result=family.add_external_child(words[1],new_addition.name,new_addition.gender)
        return result

    def get_relationship(family,words):
        person=family.find_person(words[1])
        function=set1solution.relation_map.get(words[2])
        result=function(family,person)
        return result
python-3.x solid-principles open-closed-principle
1个回答
0
投票

正如您正确提到的那样,您的代码取决于不建议使用的文件格式。 add_childget_relationship不应该了解文件格式,因此您的代码中应该包含以下数据流:

File => File parser => app logic

文件解析器是文件中的数据和您的代码之间的一种中介。实现此目的的方法很少,这是一个简短解决方案的一部分(附我的评论):

def add_child_parser(words):
    return add_child, (family, words[0], words[1], words[2])  # return params for add_child function in correct order, not that it's not obvious from your code where family come from

def command_parser(line):
    d = {
        "ADD_CHILD": add_child_parser,
        "GET_RELATIONSHIP": get_relationship_parser
    }  # dict with all availbale command parsers
    words = line.split()
    curr_parser = d[words[0]]  # get parser for current command
    func, args_list = curr_parser(words[1:])  # call parser for current command with other words as params
    func(*args_list)  # call returned function

def file_parser(file_path):
    file_input = open(file_path, "r")
    for line in file_input:
        command_parser(line)  # process each line

def add_child(family, parent_name, child_name, child_gender):  # note, we receive all required data in params, not as single string
    parent = family.find_person(parent_name)
    new_child = Person(child_name, child_gender, parent_name)

    return family.add_external_child(new_child)
© www.soinside.com 2019 - 2024. All rights reserved.