下面是详细讲解“基于ERP程序的公共代码中出现的问题及过度封装不方便维护的解决办法”的完整攻略:
问题描述
在基于ERP程序开发中,通常会编写一些公共代码,用于实现各个模块之间的数据交互、统计分析等公共功能。然而,这些公共代码中常常存在以下问题:
- 代码重复冗余:由于各个模块有不同的需求,开发人员往往为了方便直接复制粘贴原有代码,导致公共代码中存在大量重复和冗余的代码片段。
- 封装过度:为了提高代码的可复用性和易维护性,开发人员常常会对公共代码进行过度的封装,导致代码结构复杂,不易理解和维护。
解决办法
针对以上问题,可以采用以下解决办法:
1. 代码复用
为了减少重复冗余的代码片段,可以将公共代码进行封装,形成一个独立的模块或类库,供各个模块共享调用。例如,对于重复的数据库连接和关闭操作,可以封装成一个公共函数,供各个模块调用。
同时,也可以采用面向对象编程的思想,将多个功能相似的代码封装成一个基类,继承该基类的子类可以共享基类的方法和属性。这样既能减少代码冗余,又能提高代码的复用性。
例如:
# 封装为公共函数
def connect_db():
db = MySQLdb.connect(host='localhost', user='root', password='123456', db='erp')
cursor = db.cursor()
return db, cursor
# 继承基类
class Base(object):
def connect_db(self):
self.db, self.cursor = MySQLdb.connect(host='localhost', user='root', password='123456', db='erp')
def close_db(self):
self.cursor.close()
self.db.close()
class ModuleA(Base):
def do_something(self):
self.connect_db()
# do something
self.close_db()
class ModuleB(Base):
def do_something_else(self):
self.connect_db()
# do something else
self.close_db()
2. 最小化封装
为了避免过度封装,可以采用最小化封装的原则,即尽量保持代码简洁和易读。同时,也要注意封装的层次不能过深,过多的层次会增加阅读和维护的难度。
例如,对于数据库操作代码:
class DbHelper(object):
# 处理数据库连接和关闭
def __init__(self, host, user, password, db):
self.host = host
self.user = user
self.password = password
self.db = db
self.db_conn = None
self.db_cursor = None
def connect(self):
self.db_conn = pymysql.connect(
host=self.host,
user=self.user,
password=self.password,
db=self.db,
charset='utf8mb4'
)
self.db_cursor = self.db_conn.cursor()
def close(self):
try:
if self.db_cursor:
self.db_cursor.close()
if self.db_conn:
self.db_conn.close()
except Exception as e:
print('close db connection error: ', e)
可以最小化封装,将数据库连接和关闭的代码直接放在模块内:
class ModuleA(object):
# 处理数据库连接和关闭
def __init__(self, host, user, password, db):
self.host = host
self.user = user
self.password = password
self.db = db
self.db_conn = None
self.db_cursor = None
def connect(self):
self.db_conn = pymysql.connect(
host=self.host,
user=self.user,
password=self.password,
db=self.db,
charset='utf8mb4'
)
self.db_cursor = self.db_conn.cursor()
def close(self):
try:
if self.db_cursor:
self.db_cursor.close()
if self.db_conn:
self.db_conn.close()
except Exception as e:
print('close db connection error: ', e)
def do_something(self):
self.connect()
# do something
self.close()
class ModuleB(object):
# 处理数据库连接和关闭
def __init__(self, host, user, password, db):
self.host = host
self.user = user
self.password = password
self.db = db
self.db_conn = None
self.db_cursor = None
def connect(self):
self.db_conn = pymysql.connect(
host=self.host,
user=self.user,
password=self.password,
db=self.db,
charset='utf8mb4'
)
self.db_cursor = self.db_conn.cursor()
def close(self):
try:
if self.db_cursor:
self.db_cursor.close()
if self.db_conn:
self.db_conn.close()
except Exception as e:
print('close db connection error: ', e)
def do_something_else(self):
self.connect()
# do something else
self.close()
这样代码会更加简洁,易于理解和维护。
示例说明
下面给出两个具体的示例,说明如何解决基于ERP程序的公共代码中出现的问题及过度封装不方便维护的解决办法。
示例一:数据库连接
假设在ERP系统中有多个模块需要访问同一个数据库,为了提高可复用性和扩展性,我们需要将数据库操作封装为公共代码。我们可以采用最小化封装的原则,将数据库连接和关闭操作封装在模块内部,减少过度封装的问题。
class ModuleA(object):
# 处理数据库连接和关闭
def __init__(self, host, user, password, db):
self.host = host
self.user = user
self.password = password
self.db = db
self.db_conn = None
self.db_cursor = None
def connect(self):
self.db_conn = pymysql.connect(
host=self.host,
user=self.user,
password=self.password,
db=self.db,
charset='utf8mb4'
)
self.db_cursor = self.db_conn.cursor()
def close(self):
try:
if self.db_cursor:
self.db_cursor.close()
if self.db_conn:
self.db_conn.close()
except Exception as e:
print('close db connection error: ', e)
def do_something(self):
self.connect()
# do something
self.close()
class ModuleB(object):
# 处理数据库连接和关闭
def __init__(self, host, user, password, db):
self.host = host
self.user = user
self.password = password
self.db = db
self.db_conn = None
self.db_cursor = None
def connect(self):
self.db_conn = pymysql.connect(
host=self.host,
user=self.user,
password=self.password,
db=self.db,
charset='utf8mb4'
)
self.db_cursor = self.db_conn.cursor()
def close(self):
try:
if self.db_cursor:
self.db_cursor.close()
if self.db_conn:
self.db_conn.close()
except Exception as e:
print('close db connection error: ', e)
def do_something_else(self):
self.connect()
# do something else
self.close()
示例二:日志输出
假设在ERP系统中有多个模块需要输出日志信息,我们需要将日志输出封装为公共代码。我们可以采用代码复用的方式,将日志输出封装为一个独立的模块LogHelper,供各个模块调用。
# 封装日志输出
class LogHelper(object):
def __init__(self, logger_name, log_file_path):
self.logger = logging.getLogger(logger_name)
self.logger.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
file_handler = logging.FileHandler(log_file_path)
file_handler.setLevel(logging.DEBUG)
file_handler.setFormatter(formatter)
self.logger.addHandler(file_handler)
def info(self, log_message):
self.logger.info(log_message)
def warning(self, log_message):
self.logger.warning(log_message)
def error(self, log_message):
self.logger.error(log_message)
class ModuleA(object):
def __init__(self, logger):
self.logger = logger
def do_something(self):
self.logger.info('invoke ModuleA.do_something')
class ModuleB(object):
def __init__(self, logger):
self.logger = logger
def do_something_else(self):
self.logger.warning('invoke ModuleB.do_something_else')
这样,我们可以通过实例化一个LogHelper对象,为各个模块提供日志输出的功能,同时避免了代码重复和过度封装的问题。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:基于ERP程序的公共代码中出现的问题及过度封装不方便维护的解决办法 - Python技术站