1.简单工厂
先来一个简单工厂的示例:
import java.util.Objects;
public class SimpleFactoryMain {
/**
* Car接口
*/
interface Car {
/**
* 行驶
*/
void run();
}
/**
* 奥迪车
*/
static class AudiCar implements Car {
@Override
public void run() {
System.out.println("奥迪车行驶速度150km/h");
}
}
/**
* 保时捷
*/
static class PorscheCar implements Car {
@Override
public void run() {
System.out.println("保时捷行驶速度200km/h");
}
}
/**
* 工厂接口
*/
interface CarFactory {
Car create(String name);
}
/**
* 工厂类实现
*/
static class DefaultCarFactory implements CarFactory {
/**
* 优点:
* 对外屏蔽具体的实现细节,外界不需要关心里面的实现逻辑,使用者只需要放心的使用
* 将生产者和消费者进行责任分割
*
* 缺点:
* 无法灵活地应对产品的增加,比如后面需要增加其他的Car,无法避免修改代码的情况下实现功能,
* 而且会造成整个实现方法越来越复杂,直至无法维护
* @param name
* @return
*/
@Override
public Car create(String name) {
if (Objects.equals(name, "Audi")) {
return new AudiCar();
} else if (Objects.equals(name, "Porsche")) {
return new PorscheCar();
}
return null;
}
}
/**
* 主函数
*
* @param args
*/
public static void main(String[] args) {
CarFactory carFactory = new DefaultCarFactory();
Car car = carFactory.create("Audi");
car.run();
car = carFactory.create("Porsche");
car.run();
}
}
关于简单工厂在java中的使用,可以查看DateFormat类中的getTimeInstance()和getDateInstance()一系列方法,这是一个典型的简单工厂模式在java中的应用。DateFormat使用静态工厂方法,运用java的多态特性,如图:
//不需要关心子类SimpleDateFormat的创建细节,只需要通过静态工厂方法创建即可
DateFormat dateFormat = DateFormat.getDateInstance();
正是因为简单工厂的缺点,使用一个工厂类无法应对多样的产品变化,导致代码的维护越来越困难,脱离了设计模式的初衷。所以针对后期可能出现的多样产品,我们尝试使用一下工厂方法解决问题。
2.工厂方法
代码示例:
public class FactoryMain {
/**
* Car接口
*/
interface Car {
/**
* 行驶
*/
void run();
}
/**
* 奥迪车
*/
static class AudiCar implements Car {
@Override
public void run() {
System.out.println("奥迪车行驶速度150km/h");
}
}
/**
* 保时捷
*/
static class PorscheCar implements Car {
@Override
public void run() {
System.out.println("保时捷行驶速度200km/h");
}
}
/**
* 工厂接口
*/
interface CarFactory {
/**
* 生产车
*
* @return
*/
Car create();
}
/**
* 奥迪工厂类实现
*/
static class AudiCarFactory implements CarFactory {
/**
* @return
*/
@Override
public Car create() {
return new AudiCar();
}
}
/**
* 保时捷工厂类实现
*/
static class PorscheCarFactory implements CarFactory {
/**
* @return
*/
@Override
public Car create() {
return new PorscheCar();
}
}
/**
* 主函数
*
* @param args
*/
public static void main(String[] args) {
//奥迪车工厂
CarFactory carFactory1 = new AudiCarFactory();
Car car = carFactory1.create();
car.run();
/**
* 保时捷工厂
*/
CarFactory carFactory2 = new PorscheCarFactory();
car = carFactory2.create();
car.run();
}
}
基于工厂方法的设计思想,即使有再多的产品需要加入进来,也是可以通过不断地创建对应的工厂类进行生产,完全不需要担心修改或维护非常复杂的创建逻辑。
工厂方法在jdk中的应用:
// 所有实现Collection接口的实现类都需要实现iterator()方法
// 不同的子类需要创建不同的Iterator子类
public interface Collection<E> extends Iterable<E> {
Iterator<E> iterator();
}
3.抽象工厂
工厂方法和抽象工厂最大的区别在于,工厂方法针对于一个产品等级结构,而抽象工厂针对于多个产品等级结构。
public class AbstractFactoryMain {
/**
* Car接口
*/
interface Car {
/**
* 行驶
*/
void run();
}
/**
* 奥迪车
*/
static class AudiCar implements Car {
@Override
public void run() {
System.out.println("奥迪车行驶速度150km/h");
}
}
/**
* 保时捷
*/
static class PorscheCar implements Car {
@Override
public void run() {
System.out.println("保时捷行驶速度200km/h");
}
}
/**
* 发动机
*/
interface Engine {
void run();
}
/**
* 奥迪发动机
*/
static class AudiEngine implements Engine {
@Override
public void run() {
System.out.println("奥迪发动机在运行");
}
}
/**
* 保时捷发动机
*/
static class PorscheEngine implements Engine {
@Override
public void run() {
System.out.println("保时捷发动机在运行");
}
}
/**
* 工厂接口
*/
interface CarFactory {
/**
* 生产车
*
* @return
*/
Car createCar();
/**
* 生产发动机
*
* @return
*/
Engine createEngine();
}
/**
* 奥迪工厂类实现
*/
static class AudiCarFactory implements CarFactory {
/**
* @return
*/
@Override
public Car createCar() {
return new AudiCar();
}
@Override
public Engine createEngine() {
return new AudiEngine();
}
}
/**
* 保时捷工厂类实现
*/
static class PorscheCarFactory implements CarFactory {
/**
* @return
*/
@Override
public Car createCar() {
return new PorscheCar();
}
@Override
public Engine createEngine() {
return new PorscheEngine();
}
}
/**
* 主函数
*
* @param args
*/
public static void main(String[] args) {
//奥迪车工厂
CarFactory carFactory1 = new AudiCarFactory();
Car car = carFactory1.createCar();
car.run();
Engine engine1 = carFactory1.createEngine();
engine1.run();
/**
* 保时捷工厂
*/
CarFactory carFactory2 = new PorscheCarFactory();
car = carFactory2.createCar();
car.run();
Engine engine2 = carFactory2.createEngine();
engine2.run();
}
}
从以上代码中可以看出,抽象工厂已经不仅仅是应对一类产品的变化了,它可以同时应对多类产品的变化。
以上是我对于简单工厂,工厂方法和抽象工厂的简单理解和认识,谢谢!
网友评论