我必须重构此代码,因为从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
正如您正确提到的那样,您的代码取决于不建议使用的文件格式。 add_child
和get_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)