Java 设计模式 之 工厂方法模式、抽象工厂模式
目录
工厂方法模式(Factory Method)
1、《简单工厂模式》有一个问题是“类的创建依赖工厂类,如果想要拓展程序,必须对工厂类进行修改”,这违背了闭包原则,所以从设计角度考虑,有一定的问题。
2、如何解决这个问题?就有了本节的工厂方法模式,创建一个工厂接口和多个工厂实现类,这样一旦需要增加新的功能,直接增加新的工厂类就可以了,不需要修改之前的代码。
3、下面开始实现上图的结构,Sender(发件人)接口如下:
package com.lct.factoryMethod;
/**
* Created by Administrator on 2019/4/7.
* 发件人
*/
public interface Sender {
/**
* 发送消息
*
* @param message
*/
void send(String message);
}
4、实现类 MailSender、SmsSender 如下:
package com.lct.factoryMethod;
import java.util.logging.Logger;
/**
* Created by Administrator on 2019/4/7.
* 邮件发送者
*/
public class MailSender implements Sender {
protected MailSender() {
}
@Override
public void send(String message) {
Logger logger = Logger.getAnonymousLogger();
logger.info(message);
}
}
package com.lct.factoryMethod;
import java.util.logging.Logger;
/**
* Created by Administrator on 2019/4/7.
* 短信发送者
*/
public class SmsSender implements Sender {
protected SmsSender() {
}
@Override
public void send(String message) {
Logger logger = Logger.getAnonymousLogger();
logger.info(message);
}
}
5、工厂接口 Provider 如下:
package com.lct.factoryMethod;
/**
* Created by Administrator on 2019/4/7.
* 供应商工厂接口
*/
public interface Provider {
Sender produce();
}
6、两个工厂类 SmsFactory、MailFactory 如下:
package com.lct.factoryMethod;
/**
* Created by Administrator on 2019/4/7.
* 工厂接口实现类
*/
public class MailFactory implements Provider {
@Override
public Sender produce() {
return new MailSender();
}
}
package com.lct.factoryMethod;
/**
* Created by Administrator on 2019/4/7.
* 工厂接口实现类
*/
public class SmsFactory implements Provider {
@Override
public Sender produce() {
return new SmsSender();
}
}
7、测试如下:
package com.lct.test;
import com.lct.factoryMethod.MailFactory;
import com.lct.factoryMethod.Provider;
import com.lct.factoryMethod.Sender;
import com.lct.factoryMethod.SmsFactory;
/**
* Created by Administrator on 2019/4/7.
*/
public class Test {
public static void main(String[] args) {
Provider mailFactory = new MailFactory();
Provider smsFactory = new SmsFactory();
Sender sender_mail = mailFactory.produce();
Sender sender_sms = smsFactory.produce();
sender_sms.send("今日高温红色预警.");
sender_mail.send("点击链接**邮件.");
}
}
这个模式的好处就是拓展性较好!比如果现在想增加一个功能:发及时信息,则只需做一个实现类,实现 Sender 接口,同时做一个工厂类,实现 Provider 接口,就 OK 了,无需去改动现成的代码。
抽象工厂模式(Abstract Factory)
1、 工厂方法模式特点:
1)一个抽象产品类,可以派生出多个具体产品类。如上面的 Sender 与 MailSender、SmsSender
2)一个抽象工厂类,可以派生出多个具体工厂类。如上面的 Provider 与 MailFactory、SmsFactory
3)每个具体工厂类只能创建一个具体产品类的实例。
2、抽象工厂模式特点:
1)多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。
2)一个抽象工厂类,可以派生出多个具体工厂类。
3)每个具体工厂类可以创建多个具体产品类的实例,也就是创建的是一个产品线下的多个产品。
3、工厂方法模式 VS 抽象工厂模式:
1)工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。
2)工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。
3)工厂方法创建 "一种" 产品,他的着重点在于"怎么创建",也就是说如果你开发,你的大量代码很可能围绕着这种产品的构造,初始化这些细节上面。也因为如此,类似的产品之间有很多可以复用的特征,所以会和模版方法相随。
4)抽象工厂需要创建一系列产品,着重点在于"创建哪些"产品上,也就是说,如果你开发,你的主要任务是划分不同差异的产品线,并且尽量保持每条产品线接口一致,从而可以从同一个抽象工厂继承。
4、对于 java 来说,见到的大部分抽象工厂模式是这样的: 它的里面是一堆工厂方法,每个工厂方法返回某种类型的对象。
5、举个例子:
比如说工厂可以生产鼠标和键盘,那么抽象工厂的实现类(它的某个具体子类)的对象都可以生产鼠标和键盘,但可能工厂A生产的是罗技的键盘和鼠标,工厂B是微软的。
这样A和B就是工厂,对应于抽象工厂,每个工厂生产的鼠标和键盘就是产品,对应于工厂方法。
用了工厂方法模式,替换生成键盘的工厂方法,就可以把键盘从罗技换到微软。但是用了抽象工厂模式,只要换家工厂,就可以同时替换鼠标和键盘一套。如果需要要的产品有几十个,当然用抽象工厂模式一次替换全部最方便(这个工厂会替你用相应的工厂方法)
6、所以说抽象工厂就像工厂,而工厂方法则像是工厂的一种产品生产线。
具体可以参考:http://www.runoob.com/design-pattern/abstract-factory-pattern.html