设计模式-03工厂方法模式(Factory Method Pattern)
插曲.简单工厂模式(Simple Factory Pattern)
介绍工厂方法模式之前,先来做一个铺垫,了解一下简单工厂模式,它不属于 GoF 的 23 种经典设计模式,它的缺点是增加新产品时会违背“开闭原则”。
1.模式动机
考虑一个简单的软件应用场景,一个软件系统可以提供多个外观不同的按钮(如圆形按钮、矩形按钮、菱形按钮等),这些按钮都源自同一个基类,不过在继承基类后不同的子类有不同的实现方式从而使得它们可以呈现不同的外观,如果我们希望在使用这些按钮时,不需要知道这些具体按钮类的名字,只需要知道表示该按钮类的一个参数,并提供一个调用方便的方法,把该参数传入方法即可返回一个相应的按钮对象,此时,就可以使用简单工厂模式。
2.模式定义
简单工厂模式(Simple Factory Pattern):又称为静态工厂方法(Static Factory Method)模式,它属于类创建型模式。在简单工厂模式中,可以根据参数的不同返回不同类的实例。简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。
3.模式结构
这个模式结构有三种。
- 工厂角色:工厂角色负责实现创建所有实例的内部逻辑。
- 抽象产品角色:抽象产品角色是所创建的所有对象的父类,负责描述所有实例所共有的公共接口。
- 具体产品角色:具体产品角色是创建目标,所有创建的对象都充当这个角色的某个具体类的实例。
3.模式代码
先定义抽象产品角色,这里定义一个抽象的动物类。
public abstract class AbstractAnimal {
public abstract String say();
}
再定义具体产品角色,这里写了一个鸟一个猫的实现。
public class Bird extends AbstractAnimal {
@Override
public String say() {
return "I'm a bird.";
}
}
public class Cat extends AbstractAnimal {
@Override
public String say() {
return "I'm a cat.";
}
}
最后定义工厂类。
public class AnimalFactory {
public static AbstractAnimal create(String animalName) {
if ("cat".equals(animalName)) {
return new Cat();
} else if ("bird".equals(animalName)) {
return new Bird();
}
return null;
}
}
4.总结
简单工厂模式还是比较简单吧,虽然它不是 23 种设计模式中的一种,但是理解它可以帮助你理解本文的主角:工厂方法模式。
缺点
- 由于工厂类集中了所有产品创建逻辑,一旦不能正常工作,整个系统都要受到影响。
- 系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,在产品类型较多时,有可能造成工厂逻辑过于复杂,不利于系统的扩展和维护。
1.模式动机
现在对该系统进行修改,不再设计一个按钮工厂类来统一负责所有产品的创建,而是将具体按钮的创建过程交给专门的工厂子类去完成,我们先定义一个抽象的按钮工厂类,再定义具体的工厂类来生成圆形按钮、矩形按钮、菱形按钮等,它们实现在抽象按钮工厂类中定义的方法。这种抽象化的结果使这种结构可以在不修改具体工厂类的情况下引进新的产品,如果出现新的按钮类型,只需要为这种新类型的按钮创建一个具体的工厂类就可以获得该新按钮的实例,这一特点无疑使得工厂方法模式具有超越简单工厂模式的优越性,更加符合“开闭原则”。
2.模式定义
工厂方法模式(Factory Method Pattern)又称为工厂模式,它属于类创建型模式。在工厂方法模式中,工厂父类负责定义创建产品对象的公共接口,而工厂子类则负责生成具体的产品对象,这样做的目的是将产品类的实例化操作延迟到工厂子类中完成,即通过工厂子类来确定究竟应该实例化哪一个具体产品类。
3.模式结构
相对于简单工厂,无非是将工厂类拆分为抽象和具体了。
- 抽象工厂
- 具体工厂
- 抽象产品
- 具体产品
4.模式代码
先创建抽象工厂。
public abstract class AbstractAnimalFactory {
public abstract AbstractAnimal create();
}
再创建抽象产品。
public abstract class AbstractAnimal {
public abstract String say();
}
然后创建具体产品。
public class Bird extends AbstractAnimal {
@Override
public String say() {
return "I'm a bird.";
}
}
public class Cat extends AbstractAnimal {
@Override
public String say() {
return "I'm a cat.";
}
}
最后创建具体工厂。
public class BirdAnimalFactory extends AbstractAnimalFactory {
@Override
public AbstractAnimal create() {
return new Bird();
}
}
public class CatAnimalFactory extends AbstractAnimalFactory {
@Override
public AbstractAnimal create() {
return new Cat();
}
}
是不是理解了简单工厂模式,这个就很好理解了。
5.总结
- 在工厂方法模式中,核心的工厂类不再负责所有产品的创建,而是将具体创建工作交给子类去做。这个核心类仅仅负责给出具体工厂必须实现的接口,而不负责产品类被实例化这种细节,这使得工厂方法模式可以允许系统在不修改工厂角色的情况下引进新产品。
- 工厂方法模式的主要优点是增加新的产品类时无须修改现有系统,并封装了产品对象的创建细节,系统具有良好的灵活性和可扩展性;其缺点在于增加新产品的同时需要增加新的工厂,导致系统类的个数成对增加,在一定程度上增加了系统的复杂性。
设计模式-03工厂方法模式(Factory Method Pattern)的更多相关文章
- 乐在其中设计模式(C#) - 工厂方法模式(Factory Method Pattern)
原文:乐在其中设计模式(C#) - 工厂方法模式(Factory Method Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 工厂方法模式(Factory Method Pa ...
- 【设计模式】工厂方法模式 Factory Method Pattern
在简单工厂模式中产品的创建统一在工厂类的静态工厂方法中创建,体现了面形对象的封装性,客户程序不需要知道产品产生的细节,也体现了面向对象的单一职责原则(SRP),这样在产品很少的情况下使用起来还是很方便 ...
- 二十四种设计模式:工厂方法模式(Factory Method Pattern)
工厂方法模式(Factory Method Pattern) 介绍定义一个用于创建对象的接口,让子类决定将哪一个类实例化.Factory Method使一个类的实例化延迟到其子类. 示例有SqlMes ...
- 设计模式之工厂方法模式(Factory Method Pattern)
一.工厂方法模式的诞生 在读这篇文章之前,我先推荐大家读<设计模式之简单工厂模式(Simple Factory Pattern)>这篇文档.工厂方法模式是针对简单工厂模式中违反开闭原则的不 ...
- 【UE4 设计模式】工厂方法模式 Factory Method Pattern 及自定义创建资源
概述 描述 又称为工厂模式,也叫虚拟构造器(Virtual Constructor)模式,或者多态工厂(Polymorphic Factory)模式 工厂父类负责定义创建产品对象的公共接口,而工厂子类 ...
- 设计模式之 - 工厂方法模式 (Factory Method design pattern)
1. 模式意图: 定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类. 2. 别名(Virtual Constructor) 3. 结构 4. 工厂方法模式C ...
- C#设计模式——工厂方法模式(Factory Method Pattern)
一.概述在软件系统中,经常面临着“某个对象”的创建工作,由于需求的变化,这个对象的具体实现经常面临着剧烈的变化,但是它却拥有比较稳定的接口.如何应对这种变化?如何提供一种封装机制来隔离出“这个易变对象 ...
- 六个创建模式之工厂方法模式(Factory Method Pattern)
问题: 在使用简单工厂模式的时候,如果添加新的产品类,则必需修改工厂类,违反了开闭原则. 定义: 定义一个用于创建对象的接口,让子类决定具体实例化哪个产品类.此时工厂和产品都具有相同的继承结构,抽象产 ...
- 工厂方法模式(Factory Method Pattern)
工厂方法模式概述 工厂方法模式是为了弥补简单工厂模式的不足并且继承它的优点而延生出的一种设计模式,属于GoF中的一种.它能更好的符合开闭原则的要求. 定义:定义了一个用于创建对象的接口,但是让子类决定 ...
随机推荐
- C++Review7_STL、容器、迭代器
我之前的博文中有专门的5篇整理并介绍了STL的概念: STL1——整体介绍:https://www.cnblogs.com/grooovvve/p/10467794.html STL2——泛型编程(模 ...
- 图解Go里面的互斥锁mutex了解编程语言核心实现源码
1. 锁的基础概念 1.1 CAS与轮询 1.1.1 cas实现锁 在锁的实现中现在越来越多的采用CAS来进行,通过利用处理器的CAS指令来实现对给定变量的值交换来进行锁的获取 1.1.2 轮询锁 在 ...
- Kubernetes Clusters
1. 创建集群 Kubernetes集群 Kubernetes协调一个高可用的计算机集群,作为一个单独的单元来一起工作.有了这种抽象,在Kubernetes中你就可以将容器化的应用程序部署到集群中, ...
- JavaScript | 值传递、引用传递的区别
值传递 JavaScript值传递的数据类型:字符串(String).数字(Number).布尔(Boolean).空(Null).未定义(Undefined), 这五种数据类型是按值访问的,因为可以 ...
- 转载:通过监控Nginx日志来实时屏蔽高频恶意访问的IP
通过监控Nginx日志来实时屏蔽高频恶意访问的IP 目前在我的VPS上主要通过两种方式来限制ip的访问次数. 通过Nginx的limit_req配置来限制同一ip在一分钟内的访问次数 通过Ngin ...
- nginx部署vue跨域proxy方式
server { listen 80; charset utf-8; #server_name localhost; server_name you_h5_name; ###VUE项目H5域名 err ...
- 【题解】有标号的DAG计数3
[HZOI 2015] 有标号的DAG计数 III 我们已经知道了\(f_i\)表示不一定需要联通的\(i\)节点的dag方案,考虑合并 参考[题解]P4841 城市规划(指数型母函数+多项式Ln), ...
- 1037 在霍格沃茨找零钱 (20 分)C语言
题目描述 如果你是哈利·波特迷,你会知道魔法世界有它自己的货币系统 -- 就如海格告诉哈利的:"十七个银西可(Sickle)兑一个加隆(Galleon),二 十九个纳特(Knut)兑一个西可 ...
- C Primer Plus(二)
重读C Primer Plus ,查漏补缺 重读C Primer Plus,记录遗漏的.未掌握的.不清楚的知识点 分支和跳转 1.ctype.h头文件里包含了一些列用于字符判断的函数,包括判断数字.大 ...
- Nginx流量复制
1. 需求 将生产环境的流量拷贝到预上线环境或测试环境,这样做有很多好处,比如: 可以验证功能是否正常,以及服务的性能: 用真实有效的流量请求去验证,又不用造数据,不影响线上正常访问: 这跟灰度发布还 ...