工厂模式细分下来有三大类:简单工厂、工厂方法、抽象工厂
简单工厂模式
准确的说简单工厂不是一个模式,而是一种编程习惯。
由三种角色组成:
工厂角色:这是本模式的核心,含有一定的商业逻辑和判断逻辑。在java中它往往由一个具体类实现。
抽象产品角色:它一般是具体产品继承的父类或者实现的接口。在java中由接口或者抽象类来实现。
具体产品角色:工厂类所创建的对象就是此角色的实例。在java中由一个具体类实现。
例子如下:
我们需要造3种不同的车(电车,油车,混动车),用户自行指定需要什么车,就给用户创建什么车的对象。
车的对象接口
public interface Car {
public void createCar();
}
创建车的类型,并实现接口
public class DCar implements Car{
@Override
public void createCar() {
System.out.println("造出电车");
}
}
public class FCar implements Car{
@Override
public void createCar() {
System.out.println("造出混动车");
}
}
public class YCar implements Car{
@Override
public void createCar() {
System.out.println("造出油车");
}
}
工厂类
public class CarFactory {
public Car CreateCar(String CarName){
Car car=null;
switch (CarName){
case "油车":
car=new YCar();
break;
case "电车":
car=new DCar();
break;
case "混动车":
car=new FCar();
break;
}
return car;
}
}
测试类
public class TestCar {
public static void main(String[] args) {
CarFactory carFactory=new CarFactory();
Car car=carFactory.CreateCar("混动车");
car.createCar();
}
}
测试结果
造出混动车
优点:
将创建实例的工作与使用实例的工作分开,实现了解耦;
把初始化实例时的工作放到工厂里进行,使代码更容易维护。 更符合面向对象的原则 。
缺点:
工厂类集中了所有实例的创建逻辑,一旦这个工厂不能正常工作,整个系统都会受到影响;
违背“开放 - 关闭原则”,一旦添加新产品就不得不修改工厂类的逻辑,这样就会造成工厂逻辑过于复杂。
工厂方法模式
作用:将类的实例化(具体产品的创建)延迟到工厂类的子类(具体工厂)中完成,即由子类来决定应该实例化(创建)哪一个类。
由四种角色组成:
抽象工厂角色:这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。在java中它由抽象类或者接口来实现。
具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。在java中它由具体的类来实现。
抽象产品角色:它是具体产品继承的父类或者是实现的接口。在java中一般有抽象类或者接口来实现。
具体产品角色:具体工厂角色所创建的对象就是此角色的实例。在java中由具体的类来实现。
例子还是接着我们上面的实例
车的接口
public interface Car {
public void createCar();
}
车的类型,实现接口
public class DCar implements Car{
@Override
public void createCar() {
System.out.println("造出电车");
}
}
public class FCar implements Car{
@Override
public void createCar() {
System.out.println("造出混动车");
}
}
public class YCar implements Car{
@Override
public void createCar() {
System.out.println("造出油车");
}
}
我们的车类工厂改为接口
public interface CarFactory {
public Car createCar();
}
我们创建个个汽车的工厂类来实现接口
public class DCarFactory implements CarFactory {
@Override
public Car createCar() {
return new DCar();
}
}
public class FCarFactory implements CarFactory {
@Override
public Car createCar() {
return new FCar();
}
}
public class YCarFactory implements CarFactory {
@Override
public Car createCar() {
return new YCar();
}
}
测试类
public class TestCar {
public static void main(String[] args) {
CarFactory carFactory=new DCarFactory();
Car car=carFactory.createCar();
car.createCar();
CarFactory fixFactory=new FCarFactory();
Car fcar=fixFactory.createCar();
fcar.createCar();
}
}
运行结果
造出电车
造出混动车
优点:
符合开-闭原则 符合单一职责原则。
不使用静态工厂方法,可以形成基于继承的等级结构。
缺点:
增加了代码量。
工厂使用太单一。
抽象工厂模式
作用:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
与工厂方法如出一辙,四种角色组成:
抽象工厂角色:这是抽象工厂模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。在java中它由抽象类或者接口来实现。
具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。在java中它由具体的类来实现。
抽象产品角色:它是具体产品继承的父类或者是实现的接口。在java中一般有抽象类或者接口来实现。
具体产品角色:具体工厂角色所创建的对象就是此角色的实例。在java中由具体的类来实现。
现在我们先创建每种车的一个抽象接口
public interface DCar {
void CreateCar();
}
public interface FCar {
void CreateCar();
}
public interface YCar {
void CreateCar();
}
我们现在分别用奔驰和宝马车这两个产品来实现这三个接口
public class BenzDCar implements DCar{
@Override
public void CreateCar() {
System.out.println("奔驰电车");
}
}
public class BenzFCar implements FCar{
@Override
public void CreateCar() {
System.out.println("奔驰混动车");
}
}
public class BenzYCar implements YCar{
@Override
public void CreateCar() {
System.out.println("奔驰油车");
}
}
public class BmwDCar implements DCar{
@Override
public void CreateCar() {
System.out.println("宝马电车");
}
}
public class BmwFCar implements FCar{
@Override
public void CreateCar() {
System.out.println("宝马混动");
}
}
public class BmwYCar implements YCar{
@Override
public void CreateCar() {
System.out.println("宝马油车");
}
}
创建两个宝马工厂和比亚迪工厂分别来实现抽象工厂CarFactory
public interface CarFactory {
DCar CreateDCar();
YCar CreateYCar();
FCar CreateFCar();
}
public class BenzFactory implements CarFactory{
@Override
public DCar CreateDCar() {
return new BenzDCar();
}
@Override
public YCar CreateYCar() {
return new BenzYCar();
}
@Override
public FCar CreateFCar() {
return new BenzFCar();
}
}
public class BmwFactory implements CarFactory{
@Override
public DCar CreateDCar() {
return new BmwDCar();
}
@Override
public YCar CreateYCar() {
return new BmwYCar();
}
@Override
public FCar CreateFCar() {
return new BmwFCar();
}
}
测试类
public class TestCar {
public static void main(String[] args) {
CarFactory carFactory = new BenzFactory();
DCar dCar=carFactory.CreateDCar();
dCar.CreateCar();
CarFactory carFactory1 = new BmwFactory();
FCar fCar=carFactory1.CreateFCar();
fCar.CreateCar();
}
}
测试结果
奔驰电车
宝马混动
优点:
增加新的产品族很方便,无须修改已有系统,符合“开闭原则”。
当一个产品族中的多个对象被设计成一起工作时,它能够保证客户端始终只使用同一个产品族中的对象。
缺点:
增加新的产品等级结构麻烦,需要对原有系统进行较大的修改,灵活性低