Python_面向对象:多态&工厂模式

一、概念

多态是面向对象编程的三大特征之一,多态则是指同一个行为可以有多个不同表现形式的能力。也就是说,在父类中定义的属性和方法,在子类继承后,可以有不同的数据类型或表现出不同的行为。这可以使得同一个属性或方法,在父类及其各个子类中,可能会有不同的表现或含义。

二、作用

根据多态的概念可知,多态机制可以在不修改父类代码的基础上,允许多个子类进行功能的扩展。比如父类中定义了一个方法A,有N个子类继承该父类,这几个子类都可以重写这个A方法。并且子类的方法还可以将自己的参数类型改为父类方法的参数类型,或者将自己的返回值类型改为父类方法的返回值类型。这样就可以动态地调整对象的调用,降低对象之间的依存关系,消除类型之间的耦合,使程序有良好的扩展,并可以对所有类的对象进行通用处理,让代码实现更加的灵活和简洁。

三、实现多态的条件

1、必须在继承体系下
2、子类必须要对父类中的方法进行重写
3、通过子类的引用调用重写的方法

3.1 案例演示

同一目录下有文件如下:
report.py
class BaseReport(object):
    report_type = None

    def __init__(self):
        self.content = None

    def handle_content(self):
        pass

    def write(self):
        content = self.content or "无报告"
        print("输出测试报告:" + content)


class HtmlReport(BaseReport):
    report_type = "Html"

    def handle_content(self):
        self.content = "处理html报告内容"


class TextReport(BaseReport):
    report_type = "Text"

    def handle_content(self):
        self.content = "处理text报告内容"


class XmlReport(BaseReport):
    report_type = "Xml"

    def handle_content(self):
        self.content = "处理xml报告内容"
run.py
from report import HtmlReport, TextReport


# 简单方式演示多态
def run_test(report_type):
    if report_type == "Html":
        obj = HtmlReport()
    else:
        obj = TextReport()
    # 不同的实例对象,使用相同的方法,产生不同的结果,这就是多态的表现
    obj.handle_content()
    obj.write()


if __name__ == '__main__':
    run_test("Html")
    run_test("Text")

上面的代码通过 run_test 方法传入不同的参数,生成了不同的报告,像这种引用不同的实例对象,调用相同的方法,产生不同的结果,就是多态的表现。

四、工厂模式

再回头看下 run_test 这个方法,如果要添加新的类型报告(比如:xml),就要修改run_test 方法中的if 判断逻辑,这样的代码耦合性很高。那有没有什么方法来解耦呢?答案是使用 工厂模式。
工厂模式是一种创建型设计模式,它提供了一种创建对象的最佳方式。在工厂模式中,对象的创建过程被封装在工厂类中,通过工厂类来创建对象,可以将对象的创建与使用代码分离,提供一种统一的接口来创建不同类型的对象。这样可以降低代码的耦合性,提高代码的可维护性和可扩展性。

4.1 优点

  1. 降低代码耦合性:通过工厂类创建对象,可以将对象的创建与使用代码分离,降低了代码之间的耦合性,使得代码更加清晰和易于维护。
  2. 提高代码的可扩展性:如果需要增加新的产品类,只需要增加相应的工厂类和产品类即可,无需修改原有的代码,符合开闭原则,提高了代码的可扩展性。
  3. 提供统一的接口:工厂模式提供一个共同的接口来创建各种对象,这使得代码更加统一和易于理解。

4.2 工厂模式案例演示

import importlib
from report import BaseReport


# 工厂模式演示多态
def factory_run_test(report_type):
    # 导入report.py模块
    mod = importlib.import_module("report")
    func_strs = dir(mod)
    for fs in func_strs:
        cur_func = getattr(mod, fs)

        # 判断模块是否是类
        if not isinstance(cur_func, type):
            continue
        # 判断模块是否是BaseReport的子类
        if not issubclass(cur_func, BaseReport):
            continue
        if cur_func.report_type == report_type:
            obj = cur_func()
            obj.handle_content()
            obj.write()
            break
    else:
        print("未知报告类型")


if __name__ == '__main__':
    factory_run_test("Html")
    factory_run_test("Text")
    factory_run_test("Xml")

从代码以及执行情况可以看出,如果添加新的类型报告,只需要按规范添加BaseReport子类即可,不需要再修改 factory_run_test 方法的代码。

 

 

 

 

 

 
posted @ 2019-10-24 14:19  码上测  阅读(288)  评论(0编辑  收藏  举报