咱们常说的工厂模式并非一种具体的设计模式。在「GoF设计模式(23种经典设计模式)」里,具体的“工厂模式”是指:工厂方法模式(Factory Method Pattern)和抽象工厂模式(Abstract Factory Pattern)。但咱们常把简单工厂模式(Simple Factory Pattern)、工厂方法模式、抽象工厂模式统一称为工厂模式。编程
简单工厂也叫静态工厂。简单工厂模式并非一种设计模式,或者说它不在Gof概括的设计模式里。它是咱们的一种设计方法。当咱们建立对象时,通常经过new的方式建立,而这种方式建立就是面向实现方式编程(当咱们对象已经肯定时,相关的功能就已经肯定了)。设计模式
使用简单工厂模式建立对象的好处:markdown
简单方便获取对象app
可使建立对象的细节与业务代码分割开来,封装并隐藏对象建立的细节ide
建立对象的方式修改了,只须要修改工厂里的方法,而不须要在每一个调用方修改。ui
简单工厂方法实现起来,很是简单:lua
// 抽象产品接口
public interface IProduct {
void display();
}
复制代码
//产品A
public class AProduct implements IProduct {
@Override
public void display() {
System.out.println("我是A产品");
}
}
复制代码
// 产品B
public class BProduct implements IProduct {
@Override
public void display() {
System.out.println("我是B产品");
}
}
复制代码
// 简单工厂
public class SimpleFactory {
public static IProduct createProduct(String type) {
if ("A".equals(type)) {
return new AProduct();
}
if ("B".equals(type)) {
return new BProduct();
}
return null;
}
public static void main(String[] args) {
// A产品
IProduct aProduct = SimpleFactory.createProduct("A");
aProduct.display();
// B产品
IProduct bProduct = SimpleFactory.createProduct("B");
bProduct.display();
}
}
输出结果:
我是A产品
我是B产品
复制代码
简单工厂实现起来很简单,但也有必定弊端,主要是违法了开闭原则(对扩展开放,对修改关闭),当须要增长新的产品时,咱们须要修改简单工厂里的静态方法。url
工厂方法模式(Factory Method Pattern):定义一个用于建立对象的接口,让子类决定将哪个类实例化。工厂方法模式让一个类的实例化延迟到其子类。spa
工厂方法模式包含四种角色:抽象产品,具体产品,抽象工厂,具体工厂设计
具体产品(具体对象),由具体工厂方法建立。
用代码演示以下
// 抽象产品
public interface IProduct {
void display();
}
复制代码
//具体产品A
public class AProduct implements IProduct {
@Override
public void display() {
System.out.println("我是A产品");
}
}
复制代码
// 具体产品B
public class BProduct implements IProduct {
@Override
public void display() {
System.out.println("我是B产品");
}
}
复制代码
// 抽象工厂
public interface IProductFactory {
IProduct createProduct();
}
复制代码
// 具体工厂A
public class ProductAFactory implements IProductFactory {
@Override
public IProduct createProduct() {
return new AProduct();
}
}
复制代码
// 具体工厂B
public class ProductBFactory implements IProductFactory {
@Override
public IProduct createProduct() {
return new BProduct();
}
}
复制代码
// 客户端演示
public class Client {
public static void main(String[] args) {
// A产品工厂
IProductFactory aProductFactory = new ProductAFactory();
// 建立A产品
IProduct aProduct = aProductFactory.createProduct();
aProduct.display();
// B产品工厂
IProductFactory bProductFactory = new ProductBFactory();
// 建立B产品
IProduct bProduct = bProductFactory.createProduct();
bProduct.display();
}
}
输出结果:
我是A产品
我是B产品
复制代码
若是咱们须要新增「产品C」,只须要增长一个「产品C」的实现类和「产品C」的具体工厂。
工厂方法模式相对简单工厂方法来讲,主要是实现了对修改关闭(若要修改,只须要新增一个子类)。
工厂方法模式中的「让一个类的实例化延迟到其子类」,是增长系统扩展性的重要方式。
固然,从演示代码来看,在添加新产品时,须要编写新的具体产品类,并且还要提供与之对应的具体工厂类,系统中类的个数将成对增长,在必定程度上增长了系统的复杂度,有更多的类须要编译和运行,会给系统带来一些额外的开销。
抽象工厂模式提供一个建立一系列相关或相互依赖对象的接口。
抽象工厂模式与工厂方法相似,都是经过具体工厂来建立具体产品。但抽象工厂不是创造一类产品(全部具体产品都是实现(继承)同一个抽象产品,因此归为一类产品),而是建立一系列相关或相互依赖的产品。什么是一系列或相互依赖的产品来讲呢?举一个现实中例子,冰箱是一类产品,实际有海尔冰箱、美的冰箱等。而一系列产品就是同一品牌下的不一样产品,好比海尔系列的:海尔冰箱、海尔空调、海尔洗衣机;美的系列的:美的冰箱、美的空调、美的洗衣机。一般,一系列的产品也被称为“产品族”
用代码演示抽象工厂演示以下:
// 抽象卡券
public interface ICard {
void display();
}
复制代码
// 抽象产品
public interface IProduct {
void display();
}
复制代码
// A系列产品
public class AProduct implements IProduct {
@Override
public void display() {
System.out.println("我是A产品");
}
}
复制代码
// A系统卡券
public class ACard implements ICard {
@Override
public void display() {
System.out.println("我是A卡券");
}
}
复制代码
// B系列产品
public class BProduct implements IProduct {
@Override
public void display() {
System.out.println("我是B产品");
}
}
复制代码
// B系列卡券
public class BCard implements ICard {
@Override
public void display() {
System.out.println("我是B卡券");
}
}
复制代码
// 抽象工厂,建立相互依赖或相关的产品
public interface AbstractFactory {
/**
* 建立商品
* @return
*/
IProduct createProduct();
/**
* 建立卡券
* @return
*/
ICard createCard();
}
复制代码
// A系列工厂
public class AFactory implements AbstractFactory {
@Override
public IProduct createProduct() {
return new AProduct();
}
@Override
public ICard createCard() {
return new ACard();
}
}
复制代码
// B系列工厂
public class BFactory implements AbstractFactory {
@Override
public IProduct createProduct() {
return new BProduct();
}
@Override
public ICard createCard() {
return new BCard();
}
}
复制代码
// 客户端
public class Client {
public static void main(String[] args) {
// A系统产品
AbstractFactory aFactory = new AFactory();
IProduct aProduct = aFactory.createProduct();
ICard aCard = aFactory.createCard();
aProduct.display();
aCard.display();
// B系列产品
AbstractFactory bFactory = new BFactory();
IProduct bProduct = bFactory.createProduct();
ICard bCard = bFactory.createCard();
bProduct.display();
bCard.display();
}
}
输出结果:
我是A产品
我是A卡券
我是B产品
我是B卡券
复制代码
抽象工厂能够建立一系列产品,但其有一个弊端,在产品族中新增一个产品,其全部具体工厂,都须要从新实现一个建立新产品的方法。