举例讲解Python设计模式编程中对抽象工厂模式的运用
抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
优点:易于交换“产品系列”,只要更改相应的工厂即可。
缺点:建立产品的时候很繁琐,需要增加和修改很多东西。
优化1:为了避免客户端有过多的逻辑判断,可以封装出一个简单工厂类来生成产品类。
优化2:为了减少简单工厂类里面的逻辑判断,可以采用“反射”机制,直接根据外部的配置文件读取出需要使用产品类的信息。
#encoding=utf-8 # #by panda #抽象工厂模式 def printInfo(info): print unicode(info, 'utf-8').encode('gbk') #抽象产品A:user表 class IUser(): def Insert(self): pass def GetUser(self): pass #sqlserver实现的User class SqlserverUser(IUser): def Insert(self): printInfo("在SQL Server中给User表增加一条记录") def GetUser(self): printInfo("在SQL Server中得到User表的一条记录") #Access实现的User class AccessUser(IUser): def Insert(self): printInfo("在Access中给User表增加一条记录") def GetUser(self): printInfo("在Access中得到User表一条记录") #抽象产品B:部门表 class IDepartment(): def Insert(self): pass def GetUser(self): pass #sqlserver实现的Department class SqlserverDepartment(IUser): def Insert(self): printInfo("在SQL Server中给Department表增加一条记录") def GetUser(self): printInfo("在SQL Server中得到Department表的一条记录") #Access实现的Department class AccessDepartment(IUser): def Insert(self): printInfo("在Access中给Department表增加一条记录") def GetUser(self): printInfo("在Access中得到Department表一条记录") #抽象工厂 class IFactory(): def CreateUser(self): pass def CreateDepartment(self): pass #sql server工厂 class SqlServerFactory(IFactory): def CreateUser(self): return SqlserverUser() def CreateDepartment(self): return SqlserverDepartment() #access工厂 class AccessFactory(IFactory): def CreateUser(self): return AccessUser() def CreateDepartment(self): return AccessDepartment() #优化一:采用一个简单工厂类,封装逻辑判断操作 class DataAccess(): # db = "Sqlserver" db = "Access" @staticmethod def CreateUser(): if (DataAccess.db == "Sqlserver"): return SqlserverUser() elif(DataAccess.db == "Access"): return AccessUser() @staticmethod def CreateDepartment(): if (DataAccess.db == "Sqlserver"): return SqlserverDepartment() elif(DataAccess.db == "Access"): return AccessDepartment() #优化二:采用反射机制,避免使用太多判断 ##以下信息可以从配置文件中获取 DBType = 'Sqlserver' #'Access' DBTab_User = 'User' DBTab_Department = 'Department' class DataAccessPro(): # db = "Sqlserver" db = "Access" @staticmethod def CreateUser(): funName = DBType + DBTab_User return eval(funName)() #eval 将其中的字符串转化为python表达式 @staticmethod def CreateDepartment(): funName = DBType + DBTab_Department return eval(funName)() def clientUI(): printInfo("\n--------抽象工厂方法--------") factory = SqlServerFactory() iu = factory.CreateUser() iu.Insert() iu.GetUser() id = factory.CreateDepartment() id.Insert() id.GetUser() printInfo("\n--抽象工厂方法+简单工厂方法--") iu = DataAccess.CreateUser() iu.Insert() iu.GetUser() id = DataAccess.CreateDepartment() id.Insert() id.GetUser() printInfo("\n-抽象工厂方法+简单工厂方法+反射-") iu = DataAccessPro.CreateUser() iu.Insert() iu.GetUser() id = DataAccessPro.CreateDepartment() id.Insert() id.GetUser() return if __name__ == '__main__': clientUI();
类图:
工厂模式和抽象工厂模式的区别:工厂模式是在派生类中定义一个工厂的抽象接口,然后基类负责创建具体对象;抽象工厂模式是维护一个产品家族,由基类定义产品被生产的方法,客户根据派生类的接口进行开发。
实例:人民群众喜闻乐见的披萨店例子这里又可以搬出来了,这次我们根据抽象工厂模式的特点,用不同原材料制作不同口味的披萨,创建不同原材料的工厂,不同实体店做出口味不同的披萨。创建一个产品家族(Dough、Sauce、Cheese和Clam)的抽象类型(PizzaIngredientFactory),这个类型的子类(NYPizzaIngredientFactory和ChicagoPizzaIngredientFactory)定义了产品被产生的方法。
代码:
#!/usr/bin/python # -*- coding:utf-8 -*- import sys reload(sys) sys.setdefaultencoding('utf-8') ''' 披萨 ''' class Pizza: name = "" dough = None sauce = None cheese = None clam = None def prepare(self): pass def bake(self): print "烘烤25分钟在350。".decode('utf-8') def cut(self): print "切割成对角线切片。".decode('utf-8') def box(self): print "放在官方的盒子中。".decode('utf-8') def get_name(self): return self.name def set_name(self, name): self.name = name def to_string(self): string = "%s:\n" % self.name string += " 面团: %s\n" % self.dough.to_string() if self.dough else "" string += " 酱汁: %s\n" % self.sauce.to_string() if self.sauce else "" string += " 奶酪: %s\n" % self.cheese.to_string() if self.cheese else "" string += " 文蛤: %s\n" % self.clam.to_string() if self.clam else "" return string ''' 什么类别的披萨 ''' class CheesePizza(Pizza): def __init__(self, ingredient_factory): self.ingredient_factory = ingredient_factory def prepare(self): print "准备: %s" % self.name self.dough = self.ingredient_factory.create_dough() self.sauce = self.ingredient_factory.create_sauce() self.cheese = self.ingredient_factory.create_cheese() class ClamPizza(Pizza): def __init__(self, ingredient_factory): self.ingredient_factory = ingredient_factory def prepare(self): print "准备: %s" % self.name self.dough = self.ingredient_factory.create_dough() self.sauce = self.ingredient_factory.create_sauce() self.clam = self.ingredient_factory.create_clam() ''' 披萨店 ''' class PizzaStore: def order_pizza(self, pizza_type): self.pizza = self.create_pizza(pizza_type) self.pizza.prepare() self.pizza.bake() self.pizza.cut() self.pizza.box() return self.pizza def create_pizza(self, pizza_type): pass ''' 纽约披萨实体店1 ''' class NYPizzaStore(PizzaStore): def create_pizza(self, pizza_type): ingredient_factory = NYPizzaIngredientFactory() if pizza_type == "cheese": pizza = CheesePizza(ingredient_factory) pizza.set_name("纽约风格芝士披萨".decode('utf-8')) elif pizza_type == "clam": pizza = ClamPizza(ingredient_factory) pizza.set_name("纽约风格文蛤披萨".decode('utf-8')) else: pizza = None return pizza ''' 芝加哥披萨实体店2 ''' class ChicagoPizzaStore(PizzaStore): def create_pizza(self, pizza_type): ingredient_factory = ChicagoPizzaIngredientFactory() if pizza_type == "cheese": pizza = CheesePizza(ingredient_factory) pizza.set_name("芝加哥风格芝士披萨".decode('utf-8')) elif pizza_type == "clam": pizza = ClamPizza(ingredient_factory) pizza.set_name("芝加哥风格文蛤披萨".decode('utf-8')) else: pizza = None return pizza ''' 生产披萨的工厂 ''' class PizzaIngredientFactory: def create_dough(self): pass def create_sauce(self): pass def create_cheese(self): pass def create_clam(self): pass ''' 生产披萨的实体工厂1 ''' class NYPizzaIngredientFactory(PizzaIngredientFactory): def create_dough(self): return ThinDough() def create_sauce(self): return MarinaraSauce() def create_cheese(self): return FreshCheese() def create_clam(self): return FreshClam() ''' 生产披萨的实体工厂2 ''' class ChicagoPizzaIngredientFactory(PizzaIngredientFactory): def create_dough(self): return ThickDough() def create_sauce(self): return MushroomSauce() def create_cheese(self): return BlueCheese() def create_clam(self): return FrozenClam() class Dough: def to_string(self): pass class ThinDough(Dough): def to_string(self): return "薄的面团" class ThickDough(Dough): def to_string(self): return "厚的生面团" class Sauce: def to_string(self): pass class MarinaraSauce(Sauce): def to_string(self): return "番茄酱" class MushroomSauce(Sauce): def to_string(self): return "蘑菇酱" class Cheese: def to_string(self): pass class FreshCheese(Cheese): def to_string(self): return "新鲜的奶酪" class BlueCheese(Cheese): def to_string(self): return "蓝纹奶酪" class Clam: def to_string(self): pass class FreshClam(Clam): def to_string(self): return "新鲜的文蛤" class FrozenClam(Clam): def to_string(self): return "冷冻的文蛤" if __name__ == "__main__": # 创建了两个披萨实体店 ny_store = NYPizzaStore() chicago_store = ChicagoPizzaStore() # 在第一个披萨对象中订购了一个cheese风味的披萨 pizza = ny_store.order_pizza("cheese") print pizza.to_string() print "迈克订购了一个 %s" % pizza.get_name() print pizza = chicago_store.order_pizza("clam") print pizza.to_string() print "约翰订购了一个%s" % pizza.get_name()
结果:
准备: 纽约风格芝士披萨 烘烤25分钟在350。 切割成对角线切片。 放在官方的盒子中。 纽约风格芝士披萨: 面团: 薄的面团 酱汁: 番茄酱 奶酪: 新鲜的奶酪 迈克订购了一个 纽约风格芝士披萨 准备: 芝加哥风格文蛤披萨 烘烤25分钟在350。 切割成对角线切片。 放在官方的盒子中。 芝加哥风格文蛤披萨: 面团: 厚的生面团 酱汁: 蘑菇酱 文蛤: 冷冻的文蛤 约翰订购了一个芝加哥风格文蛤披萨

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











