它的职责是将对象从new的泥潭里解救出来,隐藏对象的构造细节,实现了对象构造和具体实现的解耦。同时它又区别于Spring Ioc的控制反转,Ioc通过反射技术实现,而工厂模式只是封装了构造细节,实现还是传统的构造方法来实现,所以Ioc更加灵活。你可能就有疑问了,既然Ioc这么灵活我还考虑工厂模式干嘛,实际上工厂模式也有它的好处,详见如下表格。
我们一定要根据实际场景灵活选用,学习技术不是为了炫耀什么,而只是用合适的技术解决当下的业务仅此而已,哪怕所用技术很简单。说白了,不能为了用而用!
接下来介绍下工厂模式的几种类型:
一、简单工厂模式
我们应该明确的知道,既然是一个工厂,那么必然这个工厂不止可以生成一个产品,它应该可以根据实际需要,创造出更多的同类产品(工厂的职责要单一,这样符合单一职责的设计原则)。既然产品可以是多个,那么我们应该明确告知工厂,我们要的是哪一种产品,很显然通过一个type类型即可实现,我以一个咖啡工厂举例,代码如下:
scala复制代码public class SimpleFactoryMethod {
public static void main(String[] args) {
Coffee coffee = SimpleCoffeeFactory.createCoffee(2);
coffee.drink();
}
}
class SimpleCoffeeFactory{
public static Coffee createCoffee(int type){
if(type == 1){
return new CoffeeA();
}else {
return new CoffeeB();
}
}
}
abstract class Coffee{
public abstract void drink();
}
class CoffeeA extends Coffee{
@Override
public void drink() {
System.out.println("drink A");
}
}
class CoffeeB extends Coffee{
@Override
public void drink() {
System.out.println("drink B");
}
}
这样我们就能根据type类型是1还是2,决定工厂生产的产品是A咖啡还是B咖啡,当然这里只是举例,type类型最好使用枚举进行实现。
二、工厂方法模式
在简单工厂模式下,我们通过类型来告诉工厂我们要生产的具体产品是哪个,那还有其他的方式吗,这个时候就要用到了我们常见的接口。这样就衍生了几个概念,抽象工厂,具体工厂和具体产品。代码如下:
typescript复制代码public class NormalFactoryMethod {
public static void main(String[] args) {
CoffeeFactory coffeeFactory = new AmericanCoffeeFactory();
Coffee coffee = coffeeFactory.createCoffee();
coffee.drink();
}
}
// 抽象工厂
interface CoffeeFactory {
Coffee createCoffee();
}
// 具体工厂
class LatteCoffeeFactory implements CoffeeFactory {
// 具体产品:咖啡A
public Coffee createCoffee() {
return new CoffeeA();
}
}
class AmericanCoffeeFactory implements CoffeeFactory {
// 具体产品:咖啡B
public Coffee createCoffee() {
return new CoffeeB();
}
}
这样我们在写业务代码时,仅需要决定创建A工厂还是B工厂,就能决定最终我们需要的是哪一种产品。
细心的你发现了,既然工厂都可以有个抽象工厂,那产品不能有一个抽象产品吗,答案是当然可以啦,这就是我接下来要说的抽象工厂模式。
三、抽象工厂模式
该模式中工厂有抽象工厂和具体工厂,产品有抽象产品和具体产品,它强调的是一个产品族。
例如现有一个海尔工厂,生产的产品有冰箱和电视,后来又有了一个Tcl工厂,也是生产冰箱和电视,那么它们共性的地方就是它们都生产冰箱和电视。
代码如下:
scala复制代码public class AbstractFactoryMethod {
public static void main(String[] args) {
CoreFactory coreFactory = new HaierFactory();
TvCore tvCore = coreFactory.CreateTvCore();
tvCore.show();
}
}
// 抽象工厂
abstract class CoreFactory{
abstract TvCore CreateTvCore();
abstract BxCore CreateBxCore();
}
// 具体工厂(海尔工厂)
class HaierFactory extends CoreFactory{
@Override
TvCore CreateTvCore() {
return new HaierTvCore();
}
@Override
BxCore CreateBxCore() {
return new HaierBxCore();
}
}
// 具体工厂(Tcl工厂)
class TclFactory extends CoreFactory{
@Override
TvCore CreateTvCore() {
return new TclTvCore();
}
@Override
BxCore CreateBxCore() {
return new TclBxCore();
}
}
// 抽象产品(电视)
abstract class TvCore{
public abstract void show();
}
// 具体产品(海尔电视)
class HaierTvCore extends TvCore{
@Override
public void show() {
System.out.println("海尔电视");
}
}
// 具体产品(Tcl电视)
class TclTvCore extends TvCore{
@Override
public void show() {
System.out.println("Tcl电视");
}
}
// 抽象产品(冰箱)
abstract class BxCore{
public abstract void show();
}
// 具体产品(海尔冰箱)
class HaierBxCore extends BxCore{
@Override
public void show() {
System.out.println("海尔冰箱");
}
}
// 具体产品(Tcl冰箱)
class TclBxCore extends BxCore{
@Override
public void show() {
System.out.println("Tcl冰箱");
}
}
最终运行效果:
海尔电视
由此可见,找到每个工厂生产的产品存在共性的地方,这个尤为重要!
结束。