基于 OOP 和 S.O.L.I.D 的硬编码替代方案
OOP and S.O.L.I.D based alternative to hard coding
我必须重构这段代码,因为从 SOLID 的角度来看,这不是一个好的做法(不可扩展),有哪些替代方案?
我有一个文本文件,我从中读取命令,其格式如下:
ADD_CHILD 姓名1 姓名2 性别
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)
我必须重构这段代码,因为从 SOLID 的角度来看,这不是一个好的做法(不可扩展),有哪些替代方案?
我有一个文本文件,我从中读取命令,其格式如下:
ADD_CHILD 姓名1 姓名2 性别
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)