基于ERP程序的公共代码中出现的问题及过度封装不方便维护的解决办法

下面是详细讲解“基于ERP程序的公共代码中出现的问题及过度封装不方便维护的解决办法”的完整攻略:

问题描述

在基于ERP程序开发中,通常会编写一些公共代码,用于实现各个模块之间的数据交互、统计分析等公共功能。然而,这些公共代码中常常存在以下问题:

  1. 代码重复冗余:由于各个模块有不同的需求,开发人员往往为了方便直接复制粘贴原有代码,导致公共代码中存在大量重复和冗余的代码片段。
  2. 封装过度:为了提高代码的可复用性和易维护性,开发人员常常会对公共代码进行过度的封装,导致代码结构复杂,不易理解和维护。

解决办法

针对以上问题,可以采用以下解决办法:

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技术站

(0)
上一篇 2023年6月25日
下一篇 2023年6月25日

相关文章

  • 需要管理员权限来启动美的vpn

    以下是详细讲解“需要管理员权限来启动美的VPN”的完整攻略,过程中至少包含两条示例说明的标准Markdown格式文本: 要管理员权限来启动美的VPN 在启动美的VPN时,可能会遇到需要管理员权限的情况。本文将介绍如何以管理员身份启动美的VPN。 方法1:右键单击程序图标 在Windows操作系统中,可以通过右键单击程序图标来以管理员身份启动程序。以下是示例步…

    other 2023年5月10日
    00
  • JavaScript使用原型和原型链实现对象继承的方法详解

    JavaScript使用原型和原型链实现对象继承的方法详解 1. 什么是原型和原型链? 在JavaScript中,每个对象都有一个指向另一个对象的原型(prototype)对象,这种关系被称为原型链(prototype chain)。 JavaScript中的继承是通过原型链实现的。每个对象都有一个原型,原型也是一个对象,同时也有自己的原型,这样就形成了一个…

    other 2023年6月26日
    00
  • Android框架RePlugin使用详解

    以下是关于Android框架RePlugin使用的详细攻略: RePlugin使用详解 RePlugin是一个开源的Android插件化框架,它可以实现在主应用中加载和运行插件。下面是使用RePlugin的步骤: 引入RePlugin库依赖 在主应用的build.gradle文件中添加以下依赖: groovy dependencies { implement…

    other 2023年10月14日
    00
  • linux软件开发时给gcc指定头文件和库文件路径的方法

    对于Linux软件开发,在编译时需要指定头文件和库文件的路径,以便编译器能够正确地找到这些文件。可以通过以下两种方法来指定这些路径: 方法一:使用gcc的-I和-L选项 gcc提供了一些选项来指定头文件和库文件的搜索路径。使用-I选项可以指定头文件的搜索路径,-L选项可以指定库文件的搜索路径。 下面是一个指定头文件和库文件路径的示例: gcc -I /pat…

    other 2023年6月27日
    00
  • perl 文件操作总结

    Perl 文件操作总结 文件句柄 在 Perl 中,文件句柄用于与外部文件进行交互。这包括打开、读取和关闭文件。 打开文件 我们可以使用 open 函数打开一个外部文件,并将其指定为一个文件句柄。语法如下: open FILEHANDLE, EXPR 其中 FILEHANDLE 是您打算使用的文件句柄名称,EXPR 是包含您要打开的文件的路径和名称的字符串表…

    other 2023年6月27日
    00
  • 推荐几个bt搜索引擎

    推荐几个BT搜索引擎 如果您在寻找BT资源时经常受到各种限制或无法找到合适的资源,那么您需要尝试使用一些更好的BT搜索引擎。以下是一些我们推荐的优秀BT搜索引擎。部分可能需要科学上网工具,可参考此文章:推荐几个靠谱的VPN。 1. 磁力猫 磁力猫是目前网上最受欢迎的BT搜索引擎之一。它提供了一种简单易用的方式来搜索第三方资源,并且支持磁力链接和种子文件的下载…

    2023年3月28日
    00
  • Golang实现单链表的示例代码

    下面是详细的攻略: 单链表简介 单链表是一种基础的数据结构,由若干个节点组成,每个节点包含数据和指向下一个节点的指针。最后一个节点指向空。单链表的优点是插入和删除操作非常方便,但查找效率较低。在Golang中,使用结构体和指针实现单链表比较方便。 实现单链表的代码 下面是实现单链表的示例代码,具体实现如下: package main import &quot…

    other 2023年6月27日
    00
  • vue遍历json

    以下是关于“Vue遍历JSON”的完整攻略: 步骤1:使用v-for指令 在Vue中,可以使用v-for指令遍历JSON数据。以下一个例,演示如何使用v-for指令遍历JSON数据: <ul> <li v-for="(item, index) in items" :key="index"> {{…

    other 2023年5月7日
    00
合作推广
合作推广
分享本页
返回顶部