设计模式之七--抽象工厂模式

抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无需指出他们具体的类。 依赖抽象编程

具体代码如下

from abc import ABCMeta, abstractmethod


class IFactory(metaclass=ABCMeta):
    @abstractmethod
    def create_user(self):
        pass

    @abstractmethod
    def create_department(self):
        pass


class AccessFactory(IFactory):
    def create_department(self):
        return AccessDepartment()

    def create_user(self):
        return AccessUser()


class SQLFactory(IFactory):

    def create_user(self):
        return SQLUser()

    def create_department(self):
        return SQLDepartment()


class IUser(metaclass=ABCMeta):
    @abstractmethod
    def insert(self, user):
        pass


class AccessUser(IUser):
    def __init__(self):
        pass

    def insert(self, user):
        print("Insert user {0} in Access".format(user))


class SQLUser(IUser):
    def __init__(self):
        pass

    def insert(self, user):
        print("Insert user {0} in SQL".format(user))


class IDepartment(metaclass=ABCMeta):
    @abstractmethod
    def insert(self, department):
        pass


class AccessDepartment(IDepartment):
    def __init__(self):
        pass

    def insert(self, department):
        print("Insert department {} in access".format(department))


class SQLDepartment(IDepartment):
    def __init__(self):
        pass

    def insert(self, department):
        print("Insert department {0} in SQL".format(department))


if __name__ == "__main__":
    factory = AccessFactory()

    user_li = AccessUser()
    department_software = AccessDepartment()

    user_operation = factory.create_user()
    user_operation.insert(user_li)

    department_operation = factory.create_department()
    department_operation.insert(department_software)

其实,抽象工厂和简单工厂模式,还有工厂方法模式非常相似。
抽象工厂的好处:

  • 在一个应用中只需要在初始化的时候出现一次,这就是的改版一个具体的工厂变得非常容易,只需要改变具体工厂即可使用不同的产品配置。
  • 他让具体的创建实例过程与客户端分离,客户端是通过他们的抽象接口操纵实例,产品的具体类名也被具体工厂的实现分离,不会出现在客户代码中。
    抽象工厂的缺点:
    每添加一个功能就需要添加类。需要进行考量。

下面把上面的实现改成通过反射和简单工厂来实现。
config.ini文件内容如下:

[DataBase]
db = Access
from abc import ABCMeta, abstractmethod
import configparser
import sys


class DataAccess:
    def __init__(self, db):
        self.db = db

    def create_user(self):
        class_name = "".join([self.db, "User"])
        user_class = getattr(sys.modules[__name__], class_name)
        return user_class()

    def create_department(self):
        class_name = "".join([self.db, "Department"])
        department_class = getattr(sys.modules[__name__], class_name)
        return department_class()


class IUser(metaclass=ABCMeta):
    @abstractmethod
    def insert(self, user):
        pass


class AccessUser(IUser):
    def __init__(self):
        pass

    def insert(self, user):
        print("Insert user {0} in Access".format(user))


class SQLUser(IUser):
    def __init__(self):
        pass

    def insert(self, user):
        print("Insert user {0} in SQL".format(user))


class IDepartment(metaclass=ABCMeta):
    @abstractmethod
    def insert(self, department):
        pass


class AccessDepartment(IDepartment):
    def __init__(self):
        pass

    def insert(self, department):
        print("Insert department {} in access".format(department))


class SQLDepartment(IDepartment):
    def __init__(self):
        pass

    def insert(self, department):
        print("Insert department {0} in SQL".format(department))


def parse_configuration():
    config = configparser.ConfigParser()
    config.read("config.ini")
    db = config.get("DataBase", "db")
    return db


if __name__ == "__main__":
    database = parse_configuration()
    data_access = DataAccess(database)

    user_li = AccessUser()
    department_software = AccessDepartment()

    user_operation = data_access.create_user()
    user_operation.insert(user_li)

    department_operation = data_access.create_department()
    department_operation.insert(department_software)

写到极致的代码,就是这样。
其实简单工厂模式里边的分支,很多时候可以通过,反射特性来消除。
简单来说,通过配置文件,配置目标,辅以反射特性,就可以消灭if else以及switch,极大增加灵活性。

你可能感兴趣的:(Python)