工厂模式(Factory)
工厂模式:创建者(工厂)和调用者(用户)分离。
在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
开闭原则OCP(Open Closed Principle):软件实体(包括类、模块、功能等)应该对扩展开放,但是对修改关闭。
实例工厂:需要对工厂对象实例化,才能拿到对象。
静态工厂:不用创建工厂对象,即可拿到对象。
1、简单工厂模式
例子:Client通过CarFactory拿到具体的Car对象。
实现思路:Byd和Audi实现Car接口,CarFactory(工厂)中提供静态方法创建并放回具体的Car对象,Client( 用户)通过工厂拿到所需要的Car对象。
接口Car:
public interface Car { void run(); }
实现类Byd:
public class Byd implements Car{ @Override public void run() { System.out.println("Byd is running."); } }
实现类Audi:
public class Audi implements Car{ @Override public void run() { System.out.println("Audi is running."); } }
工厂CarFactory:
public class CarFactory{</span><span style="color: #008000;">//</span><span style="color: #008000;">通过车名拿车</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span><span style="color: #000000;"> Car creatCar(String name){ </span><span style="color: #0000ff;">if</span>(name.equals("奥迪"<span style="color: #000000;">)){ </span><span style="color: #0000ff;">return</span> <span style="color: #0000ff;">new</span><span style="color: #000000;"> Audi(); }</span><span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span>(name.equals("比亚迪"<span style="color: #000000;">)){ </span><span style="color: #0000ff;">return</span> <span style="color: #0000ff;">new</span><span style="color: #000000;"> Byd(); }</span><span style="color: #0000ff;">else</span><span style="color: #000000;"> { </span><span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span> RuntimeException("没有你输入的车!"<span style="color: #000000;">); } } </span><span style="color: #008000;">//</span><span style="color: #008000;">创建奥迪</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span><span style="color: #000000;"> Car creatAudi(){ </span><span style="color: #0000ff;">return</span> <span style="color: #0000ff;">new</span><span style="color: #000000;"> Audi(); } </span><span style="color: #008000;">//</span><span style="color: #008000;">创建比亚迪</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span><span style="color: #000000;"> Car creatByd(){ </span><span style="color: #0000ff;">return</span> <span style="color: #0000ff;">new</span><span style="color: #000000;"> Byd(); }
}
客户Client:通过车工厂拿到指定的车
public class Client{ public static void main(String[] args) { Car car1 = CarFactory.creatCar("奥迪"); Car car2 = CarFactory.creatByd(); car1.run(); car2.run(); } }
运行结果:
若要添加新的产品(车):需要新建Car的实现类、修改CarFactoy类的代码。不符合开闭原则(OCP)
2、工厂方法模式
例子:Client通过CarFactory的实现类拿到具体的Car对象。
实现思路:Byd和Audi实现Car接口,对应的车工厂(BydFactory、AudiFactory)实现CarFactory接口,工厂中提供方法creatCari()创建并放回具体的Car对象,Client( 用户)通过具体的工厂拿到所需要的Car对象。
接口Car及实现类Byd、Audi 不变。
CarFactory接口:
public interface CarFactory{ public Car creatCar(); }
BydFactory工厂:
public class BydFactroy implements CarFactory{ @Override public Car creatCar() { return new Byd(); } }
AudiFactory工厂:
public class AudiFactory implements CarFactory{ @Override public Car creatCar() { return new Audi(); } }
Client客户:通过指定的工厂获取车。
public class Client{ public static void main(String[] args) { Car car1 =new AudiFactory().creatCar(); Car car2 =new BydFactroy().creatCar(); car1.run(); car2.run(); } }
运行结果:
若要添加新的产品(车):需要新建Car的实现类、增加对应的CarFactory,不需要修改原有的代码。(符合OCP原则)
3、抽象工厂模式
它用于产品不是单个,是产品族的情况,各个部件合在一起变成一个产品。(比如一个补给包:里面有武器、食物、宠物。)
例子:Client通过SupplyPacksFactory的实现类拿到具体的宠物、食物、武器对象。
实现思路:
每个Pet、Foods、Firearms组成一个产品族,例如:高档的宠物、食物、武器组成一个高档物资包工厂(UpscaleSupplyPacksFactory)。
在SupplyPacksFactory(工厂)中创建相应的宠物、食物、武器。
比如:
客户需要一个高档的补给包。那么先创建一个UpscaleSuppluPacksFactory(高档包工厂),然后在工厂内创建具体的高档宠物、食物、武器。
客户需要一个低档的补给包。那么先创建一个LowSuppluPacksFactory(高档包工厂),然后在工厂内创建具体的低档宠物、食物、武器。
接口 Pet 及实现类:
public interface Pet { void brak();//发出声音 }class UpscalePet implements Pet{
@Override
public void brak() {
System.out.println("恶龙咆哮:嗷呜嗷呜~");
}
}class LowPet implements Pet{
@Override
public void brak() {
System.out.println("小猫咪:嘤嘤嘤~");
}
}
接口 Foods 及实现类:
public interface Foods { void eatFoods();//吃的东西 } //高档食物 class UpscaleFoods implements Foods{ @Override public void eatFoods() { System.out.println("各种好吃的!"); } } //低档食物 class LowFoods implements Foods{ @Override public void eatFoods() { System.out.println("只有菠萝味的压缩饼干~"); } }
接口 Firearms 及实现类:
public interface Firearms { void fire();//战斗 } //高档武器 class UpscaleFirearms implements Firearms{ @Override public void fire() { System.out.println("爷们要战斗!爷们要战斗!爷们要战斗!"); } } //低档武器 class LowFirearms implements Firearms{ @Override public void fire() { System.out.println("小圈圈锤你胸口"); } }
接口 SupplyPacksFactory 及实现类:
public interface SupplyPacksFactory { Foods creatFoods(); Pet creatPet(); Firearms creatFirearms(); } //高级背包:创建高档武器、食物、宠物 class UpscaleSupplyPacksFactory implements SupplyPacksFactory{@Override </span><span style="color: #0000ff;">public</span> Foods creatFoods() { <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">new</span><span style="color: #000000;"> UpscaleFoods(); } @Override </span><span style="color: #0000ff;">public</span> Pet creatPet() { <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">new</span><span style="color: #000000;"> UpscalePet(); } @Override </span><span style="color: #0000ff;">public</span> Firearms creatFirearms() { <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">new</span><span style="color: #000000;"> UpscaleFirearms(); }
}
//低级背包:创建低档武器、食物、宠物
class LowSupplyPacksFactory implements SupplyPacksFactory{@Override </span><span style="color: #0000ff;">public</span> Foods creatFoods() { <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">new</span><span style="color: #000000;"> LowFoods(); } @Override </span><span style="color: #0000ff;">public</span> Pet creatPet() { <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">new</span><span style="color: #000000;"> LowPet(); } @Override </span><span style="color: #0000ff;">public</span> Firearms creatFirearms() { <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">new</span><span style="color: #000000;"> LowFirearms(); }
}
用户来试试:
public class Client{ public static void main(String[] args) { //创建一个高档背包工厂 SupplyPacksFactory packsFactory = new UpscaleSupplyPacksFactory(); //从工厂里拿出高档武器 Firearms firearms = packsFactory.creatFirearms(); //试试武器 firearms.fire();</span><span style="color: #008000;">//</span><span style="color: #008000;">创建一个低档背包工厂</span> SupplyPacksFactory packsFactory1 = <span style="color: #0000ff;">new</span><span style="color: #000000;"> LowSupplyPacksFactory(); </span><span style="color: #008000;">//</span><span style="color: #008000;">拿个宠物出来</span> Pet pet =<span style="color: #000000;">packsFactory1.creatPet(); </span><span style="color: #008000;">//</span><span style="color: #008000;">试试宠物</span>
pet.brak();
//看看吃的
packsFactory1.creatFoods().eatFoods();}
}
运行结果:
若要添加新的产品族(补给包):新建对应的SupplyPacksFactory实现类即可,不需要修改原有的代码。(符合OCP原则)