天天看點

用python實作軟體設計模式之抽象工廠模式

作者:搬磚搬知識

前言

抽象工廠模式,提供一個建立一系列相關或互相依賴對象的接口,而無需指定它們具體的類。

代碼

class User:
    def __init__(self) -> None:
        self.id = 0
        self.name = ""
    @property
    def ID(self):
        return self.id
    
    @ID.setter
    def ID(self, id):
        self.id = id

    @property
    def Name(self):
        return self.name
    
    @Name.setter
    def Name(self, name):
        self.name = name

class IUser:
    def Insert(self, user : User) -> None:
        self.user = user

    def Get_User(self, id : int) -> User:
        print(f"id {id}")

class Sqlserver_User(IUser):
    def Insert(self, user: User) -> None:
        print("在SQL Server中給User表添加一條記錄")
        super().Insert(user)

    def Get_User(self, id: int) -> User:
        print("在SQL Server中根據ID得到User表中的一條記錄")
        super().Get_User(id)

class Access_User(IUser):
    def Insert(self, user: User) -> None:
        print("在Access中給User表添加一條記錄")
        super().Insert(user)

    def Get_User(self, id: int) -> User:
        print("在Access中根據ID得到User表中的一條記錄")
        super().Get_User(id)

class Department:
    def __init__(self) -> None:
        self.id = 0
        self.department_name = ""
    @property
    def ID(self):
        return self.id
    
    @ID.setter
    def ID(self, id):
        self.id = id

    @property
    def Department_Name(self):
        return self.department_name
    
    @Department_Name.setter
    def Department_Name(self, department_name):
        self.department_name = department_name

class IDepartment:
    def Insert(self, department : Department):
        self.department = department

    def Get_Department(self, id):
        print(f"id {id}")

class Sqlserver_Department(IDepartment):
    def Insert(self, department: Department):
        print("在SQL Server中給Department表增加一條記錄")
        super().Insert(department)
    
    def Get_Department(self, id):
        print("在SQL Server中根據ID得到Department表中的一條記錄")
        super().Get_Department(id)

class Access_Department(IDepartment):
    def Insert(self, department: Department):
        print("在Access中給Department表增加一條記錄")
        super().Insert(department)
    
    def Get_Department(self, id):
        print("在Access中根據ID得到Department表中的一條記錄")
        super().Get_Department(id)

class IFactory:
    def Create_User(self) -> IUser:
        pass

    def Create_Department(self):
        pass

class Sqlserver_Factory(IFactory):
    def Create_User(self) -> IUser:
        return Sqlserver_User()
    
    def Create_Department(self):
        return Sqlserver_Department()

class Access_Factory(IFactory):
    def Create_User(self) -> IUser:
        return Access_User()
    
    def Create_Department(self):
        return Access_Department()

if __name__ == '__main__':
    user = User()
    user.ID = 1
    user.Name = "shockly"

    factory = Sqlserver_Factory()

    iu = factory.Create_User()

    iu.Insert(user)
    iu.Get_User(1)

    dept = Department()
    dept.ID = 2
    dept.Department_Name = "luckly"
    id = factory.Create_Department()
    id.Insert(dept)
    id.Get_Department(2)           

運作結果:

用python實作軟體設計模式之抽象工廠模式

抽象工廠模式和之前寫的工廠方法模式類似,差別在于工廠方法模式是一個工廠生成一種産品類,而抽象工廠模式是一個工廠可以生産多種産品類。

代碼中IFactory為工廠父類,Sqlserver_Factory和Access_Factory為IFactory的子類。IUser和IDepartment為産品父類,其子類分别是Sqlserver_User、Access_User和Sqlserver_Department、Access_Department。Sqlserver_Factory和Access_Factory用來分别決定是否生産Sqlserver_User、Access_User和Sqlserver_Department、Access_Department。

總結

抽象工廠模式的優點其實很明顯,可以把很多個産品類都放在一個工廠類中進行建立。

同時也會帶來其缺點,就是如果需要新增一個産品類,幾乎所有的工廠類都需要進行代碼修改。

應用的場景,當需要建立的對象是一系列互相關聯或互相依賴的産品類時,适合用抽象工廠模式。