一、简述
简单工厂模式属于创建型模式,是GOF23中较为容易上手的一种。在简单工厂中,工厂类会根据创建需求来创建不同的对象返回。
二、示例
以下是没有使用工厂模式的NoFactoryClient类
/**
* 没有使用工厂模式的Client
*/
public class NoFactoryClient {
public static void main(String[] args) {
Audi audi = new Audi();
audi.run();
}
}
奥迪和比亚迪类
/**
* 比亚迪类
*/
public class Byd{
public Byd() {
System.out.println("create a Byd");
}
public void run(){
System.out.println("Byd run");
}
}
/**
* 奥迪类
*/
public class Audi{
public Audi() {
System.out.println("create Audi");
}
public void run() {
System.out.println("Audi run");
}
}
这段代码是新手常用的创建对象的方式。虽说只有两行代码,但其中可圈可点。
其一、比如Audi audi = new Audi();这行代码,不管是奥迪还是比亚迪,他不都是车嘛,直接抽象出一个Car类,使用多态创建对象。这样做的好处是不管你究竟是什么对象,你只要是车就可以给我,我就可以调你的run方法,你具体是什么车我不管。
改进代码:根据面向对象OOP之封装与设计模式依赖倒置(面向接口编程)原则,奥迪类和比亚迪类都实现Car接口,客户端使用多态创建对象,此改进符合面相对象规范(我更愿把面向对象称为一种规范,规范就是你应尽你所能去遵守,例如法律就是一种规范)。
/**
* 车接口
*/
public interface Car {
//让车跑起来
void run();
}
/**
* 使用多态的Client
*/
public class Client {
public static void main(String[] args) {
Car car = new Audi();
car.run();
}
}
其二、在本例中体现不大,在真正的项目中创建一个对象会比创建一辆奥迪繁琐的多,比如所需的发动机的型号,轮胎的大小都是必要的。而针对这种现象,让客户端程序员创建对象显然是一种不合理的方式,这需要他知道的太多了。如果有一个工厂类帮助我们创建对象,客户端程序员只需要把要创建的对象以一种特定简便的方式来告诉工厂类,你来给我创建XXX对象,封装了复杂创建对象的工厂类会返回你所期望的对象。
/**
* 简单工厂实现
*/
public class CarFactory {
public static Car getCar(String type){
Car car;
switch (type) {
case "audi":
car = new Audi();
break;
case "byd":
car = new Byd();
break;
default :
car = null;
}
return car;
}
}
/**
* 使用简单工厂创建对象的客户端程序
*/
public class Client {
public static void main(String[] args) {
Car car = CarFactory.getCar("audi");
try{
car.run();
}catch (NullPointerException e) {
System.out.println("传入不正确的type");
}
}
}
三、简单工厂的UML类图
四、总结
优点:
1. 为创建复杂对象提供一种简便的方式去创建。
2. 区分了各类的职责,使程序更有结构化
缺点:
1. 不符合设计模式六大原则之一的开闭原则(对扩展打开,对修改关闭),在添加新产品时会修改工厂类原有代码。不过话虽如此,简单工厂的使用率仍然不低,在项目中很常见。
2. 很明显简单工厂类中集中了所有创建对象的逻辑,修改工厂类会很复杂。