简介
工厂模式就是 专门负责将大量有共同接口的类实例化,而且不必知道每次是要实例化哪一个类 的模式。
定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法让一个类的实例化延迟到其子类。
上面的话有些晦涩难懂,咱们接着往后看,后面继续理解这句话的含义。
工厂模式相当于创建实例对象的new关键字。
发展过程
举个例子,一辆车假设由发动机、车轮、底盘三部分组成,我们现在需要一辆车的实例,来看一段代码
class Engine {
public void getStyle() {
System.out.println("这是汽车的发动机");
}
}
class Underpan {
public void getStyle() {
System.out.println("这是汽车的底盘");
}
}
class Wheel {
public void getStyle() {
System.out.println("这是汽车的轮胎");
}
}
class Car implements ICar {
private Engine engine;
private Wheel wheel;
private Underpan underpan;
public Car(Engine engine, Wheel wheel, Underpan underpan) {
this.engine = engine;
this.wheel = wheel;
this.underpan = underpan;
}
@Override
public void show() {
System.out.println("This is your car");
}
}
public class Client {
public static void main(String[] args) {
Engine engine = new Engine();
Underpan underpan = new Underpan();
Wheel wheel = new Wheel();
ICar car = new Car(underpan, wheel, engine);
car.show();
}
}
对于客户端Client来说,获取一辆车Car的实例前,必须自己先获取Engine的实例、Underpan的实例、Wheel的实例。
相当于客户端自己组装了一辆车。于是客户端说了,我不想自己组装,来个工厂吧,工厂进行生产车,我直接从工厂获得。
所以产生了简单工厂模式。
简单工厂模式(静态方法工厂模式)
3个角色
● 产品接口:接口或抽象类,负责具体产品角色的定义。
● 产品实现:实现产品接口的具体类,决定了产品在客户端中的具体行为。
● 工厂类:提供具体产品实例的类,通常该方法都是静态方法。
还是上面的例子,Car还是由Engine、Underpan、Wheel组成。
产品接口:
public interface ICar {
void show();
}
产品实现:
public class Car implements ICar {
private Engine engine;
private Wheel wheel;
private Underpan underpan;
public Car(Engine engine, Wheel wheel, Underpan underpan) {
this.engine = engine;
this.wheel = wheel;
this.underpan = underpan;
}
@Override
public void show() {
System.out.println("This is your car");
}
}
工厂类:
public final class Factory {
public static ICar createCar() {
Engine engine = new Engine();
Wheel wheel = new Wheel();
Underpan underpan = new Underpan();
ICar car = new Car(engine, wheel, underpan);
return car;
}
}
接下来就可以调用了:
ublic class Client {
public static void main(String[] args) {
ICar car = Factory.createCar();
car.show();
}
}
大约为下图:
假设之前的场子是宝马厂子,只造宝马;现在需要一个能生产奔驰的厂子。
奔驰厂子和宝马厂子很像啊,怎么在原先的基础上增加一个厂子,而且对外的方法还是一样的呢?
接下来我们看工厂方法模式。
工厂方法模式
4个角色
● 产品接口:接口或抽象类,负责具体产品角色的定义。
● 产品实现:实现产品接口的具体类,决定了产品在客户端中的具体行为。
● 工厂接口:接口或抽象类,负责创建产品实例的抽象方法。
● 工厂实现:工厂的具体实现,创建产品实例的具体方法。
这里我们把奔驰厂子和宝马厂子要造车的接口抽取出成IFactory接口,然后宝马厂子造自己的宝马车,奔驰厂子造自己的奔驰车。
产品接口:
public interface ICar {
void show();
}
产品实现:
public class BmwCar implements ICar {
private Engine engine;
private Wheel wheel;
private Underpan underpan;
public BmwCar(Engine engine, Wheel wheel, Underpan underpan) {
this.engine = engine;
this.wheel = wheel;
this.underpan = underpan;
}
@Override
public void show() {
System.out.println("This is your BNW car");
}
}
public class BenzCar implements ICar {
private Engine engine;
private Wheel wheel;
private Underpan underpan;
public BenzCar(Engine engine, Wheel wheel, Underpan underpan) {
this.engine = engine;
this.wheel = wheel;
this.underpan = underpan;
}
@Override
public void show() {
System.out.println("This is your Benz car");
}
}
工厂接口:
public interface IFactory {
ICar createCar();
}
工厂实现:
public class BmwFactory implements IFactory {
@Override
public ICar createCar() {
Engine engine = new Engine();
Wheel wheel = new Wheel();
Underpan underpan = new Underpan();
ICar car = new BmwCar(engine, wheel, underpan);
return car;
}
}
public final class BenzFactory implements IFactory {
@Override
public ICar createCar() {
Engine engine = new Engine();
Wheel wheel = new Wheel();
Underpan underpan = new Underpan();
ICar car = new BenzCar(engine, wheel, underpan);
return car;
}
}
接下来就可以调用了:
public class Client {
public static void main(String[] args) {
BmwFactory bmwFactory = new BmwFactory();
ICar bmwCar = bmwFactory.createCar();
bmwCar.show();
BenzFactory benzFactory = new BenzFactory();
ICar benzCar = benzFactory.createCar();
benzCar.show();
}
}
这里BmwFactory造BmwCar,BenzFactory造BenzCar。如果之后新增法拉利厂子造法拉利的车,就可以直接增加对应的法拉利工厂类FerrariFactory和法拉利车类FerrariCar。
我们回顾一下开头的定义:定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法让一个类的实例化延迟到其子类。
● 定义一个用于创建对象的接口,就是上面的IFactory;
● 让子类决定,这里的子类就是BmwFactory和BenzFactory;
● 工厂方法让一个类的实例化延迟,一个类的实例化指的就是BmwCar的实例和BenzCar的实例。
如果所有造车的厂子,现在也可以造自行车系列了,我们希望把造自行车的方法也加到IFactory中。
接下来就有了抽象工厂模式
抽象工厂模式
角色和工厂方法模式一样,也是4个
产品接口,变成了两个,ICar和IBicycle:
public interface ICar {
void show();
}
public interface IBicycle {
void show();
}
产品实现:
public class BmwBicycle implements IBicycle {
@Override
public void show() {
System.out.println("This is your bicycle");
}
}
public class BmwCar implements ICar {
private Engine engine;
private Wheel wheel;
private Underpan underpan;
public BmwCar(Engine engine, Wheel wheel, Underpan underpan) {
this.engine = engine;
this.wheel = wheel;
this.underpan = underpan;
}
@Override
public void show() {
System.out.println("This is your BNW car");
}
}
工厂接口:
public interface IFactory {
ICar createCar();
IBicycle createBicycle();
}
工厂实现:
public class BmwFactory implements IFactory {
@Override
public ICar createCar() {
Engine engine = new Engine();
Wheel wheel = new Wheel();
Underpan underpan = new Underpan();
ICar car = new BmwCar(engine, wheel, underpan);
return car;
}
@Override
public IBicycle createBicycle() {
return new BmwBicycle();
}
}
客户端调用:
public class Client {
public static void main(String[] args) {
BmwFactory bmwFactory = new BmwFactory();
ICar bmwCar = bmwFactory.createCar();
bmwCar.show();
IBicycle bmwBicycle = bmwFactory.createBicycle();
bmwBicycle.show();
}
}
奔驰系列的类和宝马差不多哈,自己实现~~~
总结一下抽象工厂:为创建一组相关或相互依赖的对象提供一个接口。
工厂方法模式 和 抽象工厂模式 的区别
● 工厂方法模式针对的是一个产品等级结构,即提供的所有的产品都是衍生自一个接口或者抽象类
● 抽象工厂模式针对的是多个产品等级结构,即提供的产品衍生自不同的接口或者抽象类
工厂方法的优点
● 代码结构清晰
● 对调用者屏蔽具体的产品实现
● 降低耦合度