设计模式(二):工厂模式
简单工厂
概述
简单工厂适用于工厂类负责创建的对象较少的场景,且客户端只需要传入工厂类的参数,对于如何创
建对象的逻辑不需要关心。
代码模拟
-
首先定义一个接口Car,包含一个drive的方法
public interface Car { void drive(); }
-
分别有两种车,实现了该接口
public class BaoMa implements Car { @Override public void drive() { System.out.println("宝马车行驶中"); } } public class Nissan implements Car { @Override public void drive() { System.out.println("尼桑车行驶中"); } }
-
然后创建一个工厂,专门用于根据用户输入获取对应的车
public class CarFactory { public Car createCar(String name){ if("BMW".equals(name)){ return new BaoMa(); } if("Nissan".equals(name)){ return new Nissan(); } return null ; } }
-
创建测试类
public class TestSimpleFactory { public static void main(String[] args) { CarFactory carFactory = new CarFactory(); carFactory.createCar("BMW").drive(); //控制台输出:宝马车行驶中 } }
总结
优点:简单,把创建对象的细节放入的工厂
缺点:创建对象时需要知道约定好的参数,例如获取宝马4S店的时候需要输入BMW
容易出错,扩展4S店的时候需要修改工厂类,增加业务判断逻辑。
改进:针对约定参数的问题,可以考虑用反射,减少出错的概率
public class CarFactoryPlus {
public Car createCar(Class<? extends Car> clz){
Car car = null;
try {
car = clz.newInstance();
} catch (Exception e) {
return null;
}
return car;
}
}
public class TestSimpleFactory {
public static void main(String[] args) {
CarFactoryPlus carFactoryPlus = new CarFactoryPlus();
//传入需要获取对象的类型
Car carPlus = carFactoryPlus.createCar(Nissan.class);
//控制台输出:尼桑车行驶中
carPlus.drive();
}
}
查漏补缺:CarFactoryPlus的createCar
方法一开始想写成<? implements Car>
但是编译不过,原来实现接口也可以用<? extends Car>
这种写法。
工厂模式
概述
定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类,工厂方法让类的实例化推迟到子类中进行。在工厂方法模式中用户只需要关心所需产品对应的工厂,无须关心创建细节,而且加入新的产品符合开闭原则。
工厂方法模式主要解决产品扩展的问题,在简单工厂中,随着产品链的丰富,如果每个产品的创建逻辑有区别的话,工厂的职责会变得越来越多,有点像万能工厂,并不便于维护。
代码模拟
//定义汽车工厂接口
public interface CarFactory {
Car createCar();
}
//宝马工厂单独生产宝马车
public class BaoMaFactory implements CarFactory{
@Override
public Car createCar() {
return new BaoMa();
}
}
//尼桑工厂专门生产Nissan车
public class NissanFactory implements CarFactory{
@Override
public Car createCar() {
return new Nissan();
}
}
//测试类
public class TestFuncFactory {
public static void main(String[] args) {
CarFactory baoMaFactory = new BaoMaFactory();
baoMaFactory.createCar().drive();
CarFactory nissanFactory = new NissanFactory();
nissanFactory.createCar().drive();
}
}
总结
简单工厂中一个工厂创造多种对象(CarFactory可以生产尼桑和宝马两种对象),工厂模式的核心在于定义工厂接口,CarFactory
定义工厂的规职责是创造汽车,然后再由具体的工厂(BaoMaFactory/NissanFactory
)实现接口创建指定对象,一种工厂创建一种对象,这样做的好处当然是职责明确,要什么对象就用什么工厂,要扩展的话只要去实现CarFactory就可以了。
抽象工厂模式
概述
抽象工厂模式(Abastract Factory Pattern)是指提供一个创建一系列相关或相互依赖对象的接口,无须指定他们具体的类。客户端(应用层)不依赖于产品类实例如何被创建、实现等细节,强调的是一系列相关的产品对象(属于同一产品族)一起使用创建对象需要大量重复的代码。需要提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于具体实现。
代码模拟
创建抽象工厂,定义一个产品族包括小轿车和suv,这就是一个工厂需要生产的产品族
public interface AbsCarFactory {
Suv createSuv();
Car createCar();
}
//定义新的产品SUV
public interface Suv {
void drive();
}
public class NissanSuv implements Suv{
@Override
public void drive() {
System.out.println("Nissan SUV 行驶中");
}
}
public class BaoMaSuv implements Suv{
@Override
public void drive() {
System.out.println("BMW SUV 行驶中");
}
}
两个工厂分别实现接口
public class BmwFactory implements AbsCarFactory{
@Override
public Suv createSuv() {
return new BaoMaSuv();
}
@Override
public Car createCar() {
return new BaoMa();
}
}
public class NissanFactory implements AbsCarFactory{
@Override
public Suv createSuv() {
return new NissanSuv();
}
@Override
public Car createCar() {
return new Nissan();
}
}
测试类
public class TestAbsFactory {
public static void main(String[] args) {
AbsCarFactory factory = new NissanFactory();
Car nissanCar = factory.createCar();
Suv nissanSuv = factory.createSuv();
nissanCar.drive();
nissanSuv.drive();
AbsCarFactory bmwFactory = new BmwFactory();
Car bmwCar = bmwFactory.createCar();
Suv bmwSuv = bmwFactory.createSuv();
bmwCar.drive();
bmwSuv.drive();
}
}
总结
抽象工厂的好处是一个工厂可以生产出一系列的产品。两个产品族是SUV和CAR,产品登记也分为宝马(A级车)和尼桑(B级车)。有这种特点的产品适合抽象工厂模式