工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的。
工厂模式在一般分为三类:
这三种模式从上到下逐步抽象,并且更具一般性
简单工厂模式又称静态工厂方法模式。从命名上就可以看出这个模式一定很简单。
它存在的目的很简单:定义一个用于创建对象的接口,先来看看它的组成:
角色 | 说明 |
---|---|
1)工厂类角色 | 这是本模式的核心,含有一定的商业逻辑和判断逻辑。在java中它往往由一个具体类实现 |
2)抽象产品角色 | 它一般是具体产品继承的父类或者实现的接口。在java中由接口或者抽象类来实现。 |
3)具体产品角色 | 工厂类所创建的对象就是此角色的实例。在java中由一个具体类实现。 |
定义一个抽象产品 Car接口,定义三个具体产品角色类:奔驰、宝马、奥迪实现接口
package com.shixun.design.factory;
/**
* 抽象产品 Car接口
*/
public interface Car {
void show();
}
/**
* 新增的类Aodi
*/
public class AodiCar implements Car{
@Override
public void show() {
System.out.println("我是Aodi");
}
}
/**
* BenzCar具体产品
*/
public class BenzCar implements Car {
@Override
public void show() {
System.out.println("我是Benz");
}
}
/**
* BmwCar具体产品
*/
public class BmwCar implements Car {
@Override
public void show() {
System.out.println("我是Bmw");
}
}
编写简单工厂用于生产汽车
package com.shixun.design.factory.simple_factory;
import com.shixun.design.factory.AodiCar;
import com.shixun.design.factory.BenzCar;
import com.shixun.design.factory.BmwCar;
import com.shixun.design.factory.Car;
/**
* 简单工厂类
*/
public class SimpleFactory {
/**
* 生产汽车(屏蔽生产汽车细节)
*
* @param carName 汽车的名称
* @return
*/
public static Car produceCar(String carName) {
//equalsIgnoreCase 忽略大小写 字符串比较相等
if ("Benz".equalsIgnoreCase(carName)) {
return new BenzCar();
} else if ("Bmw".equalsIgnoreCase(carName)) {
return new BmwCar();
} else if ("Aodi".equalsIgnoreCase(carName)) {
return new AodiCar();
} else {
throw new RuntimeException("未知类型");
}
}
public static void main(String[] args) {
Car bmw = SimpleFactory.produceCar("bmw");
bmw.show();
Car aodi = SimpleFactory.produceCar("aodi");
aodi.show();
Car benz = SimpleFactory.produceCar("Benz");
benz.show();
}
}
运行结果如下:
使用了简单工厂模式后,我们的程序更加符合现实中的情况;而且客户端免除了直接创建产品对象的责任,而仅仅负责“消费”产品。
从开闭原则上来分析简单工厂模式:
当工厂生产一新辆车的时候,只要符合抽象产品制定的规定,所以对产品部分来说,它是符合开闭原则的;但是工厂部分好像不太理想,因为每增加一辆新车, 都要在工厂类中增加相应的业务逻辑或者判断逻辑,这显然是违背开闭原则的。可想而知对于新产品的加入,工厂类是很被动的。
工厂方法模式是简单工厂模式的进一步抽象化和推广,工厂方法模式里不再只由一个工厂类决定那一个产品类应当被实例化,这个决定被交给抽象工厂的子类去做。
也就是说交给了一个抽象工厂的子类(具体工厂)去实例化产品
来看下它的组成:
角色 | 说明 |
---|---|
1)抽象工厂角色 | 工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。 在java中它由抽象类或者接口来实现 |
2)具体工厂角色 | 含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象 |
3)抽象产品角色 | 它是具体产品继承的父类或者是实现的接口。在java中一般有抽象类或者接口来实现 |
4)具体产品角色 | 具体工厂角色所创建的对象就是此角色的实例。在java中由具体的类来实现 |
工厂方法模式使用继承自抽象工厂角色的多个子类来代替简单工厂模式中的“上帝类”。正如上面所 说,这样便分担了对象承受的压力;而且这样使得结构变得灵活 起来:当有新的产品产生时,只要按照 抽象产品角色、抽象工厂角色提供的合同来生成,那么就可以被客户使用,而不必去修改任何已有的代 码。可以看出工厂角色的结构也是符合开闭原则的
定义一个抽象产品 Car接口,定义三个具体产品角色类:奔驰、宝马、奥迪实现接口
package com.shixun.design.factory;
/**
* 抽象产品 Car接口
*/
public interface Car {
void show();
}
/**
* 新增的类Aodi
*/
public class AodiCar implements Car{
@Override
public void show() {
System.out.println("我是Aodi");
}
}
/**
* BenzCar具体产品
*/
public class BenzCar implements Car {
@Override
public void show() {
System.out.println("我是Benz");
}
}
/**
* BmwCar具体产品
*/
public class BmwCar implements Car {
@Override
public void show() {
System.out.println("我是Bmw");
}
}
定义一个抽象工厂:
package com.shixun.design.factory.factory_method;
import com.shixun.design.factory.Car;
/**
* 工厂(抽象工厂)
*/
public interface Factory {
Car produceCar();
}
定义三个具体工厂角色:
package com.shixun.design.factory.factory_method;
import com.shixun.design.factory.AodiCar;
import com.shixun.design.factory.Car;
/**
* Aodi工厂(具体工厂角色)
*/
public class AodiFactory implements Factory {
@Override
public Car produceCar() {
return new AodiCar();
}
}
package com.shixun.design.factory.factory_method;
import com.shixun.design.factory.BenzCar;
import com.shixun.design.factory.Car;
/**
* Benz工厂(具体工厂角色)
*/
public class BenzFactory implements Factory {
@Override
public Car produceCar() {
return new BenzCar();
}
}
package com.shixun.design.factory.factory_method;
import com.shixun.design.factory.BmwCar;
import com.shixun.design.factory.Car;
/**
* Bmw工厂(具体工厂角色)
*/
public class BmwFactory implements Factory {
@Override
public Car produceCar() {
return new BmwCar();
}
}
定义测试类生产三个产品:
package com.shixun.design.factory.factory_method;
import com.shixun.design.factory.Car;
/**
* 使用者
*/
public class Test {
public static void main(String[] args) {
//生产Bmw
BmwFactory bmwFactory = new BmwFactory();
Car bmw = bmwFactory.produceCar();
bmw.show();
//生产Benz
BenzFactory benzFactory = new BenzFactory();
Car benz = benzFactory.produceCar();
benz.show();
//生产Aodi
AodiFactory aodiFactory = new AodiFactory();
Car aodi = aodiFactory.produceCar();
aodi.show();
}
}
运行结果如下:
内容过多,请参考另一篇博文:https://blog.csdn.net/weixin_45525272/article/details/126317048
1、一个调用者想创建一个对象,只要知道其名称就可以了。
2、扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。
3、屏蔽产品的具体实现,调用者只关心产品的接口。
每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。这并不是什么好事。