Linux 터미널에서 Python 버전을 보려고 할 때 Linux 터미널에서 Python 버전을 볼 때 권한 문제에 대한 솔루션 ... Python을 입력하십시오 ...

Python의 Pandas 라이브러리를 사용할 때는 구조가 다른 두 데이터 프레임 사이에서 전체 열을 복사하는 방법이 일반적인 문제입니다. 두 개의 dats가 있다고 가정 해

파이썬 프로그래밍에서 Python 매개 변수 주석의 대체 사용법, 매개 변수 주석은 개발자가 기능을 더 잘 이해하고 사용하는 데 도움이되는 매우 유용한 기능입니다 ...

Python 크로스 플랫폼 데스크톱 응용 프로그램 개발 라이브러리 선택 많은 Python 개발자가 Windows 및 Linux 시스템 모두에서 실행할 수있는 데스크탑 응용 프로그램을 개발하고자합니다 ...

파이썬에서 문자열을 통해 객체를 동적으로 생성하고 메소드를 호출하는 방법은 무엇입니까? 특히 구성 또는 실행 해야하는 경우 일반적인 프로그래밍 요구 사항입니다.

Python 스크립트는 특정 위치에서 Cursor 위치로 출력을 어떻게 제거합니까? Python 스크립트를 작성할 때 이전 출력을 커서 위치로 지우는 것이 일반적입니다 ...

Python : 모래 시계 그래픽 도면 및 입력 검증을 시작 하기이 기사는 모래 시계 그래픽 드로잉 프로그램에서 Python 초보자가 발생하는 변수 정의 문제를 해결합니다. 암호...

내 코드가 API에 의해 데이터를 반환 할 수없는 이유는 무엇입니까? 프로그래밍에서 우리는 종종 API가 호출 될 때 NULL 값을 반환하는 문제를 겪는 경우가 종종 있습니다.
