[Design Patterns] 01. Creational Patterns - Abstract Factory

设计模式是一套被反复使用、多数人知晓的、通过分类编目的、代码设计经验的总结,使用设计模式的目的是提升代码的可重用性,让代码更容易被他人理解,并保证代码可靠性。它是代码编制真正实现工程化。html

四个关键元素:(1) Pattern Name, (2) Problem, (3) Solution, (4) Consequences.sql

 

1、相关资源

From: 史上最全设计模式导学目录(完整版)数据库

Ref: 菜鸟教程之抽象工厂 json

六个建立型模式中的前三个。设计模式

 

简单工厂模式-Simple Factory Pattern【学习难度:★★☆☆☆,使用频率:★★★☆☆】安全

工厂三兄弟之简单工厂模式(一):图表库的设计函数

工厂三兄弟之简单工厂模式(二):简单工厂模式概述学习

工厂三兄弟之简单工厂模式(三):图表库的简单工厂模式解决方案spa

工厂三兄弟之简单工厂模式(四):图表库解决方案的改进,简单工厂模式的简化,简单工厂模式总结.net

 

工厂方法模式-Factory Method Pattern【学习难度:★★☆☆☆,使用频率:★★★★★】

工厂三兄弟之工厂方法模式(一):日志记录器的设计

工厂三兄弟之工厂方法模式(二):工厂方法模式概述

工厂三兄弟之工厂方法模式(三):日志记录器的工厂方法模式解决方案,反射与配置文件

工厂三兄弟之工厂方法模式(四):重载的工厂方法,工厂方法的隐藏,工厂方法模式总结

 

抽象工厂模式-Abstract  Factory Pattern【学习难度:★★★★☆,使用频率:★★★★★】

工厂三兄弟之抽象工厂模式(一):界面皮肤库的初始设计

工厂三兄弟之抽象工厂模式(二):产品等级结构与产品族

工厂三兄弟之抽象工厂模式(三):抽象工厂模式概述

工厂三兄弟之抽象工厂模式(四):界面皮肤库的抽象工厂模式解决方案

工厂三兄弟之抽象工厂模式(五):“开闭原则”的倾斜性,抽象工厂模式总结

 

Abstract Factory Pattern 是重难点

一个工厂通常会生产一系列具备相关性的产品,即产品族

在不一样的工厂(大环境下)可能生产同一系列的产品族,具备类似的产品等级结构

 

 

2、举个栗子

工厂方法 - 支持处理不一样的文件格式

首先,“链接数据库” 的过程是对外“屏蔽的“;

接着,获得的工厂所包含的方法是统一的。这里对于静态语言而言,每每经过接口实现。

def main():

# 但愿 connect_to 能够处理各类数据库文件,那就返回合适的工厂 # 而工厂实际上是“包含了许多方法”的集合,也就是一个特殊的类 sqlite_factory = connect_to('data/person.sq3') print() xml_factory = connect_to('data/person.xml') xml_data = xml_factory.parsed_data
liars
= xml_data.findall(".//{}[{}='{}']".format('person', 'lastName', 'Liar')) print('found: {} persons'.format(len(liars))) for liar in liars: print('first name: {}'.format(liar.find('firstName').text)) print('last name: {}'.format(liar.find('lastName').text)) [print('phone number ({})'.format(p.attrib['type']), p.text) for p in liar.find('phoneNumbers')] print() json_factory = connect_to('data/donut.json') json_data = json_factory.parsed_data
print('found: {} donuts'.format(len(json_data))) for donut in json_data: print('name: {}'.format(donut['name'])) print('price: ${}'.format(donut['ppu'])) [print('topping: {} {}'.format(t['id'], t['type'])) for t in donut['topping']]

 

factory 等价于 connection_factory(filepath) 初始化了一个 ”特定的类“。

同时也就意味着:添加一个产品须要修改下面的函数,这不是很符合“开闭原则”。

# factory:根据参数返回合适的工厂产品
def connection_factory(filepath):
    if filepath.endswith('json'):
        connector = JSONConnector
    elif filepath.endswith('xml'):
        connector = XMLConnector
    else:
        # 由于有“为保证安全”的connect_to层
        raise ValueError('Cannot connect to {}'.format(filepath))
  
# 这里返回的已是一个”实例”
return connector(filepath) # 看上去像是专门为了factory变量的安全考虑 def connect_to(filepath): factory = None try: factory = connection_factory(filepath) # 简单模式下,只有一个工厂 except ValueError as ve: print(ve) return factory

 

  

3、提出问题

类图符号的学习,参考:类图

类名(Class):每一个类都必须有一个名字,类名是一个字符串。
属性(Attributes):属性是指类的性质,即类的成员变量。类能够有任意多个属性,也能够没有属性。
操做(Operations):操做是类的任意一个实例对象均可以使用的行为,操做是类的成员方法。

 

关联关系 (Association)

将一个类的对象做为另外一个类的属性。

单向关联

在这里插入图片描述

 

双向关联

在这里插入图片描述

 

多重性关联关系

在这里插入图片描述

  

聚合关系 (Aggregation) 组合关系 (Composition)

前者是弱关系;后者是强关系;

组合关系,表示总体与部分的关系。

可是与聚合不一样此关系是总体与部分是同生共死关系,即若是总体对象销毁了部分也会被销毁。

在这里插入图片描述

在这里插入图片描述

 

依赖关系 (Dependency)

Driver是一个总体,Car也是总体,不是总体与部分关系。

可是,Driver中使用了Car的move方法,从而造成了“依赖关系”。

在这里插入图片描述

 

泛化关系 (Generalization)

继承(extends)关系,父类与子类关系。

在这里插入图片描述

 

实现关系 (Realization)

类实现(implements)了接口。当多个类有相似的行为方式的时候咱们一般会使用接口。

在这里插入图片描述

  

 

4、再举个栗子

抽象工厂 

首先,“游戏开始play” 的过程是对外“屏蔽的“;

接着,获得的工厂所包含的方法是统一的。这里对于静态语言而言,每每经过接口实现。

class GameEnvironment:  # 工厂类 def __init__(self, factory):
        self.hero     = factory.make_character()
        self.obstacle = factory.make_obstacle()

    def play(self):
        self.hero.interact_with(self.obstacle)  # 创建好产品之间的关系

def main(): name = input("Hello. What's your name? ") valid_input = False while not valid_input: valid_input, age = validate_age(name) game = FrogWorld if age < 18 else WizardWorld  # <---- 关键的一个句子 environment = GameEnvironment(game(name)) # <---- 抽象工厂的"工厂"是"类";参数是类的类! environment.play()

 

Goto: 抽象工厂模式和工厂模式的区别?【三种枪的例子比较不错】

重要的两个问题:

    1. 增长一个新工厂,只要实现这个类便可。
    2. 增长一个新产品 ,只要为类添加新方法便可。

 

抽象工厂的工厂是类;工厂方法的工厂是方法。

抽象工厂的工厂类就作一件事情生产产品。生产的产品给客户端使用,毫不给本身用。

 

普通工厂产出是一个产品(实例),抽象工厂产出是一个抽象(接口)。

区别在于,若添加一个新的产品,前者是修改工厂,后者是建立新工厂(符合“闭合原则”)。

其实,抽象工厂多了一个“抽象的部分”从而间接调用“参数类(产品)”的方法。

 

 End.

相关文章
相关标签/搜索