概述
工厂模式
- 简单工厂分类
- 1.普通简单工厂
- 2.多方法简单工厂
- 3.静态方法简单工厂
- 工厂方法模式
- 1.模式说明
- 2.开发实例
- 抽象工厂模式
- 1.模式特点
- 2.组成角色
- 3.开发实例
- 4.良好拓展性
工厂模式对将调用的方法或者通过new创建类对象的过程进行封装。就好像使用数据库中间件的过程,无需关心底层的实现,只需要将用户名和密码上传即可。
工厂模式的优点如下,
- 一个调用者想创建某个对象只需要知道名称即可
- 屏蔽具体的行为过程,调用者只需掌握接口方法,减轻负担
- 拓展性高,如果想增加一个类进入工厂,只需要拓展一个工厂类即可
从简单工厂引入,深入到工厂模式。
简单工厂分类
工厂模式分为3种,
- 普通简单工厂模式
- 多方法简单工厂
- 静态方法简单工厂
3种模式从上到下逐渐抽象,并更具一般性。以信息、快递和邮件的发送为例进行说明。
1.普通简单工厂
- 创建接口
三者共有的接口,
public interface Sender {
public void Send();
}
- 创建发送信息、邮件和快递的实现类,
public class EmailSender implements Sender{
@Override
public void send() {
System.out.println("发送邮件");
}
}
public class SmsSender implements Sender{
@Override
public void send() {
System.out.println("发送短信");
}
}
public class ExpressSender implements Sender{
@Override
public void send() {
System.out.println("发送快递");
}
}
- 创建普通简单工厂
public class SendFactory{
public Sender produce(String type) {
if (type == null)
return null;
else if ("email".equalsIgnoreCase(type))
return new EmailSender();
else if ("sms".equalsIgnoreCase(type))
return new SmsSender();
else if ("express".equalsIgnoreCase(type))
return new ExpressSender();
else
return null;
}
}
- 调用普通简单工厂
public class Main {
public static void main(String[] args) {
SendFactory sendFactory = new SendFactory();
Sender senderSms = sendFactory.produce("sms");
senderSms.Send(); // 发送短信
Sender senderEmail = sendFactory.produce("email");
senderEmail.Send(); // 发送邮件
Sender senderExpress = sendFactory.produce("express");
senderExpress.Send(); // 发送快递
}
}
- 小结
普通简单工厂在使用时,如果参数type
传递错误就无法正确创建对象。
2.多方法简单工厂
依旧使用普通简单工厂类中的3个Sender接口实现类。
- 基于普通简单工厂进行修改
只需要对SendFactory
类进行修改即可,
public class SendFactory {
public Sender produceSms(){
return new SmsSender();
}
public Sender produceEmail(){
return new EmailSender();
}
public Sender produceExpress() {
return new ExpressSender();
}
}
- 测试多方法简单工厂
public class Main {
public static void main(String[] args) {
SendFactory sendFactory = new SendFactory();
Sender senderEmail = sendFactory.produceEmail();
senderEmail.Send(); // 发送邮件
Sender senderSms = sendFactory.produceSms();
senderSms.Send(); // 发送短信
Sender senderExpress = sendFactory.produceExpress();
senderExpress.Send(); // 发送快递
}
}
- 小结
普通工厂模式和多方法工厂模式均存在一个弊端,即需要频繁实例化工厂类。
3.静态方法简单工厂
一般情况下会将多方法简单工厂中的创建实例的方法设置为静态,从而避免频发实例化工厂类。
- 测试静态方法简单工厂
public class Main {
public static void main(String[] args) {
Sender senderEmail = SendFactory.produceEmail();
senderEmail.Send(); // 发送邮件
Sender senderSms = SendFactory.produceSms();
senderSms.Send(); // 发送短信
Sender senderExpress = SendFactory.produceExpress();
senderExpress.Send(); // 发送快递
}
}
- 小结
静态方法简单工厂仍有明显的弊端,即工厂类中定义了所有市里的创建逻辑,违背高内聚的责任分配原则和闭包规则。
工厂方法模式
1.模式说明
工厂方法模式是简单工厂的延伸,将原先存在于一个工厂类中的逻辑抽调出来,创建一个接口和多个工厂类。
这种方式在拓展工厂功能时有很好的表现,无需修改之前的代码。
2.开发实例
基于简单工厂中创建的3个Sender
接口实现类进行开发。
- 统一工厂类的接口行为
public interface Provider {
public Sender produce();
}
- 实现3个工厂类并进行行为约束
public class EmailSendFactory implements Provider{
@Override
public Sender produce() {
return new EmailSender();
}
}
public class SmsSendFactory implements Provider{
@Override
public Sender produce() {
return new SmsSender();
}
}
public class ExpressSendFactory implements Provider{
@Override
public Sender produce() {
return new ExpressSender();
}
}
- 测试工厂模式
public class Main {
public static void main(String[] args) {
Provider providerSms = new SmsSendFactory();
Sender senderSms = providerSms.produce();
senderSms.Send(); // 发送短信
Provider providerEmail = new EmailSendFactory();
Sender senderEmail = providerEmail.produce();
senderEmail.Send(); // 发送邮件
Provider providerExpress = new ExpressSendFactory();
Sender senderExpress = providerExpress.produce();
senderExpress.Send(); // 发送快递
}
}
- 小结
上方的代码具体的好处在于拓展性。
1) 不要把焦点放在new
上面,这里的好处并不是new
不new
的问题。
2)真正的好处是,多方法简单工厂的最大弊端是:如果需要增加一个新的Sender
接口实现类,就不得不去修改工厂类SendFactory
的代码。
工厂类作为一个基础类尽量不要做改动。试想,如果每当要加一个实现类就改动工厂,工厂类不断膨胀,后期很难维护,要符合开闭原则。
如果用工厂方法就不一样了,对工厂进行接口化,并提供各Sender
接口实现类对应的工厂类。如果要新增实现类,就再扩展一个新的工厂,不会对接口进行改变。虽然调用过程中代码量多了,但是在实际业务中会极大的方便后期维护。这样是低耦合的,并且符合开闭原则。
抽象工厂模式
是最具抽象性和一般性的形态。可以像客户端提供一个接口,客户端无需指定产品的情况下,创建多个对象。
以电脑生产为例,比较工厂方法模式和抽象工厂模式,
模式 | 实现 |
---|---|
工厂方法模式 | 需要主板工厂、CPU工厂、显卡工厂等 |
抽象工厂模式 | 只有一个PC工厂,该工厂中再包含主板、显卡和CPU工厂 |
简言之,工厂方法模式的工厂类针对同一类产品;抽象工厂模式的工厂类针对多种类的产品。
1.模式特点
- 系统中有多个产品族,每个具体工厂负责创建同一族但是不同种类(产品等级)的产品。产品族和产品等级的概念如下,
- 系统一次只能消费某一产品族的产品
- 当系统需要新增一个产品族时,只需要增加新的工厂类即可,无需修改源代码;但是如果需要产品族中增加一个新种类的产品时,则所有的工厂类都需要修改
抽象工厂模式中的抽象工厂类的职责就是定义每个工厂要实现的功能,即定义多个产品族的产品的创建。这里,同一产品族下有多个产品时,对应的抽象工厂就会有多个抽象方法用来提供创建这些产品的接口。
2.组成角色
抽象工厂中的四种角色,
角色 | 说明 |
---|---|
抽象工厂 | 提供创建产品的接口,包含多个创建产品的方法,即包含多个类似的方法 |
具体工厂 | 实现抽象工厂定义的接口,完成具体产品的创建 |
抽象产品 | 一般有多少抽象产品,抽象工厂中就有多少个创建产品的方法 |
具体产品 | 抽象产品的实现类 |
3.开发实例
- 定义抽象工厂接口
public interface Factory {
Television newTelevision();
Refrigerator newRefrigerator();
}
- 定义抽象产品接口
public interface Television {
void dosomething();
}
public interface Refrigerator {
void dosomething();
}
- 实现具体工厂类
public class TCLFactory implements Factory {
@Override
public Television newTelevision() {
return new TCLTelevision();
}
@Override
public Refrigerator newRefrigerator() {
return new TCLRefrigerator();
}
}
public class MeiDFactory implements Factory {
@Override
public Television newTelevision() {
return new MeiDTelevision();
}
@Override
public Refrigerator newRefrigerator() {
return new MeiDRefrigerator();
}
}
- 实现具体产品类
public class TCLTelevision implements Television {
@Override
public void dosomething() {
System.out.println("我是TCL电视机,我可以看电视");
}
}
public class MeiDTelevision implements Television {
@Override
public void dosomething() {
System.out.println("我是美的电视机,我可以看电视");
}
}
public class TCLRefrigerator implements Refrigerator {
@Override
public void dosomething() {
System.out.println("我是TCL冰箱,我可以洗衣服");
}
}
public class MeiDRefrigerator implements Refrigerator {
@Override
public void dosomething() {
System.out.println("我是美的冰箱,我可以洗衣服");
}
}
- 测试
public class Main {
public static void main(String[] args) {
Factory factory = new TCLFactory();
Television television = factory.newTelevision();
Refrigerator refrigerator = factory.newRefrigerator();
television.dosomething(); // 我是TCL电视机,我可以看电视
refrigerator.dosomething(); // 我是TCL冰箱,我可以洗衣服
factory = new MeiDFactory();
television = factory.newTelevision();
refrigerator = factory.newRefrigerator();
television.dosomething(); // 我是美的电视机,我可以看电视
refrigerator.dosomething(); // 我是美的冰箱,我可以洗衣服
}
}
4.良好拓展性
- 新增产品族
假设某天新增海尔的电视机和冰箱,
体现了开闭原则,对修改关闭,对拓展开放。产品族拓展不需要修改源代码即可实现功能拓展。 - 新增产品等级
假设某天TCL和美的上新电风扇,
当需要增加一个新的产品时,所有的工厂类都需要进行修改,修改产品等级时,不满足开闭原则。所以,这也是抽象工厂的一个弊端。
最后
以上就是认真眼睛为你收集整理的创建型设计模式(1):工厂模式简单工厂分类工厂方法模式抽象工厂模式的全部内容,希望文章能够帮你解决创建型设计模式(1):工厂模式简单工厂分类工厂方法模式抽象工厂模式所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复