实现了创建者和调用者的分离。实例化对象,用工厂方法代替new操作。
主要分为三类:
简单工厂模式:不符合开闭原则,但是实际应用最多。
工厂方法模式:不修改已有类的前提下,增加新的工厂类进行扩展。
抽象工厂模式:不可以增加产品,可以增加产品族。
应用场景:spring中ioc创建管理bean对象。
简单工厂:
下面一个简单的场景,生产车,有CarA和CarB两种车。
public interface Car {
void run();
}
public class CarA implements Car {
@Override
public void run() {
System.out.println("CarA run!");
}
}
public class CarB implements Car {
@Override
public void run() {
System.out.println("CarB run!");
}
}
车工厂类
public class CarFactory {
//根据传入的类型创建车
public static Car createCar(String type){
if("A".equals(type)){
return new CarA();
}else if("B".equals(type)){
return new CarB();
}else{
return null;
}
}
//也可以多个方法返回不同的车
// public static CarA createCarA(){
// return new CarA();
// }
//
// public static CarB createCarB(){
// return new CarB();
// }
}
测试类
public class Test {
//没有使用工厂模式的时候创建对象
public static void main(String[] args) {
CarA carA = new CarA();
CarB carB = new CarB();
carA.run();
carB.run();
}
//使用简单工厂模式
// public static void main(String[] args) {
// Car carA = CarFactory.createCar("A");
// Car carB = CarFactory.createCar("B");
// carA.run();
// carB.run();
// }
}
从上面的例子可以看到利用简单工厂创建对象,但是如果我们增加新的类型的车,比如CarC,那么就要在原来类的基础上进行修改,这样违反了开闭原则。
接下来看一下工厂方法模式。
public interface CarFactory {
Car createCar();
}
CarA工厂类
public class CarAFactory implements CarFactory{
@Override
public Car createCar() {
return new CarA();
}
}
CarB工厂类
public class CarBFactory implements CarFactory{
@Override
public Car createCar() {
return new CarB();
}
}
public class Test {
public static void main(String[] args) {
Car carA = new CarAFactory().createCar();
Car carB = new CarBFactory().createCar();
carA.run();
carB.run();
}
}
上面我们可以看到,对于每一种车型建一个类,这样下次增加新的车型的时候,不用修改原来的代码,直接增加一个新的工厂类就行。
抽象工厂模式:
生产不同产品族的全部产品,不能增加新的产品。
下面的场景是不同的产品族,比如一个发动机和一个座位构成了一个产品族,发动机对应好和坏,座位对应好和坏。那么好的发动机和好的座位构成好的汽车,这是一种产品族,坏的发动机和坏的座位构成坏的汽车,这是一种产品族。这里就不能只生成一个发动机而不生成座位,这两个是绑定一起的。
public interface CarFactory {
Engine createEngine();
Seat createSeat();
}
发动机接口
public interface Engine {
void run();
void start();
}
class GoodEngine implements Engine{
@Override
public void run() {
System.out.println("转得快");
}
@Override
public void start() {
System.out.println("启动快");
}
}
class BadEngine implements Engine{
@Override
public void run() {
System.out.println("转得慢");
}
@Override
public void start() {
System.out.println("启动慢");
}
}
座位接口
public interface Seat {
void function();
}
class GoodSeat implements Seat{
@Override
public void function() {
System.out.println("可以拉伸");
}
}
class BadSeat implements Seat{
@Override
public void function() {
System.out.println("不能拉伸");
}
}
坏的汽车工厂类
public class BadCarFactory implements CarFactory {
@Override
public Engine createEngine() {
return new BadEngine();
}
@Override
public Seat createSeat() {
return new BadSeat();
}
}
好的汽车工厂类
public class GoodCarFactory implements CarFactory {
@Override
public Engine createEngine() {
return new GoodEngine();
}
@Override
public Seat createSeat() {
return new GoodSeat();
}
}
public class Test {
public static void main(String[] args) {
CarFactory carFactory = new GoodCarFactory();
Engine engine = carFactory.createEngine();
engine.start();
engine.run();
}
}
虽然上面说过简单工厂模式违背了开闭原则,但是确实我们实际运用最多的,很简单,我肯定愿意只修改一点代码,而不是新增一个类,类太多也没什么好处,难于管理。