核心本质
1. 实例化对象:用工厂方法代替new操作
2. 将选择实现类、创建对象统一管理和控制。从而将调用者和我们的实现类解耦。
分类:
- 简单工厂模式:用来生产同一等级结构中的任意产品(对于新增加的产品,需要修改已有代码)
- 工厂方法模式:用来生产同一等级结构中的固定产品(支持增加任意产品)
- 抽象工厂模式:用于生产不同产品族的所有产品(支持增加产品族,对于新增加的产品无能为力)
无工厂情况
package com.ph.gof23.factory.simpleFactory;
public class NoFactoryDemo {
public static void main(String[] args) {
Byd c1 = new Byd();
Auid c2 = new Auid();
c1.run();
c2.run();
}
}
简单工厂模式(只有一个工厂类)
package com.ph.gof23.factory.simpleFactory;
public class SimpleFactory {
public static Car carFactory(String type){
if("奥迪".equals(type)){
return new Auid();
}else if("比亚迪".equals(type)){
return new Byd();
}else{
return null;
}
}
public static void main(String[] args) {
Car c1=SimpleFactory.carFactory("奥迪");
c1.run();
Car c2=SimpleFactory.carFactory("比亚迪");
c2.run();
}
}
优点:结构复杂度、客户端复杂度和代码复杂度占优
工厂方法模式(有一组实现了相同接口的工厂类)
创建一个抽象工厂(Creator)角色和抽象产品(Product)角色接口
package com.ph.gof23.factory.factoryMethod;
/**
* 抽象产品(Product)角色
* @author PangHao
*
*/
public interface Car {
void run();
}
package com.ph.gof23.factory.factoryMethod;
/**
* 抽象工厂(Creator)角色
* @author PangHao
*
*/
public interface CarFactory {
Car createCar();
}
为每一个产品增加一个工厂类该类实现了抽象工厂(Creator)角色和抽象产品(Product)角色接口
package com.ph.gof23.factory.simpleFactory;
/**
* 奥迪
* @author PangHao
*
*/
public class Auid implements Car{
@Override
public void run() {
System.out.println("Auid汽车");
}
}
package com.ph.gof23.factory.factoryMethod;
/**
* 奥迪工厂
* @author PangHao
*
*/
public class AuidFactory implements CarFactory{
@Override
public Car createCar() {
return new Auid();
}
}
通过产品的产品工厂类来创建产品
package com.ph.gof23.factory.factoryMethod;
public class FactoryMethodDemo {
public static void main(String[] args) {
Car c1 = new BydFactory().createCar();
Car c2 = new AuidFactory().createCar();
c1.run();
c2.run();
}
}
优点:符合开闭原则(ocp),通过增加新的工厂和产品来进行拓展,不需要修改已有的类
缺点:需要增加太多新的类,结构和代码太过复杂,编程难度高,不易于管理
抽象工厂模式
应用于存在多个产品族的场景
假设我们需要造一辆豪车和一辆破车,豪车和破车的部件的种类相同但是质量存在差异
那么首先,我们需要把豪车和破车的每个部件造出来
package com.ph.gof23.factory.abstraFactory;
/**
* 引擎
* @author PangHao
*
*/
public interface Engin {
void run();
void start();
}
//豪车
class LuxuryEngin implements Engin{
@Override
public void run() {
System.out.println("跑的贼快");
}
@Override
public void start() {
System.out.println("自动启停");
}
}
//破车
class LowEngin implements Engin{
@Override
public void run() {
System.out.println("跑的死慢");
}
@Override
public void start() {
System.out.println("自启不行但是有几率自停");
}
}
package com.ph.gof23.factory.abstraFactory;
/**
* 座椅
* @author PangHao
*
*/
public interface Seat {
void massage();
}
class LuxurySeat implements Seat{
@Override
public void massage() {
System.out.println("可以自动按摩");
}
}
class LowSeat implements Seat{
@Override
public void massage() {
System.out.println("硌屁股");
}
}
生产完了部件接下来我们需要在汽车工厂进行拼装
package com.ph.gof23.factory.abstraFactory;
/**
* 豪华车工厂
* @author PangHao
*
*/
public class LuxuryCarFactory implements CarFactory{
@Override
public Engin createEngin() {
return new LuxuryEngin();
}
@Override
public Tyre createTyre() {
return new LuxuryTyre();
}
@Override
public Seat createSeat() {
return new LuxurySeat();
}
}
package com.ph.gof23.factory.abstraFactory;
/**
* 破车工厂
* @author PangHao
*
*/
public class LowCarFactory implements CarFactory{
@Override
public Engin createEngin() {
return new LowEngin();
}
@Override
public Tyre createTyre() {
return new LowTyre();
}
@Override
public Seat createSeat() {
return new LowSeat();
}
}
完成拼装后我们就可以试验我们的新车了
package com.ph.gof23.factory.abstraFactory;
public class AbstractFactoryDemo {
public static void main(String[] args) {
CarFactory luxuryCarFactory = new LuxuryCarFactory();
Engin luxuryEngin = luxuryCarFactory.createEngin();
luxuryEngin.run();
luxuryEngin.start();
CarFactory lowCarFactory = new LowCarFactory();
Seat lowSeat = lowCarFactory.createSeat();
lowSeat.massage();
}
}
优点:
1、抽象工厂模式隔离了具体类的生产,使得客户并不需要知道什么被创建。
2、当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。
3、增加新的具体工厂和产品族很方便,无须修改已有系统,符合“开闭原则”。
缺点:
增加新的产品等级结构很复杂,需要修改抽象工厂和所有的具体工厂类,对“开闭原则”的支持呈现倾斜性。