设计模式系列--Factory
写在开头:工厂模式是我们开发中最常用的模式,工厂模式又有三个不同的版本:简单工厂,工厂方法,抽象工厂,下面依次讲解。
一.类图
1. 简单工厂
2. 工厂方法
3. 抽象工厂
二.意图
1. 简单工厂
定义了一个用于创建对象的工具类,这个类包含特定的逻辑判断,可以决定什么时候创建一个产品。
2. 工厂方法
定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method 使一个类的实例化延迟到其子类。
3. 抽象工厂
供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
三.适用性
1. 简单工厂
a) 免除客户端创建类的责任,仅仅用于使用产品。
2. 工厂方法
a) 当一个类不知道它所必须创建的对象的类的时候。
b) 当一个类希望由它的子类来指定它所创建的对象的时候。
c) 当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候。
3. 抽象工厂
a) 一个系统要独立于它的产品的创建、组合和表示时。
b) 一个系统要由多个产品系列中的一个来配置时。
c) 当你要强调一系列相关的产品对象的设计以便进行联合使用时。
d) 当你提供一个产品类库,而只想显示它们的接口而不是实现时。
四.实例
例子还是用《乡村爱情》中的吧。这次例子的主人公是王小蒙家。看过《乡村爱情》的朋友都知道王小蒙家是卖豆腐的,那我们就从豆腐说起。
懂事孝顺的王小蒙"子承父业",继承了父亲买豆腐的行当。由于是山里的娃见识少,所以就是骑着一个三轮车在村子里吆喝。如果你想买豆腐直接把小蒙唤过来进行了。这就相当于简单工厂的模式,如果你想要豆腐,小蒙就会为你准备好。
自从和王兵见面后小蒙深有感触,这样骑着车卖豆腐什么时候是个头呀。"我要办一个豆腐加工厂"。最终小蒙的这个想法付诸实践,并且很成功,他生产的豆腐大批量的送往王兵的豆制品加工厂。这就相当于工厂方法模式,只不过是王小蒙的想法还很单一,这时她如果添加豆腐的品种,都很容易,比方说添加一个花生豆腐,这都很容易。因为她有了豆腐工厂。
"王兵可以办豆制品加工厂,为什么我不能呢?"。由于自己多年与豆腐打交道的经验,小蒙顺利的办起了豆制品加工厂。在原有的设备基础上上,小蒙还收购了王兵的先进的设备。原有的设备生产普通的产品,王兵的设备生产优质的产品。厂子办的红红火火。着就相当于抽象工厂模式,不仅有了工厂方法中豆腐的抽象,我们还对厂子进行了抽象,原有的工厂生产普通的产品,购买王兵的生产优质的产品。
1.简单工厂
package explore.simplefactory;
public class Tofu {
private int weight;
public Tofu() {
}
public Tofu(int weight) {
this.weight = weight;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
@Override
public String toString() {
return "一块" + weight + "斤的豆腐!";
}
}
package explore.simplefactory;
public class TofuFactory {
public static Tofu getTofu(int weight) {
if(weight > 0) {
return new Tofu(weight);
}
return null;
}
}
package explore.simplefactory;
public class Client {
public static void main(String[] args) {
Tofu t = TofuFactory.getTofu(3);
System.out.println(t);
}
}
2.工厂方法
package explore.factorymethod;
public abstract class Tofu {
private String metrial;
public Tofu() {}
public Tofu(String metrial) {
this.metrial = metrial;
}
@Override
public String toString() {
return metrial + "豆腐";
}
}
package explore.factorymethod;
public class PeanutTofu extends Tofu {
public PeanutTofu(String metrial) {
super(metrial);
}
public PeanutTofu() {
this("花生");
}
}
package explore.factorymethod;
public class SoybeanTofu extends Tofu {
public SoybeanTofu(String metrial) {
super(metrial);
}
public SoybeanTofu() {
this("黄豆");
}
}
package explore.factorymethod;
public interface TofuFactory {
public Tofu produce();
}
package explore.factorymethod;
public class SoybeanTofuFactory implements TofuFactory {
@Override
public Tofu produce() {
return new SoybeanTofu();
}
}
package explore.factorymethod;
public class PeanutTofuFactory implements TofuFactory {
@Override
public Tofu produce() {
return new PeanutTofu();
}
}
package explore.factorymethod;
public class Client {
public static void main(String[] args) {
//花生豆腐订单
int num1 = 20;
//黄豆豆腐订单
int num2 = 30;
TofuFactory pnFactory = new PeanutTofuFactory();
TofuFactory sbFactory = new SoybeanTofuFactory();
System.out.println("----------------第一笔订单开始----------------");
//生产第一笔订单
for(int i = 0; i < num1; i++) {
System.out.println("第" + i + "块" + pnFactory.produce());
}
System.out.println("----------------第一笔订单完成----------------");
System.out.println("----------------第二笔订单开始----------------");
//生产第二笔订单
for(int i = 0; i < num2; i++) {
System.out.println("第" + i + "块" + sbFactory.produce());
}
System.out.println("----------------第二笔订单完成----------------");
}
}
3.抽象工厂
package explore.abstractfactory;
public abstract class Tofu {
private String metrial;
private String quality;
public Tofu() {}
public Tofu(String metrial, String quality) {
this.metrial = metrial;
this.quality = quality;
}
@Override
public String toString() {
return quality + metrial + "豆腐";
}
}
package explore.abstractfactory;
public class PeanutTofu extends Tofu {
public PeanutTofu(String metrial, String quality) {
super(metrial, quality);
}
public PeanutTofu(String quality) {
this("花生", quality);
}
}
package explore.abstractfactory;
public class SoybeanTofu extends Tofu {
public SoybeanTofu(String metrial, String quality) {
super(metrial, quality);
}
public SoybeanTofu(String quality) {
this("黄豆", quality);
}
}
package explore.abstractfactory;
public interface TofuFactory {
public Tofu producePeanutTofu();
public Tofu produceSoybeanTofu();
}
package explore.abstractfactory;
public class HighQualityTofuFactory implements TofuFactory {
@Override
public Tofu producePeanutTofu() {
return new PeanutTofu("高质量的");
}
@Override
public Tofu produceSoybeanTofu() {
return new SoybeanTofu("高质量的");
}
}
package explore.abstractfactory;
public class NormalQualityTofuFactory implements TofuFactory {
@Override
public Tofu producePeanutTofu() {
return new PeanutTofu("普通的");
}
@Override
public Tofu produceSoybeanTofu() {
return new SoybeanTofu("普通的");
}
}
package explore.abstractfactory;
public class Client {
public static void main(String[] args) {
//高质量的花生豆腐订单
int num1 = 20;
//高质量的黄豆豆腐订单
int num2 = 30;
TofuFactory highQ = new HighQualityTofuFactory();
TofuFactory normalQ = new NormalQualityTofuFactory();
System.out.println("----------------第一笔订单开始----------------");
//生产第一笔订单
for(int i = 0; i < num1; i++) {
System.out.println("第" + i + "块" + highQ.producePeanutTofu());
}
System.out.println("----------------第一笔订单完成----------------");
System.out.println("----------------第二笔订单开始----------------");
//生产第二笔订单
for(int i = 0; i < num2; i++) {
System.out.println("第" + i + "块" + highQ.produceSoybeanTofu());
}
System.out.println("----------------第二笔订单完成----------------");
}
}
五.JDK中的工厂模式
工厂模式在JDK中的使用极其广泛,凡是我们看到valueOf,newInstance等方法字样基本上都使用了工厂模式。就不分析JDK的代码了,大家随便的看一下。