【java设计模式】之 工厂模式

2019-07-26 14:13:56 浏览数 (1)

1、介绍

属于创建型设计模式,需要生成的对象叫做产品 ,生成对象的地方叫做工厂

使用场景:在任何需要生成复杂对象的地方,都可以使用工厂方法模式。 直接用new可以完成的不需要用工厂模式

2、简单工厂模式(Simple Factory Pattern)

一个栗子: 我喜欢吃面条,抽象一个面条基类,(接口也可以),这是产品的抽象类

代码语言:javascript复制
public abstract class INoodles {
    /**
     * 描述每种面条啥样的
     */
    public abstract void desc();
}

先来一份兰州拉面(具体的产品类):

代码语言:javascript复制
public class LzNoodles extends INoodles {
    @Override
    public void desc() {
        System.out.println("兰州拉面 上海的好贵 家里才5 6块钱一碗");
    }
}

程序员加班必备也要吃泡面(具体的产品类):

代码语言:javascript复制
public class PaoNoodles extends INoodles {
    @Override
    public void desc() {
        System.out.println("泡面好吃 可不要贪杯");
    }
}

还有我最爱吃的家乡的干扣面(具体的产品类):

代码语言:javascript复制
public class GankouNoodles extends INoodles {
    @Override
    public void desc() {
        System.out.println("还是家里的干扣面好吃 6块一碗");
    }
}

准备工作做完了,我们来到一家“简单面馆”(简单工厂类),菜单如下:

代码语言:javascript复制
public class SimpleNoodlesFactory {
    public static final int TYPE_LZ = 1;//兰州拉面
    public static final int TYPE_PM = 2;//泡面
    public static final int TYPE_GK = 3;//干扣面

    public static INoodles createNoodles(int type) {
        switch (type) {
            case TYPE_LZ:
                return new LzNoodles();
            case TYPE_PM:
                return new PaoNoodles();
            case TYPE_GK:
            default:
                return new GankouNoodles();
        }
    }
}

简单面馆就提供三种面条(产品),你说你要啥,他就给你啥。这里我点了一份干扣面:

代码语言:javascript复制
/**
 * 简单工厂模式
 */
 INoodles noodles = SimpleNoodlesFactory.createNoodles(SimpleNoodlesFactory.TYPE_GK);
 noodles.desc();

输出:

代码语言:javascript复制
还是家里的干扣面好吃 6块一碗

特点

1 它是一个具体的类,非接口 抽象类。有一个重要的create()方法,利用if或者 switch创建产品并返回。

2 create()方法通常是静态的,所以也称之为静态工厂

缺点

1 扩展性差(我想增加一种面条,除了新增一个面条产品类,还需要修改工厂类方法)

2 不同的产品需要不同额外参数的时候 不支持。

三 另一种简单工厂(反射):

代码语言:javascript复制
public class SimpleFactory {  
  
    public Object create(Class<?> clazz) {  
        if (clazz.getName().equals(Plane.class.getName())) {  
            return createPlane();  
        } else if (clazz.getName().equals(Broom.class.getName())) {  
            return createBroom();  
        }  
          
        return null;  
    }  
      
    private Broom createBroom() {  
        return new Broom();  
    }  
      
    private Plane createPlane() {  
        return new Plane();  
    }  
}  

测试代码:

代码语言:javascript复制
public class FactoryTest {  
  
    public static void main(String[] args) {  
        // 简单工厂模式测试  
        SimpleFactory simpleFactory = new SimpleFactory();  
        Broom broom = (Broom) simpleFactory.create(Broom.class);  
        broom.run();  
    }  
}

4、工厂方法模式(Factory Method Pattern)

我们来看一下工厂方法模式的定义吧。工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化哪一个。工厂方法让类把实例化推迟到了子类。(定义摘自《Head First设计模式》)

抽象工厂

代码语言:javascript复制
public abstract class VehicleFactory {  
    public abstract Moveable create();  
}  

具体工厂

代码语言:javascript复制
public class BroomFactory extends VehicleFactory {  
  
    @Override  
    public Moveable create() {  
        return new Broom();  
    }  
  
}  

抽象产品

代码语言:javascript复制
public interface Moveable {  
    public void run();  
}  

具体产品

代码语言:javascript复制
public class Broom implements Moveable {  
  
    @Override  
    public void run() {  
        System.out.println("我是Broom.我在飞...");  
    }  
  
}  

测试代码

代码语言:javascript复制
VehicleFactory factory = new BroomFactory();  
Moveable moveable = factory.create();  
moveable.run();  

5、抽象工厂模式(Abstract Factory Pattern)

从上面的工厂方法中的结构图中,我们可以看到其中的具体工厂A和B是两个完全独立的。两者除了都是抽象工厂的子类,没有任何其他的交集。

但是,如果我们有这样一个需求:具体工厂A和B需要生产一些同类型的不同产品。那么我们就可以试试抽象工厂模式。

我们来看看抽象工厂模式是怎么定义的:为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。同样在下面的结构图中,我们可以更好地解释这一定义。我们的抽象工厂中包含一系列的去构造一个抽象产品的方法,而具体产品的实现则是放在了具体工厂(图中的A和B)中进行。

抽象工厂:

代码语言:javascript复制
public abstract class AbstractFactory {  
  
    public abstract Flyable createFlyable();  
      
    public abstract Moveable createMoveable();  
      
    public abstract Writeable createWriteable();  
} 

具体工厂

代码语言:javascript复制
public class Factory1 extends AbstractFactory {  
  
    @Override  
    public Flyable createFlyable() {  
        return new Aircraft();  
    }  
  
    @Override  
    public Moveable createMoveable() {  
        return new Car();  
    }  
  
    @Override  
    public Writeable createWriteable() {  
        return new Pen();  
    }  
  
} 

抽象产品接口

代码语言:javascript复制
public interface Flyable {  
  
    public void fly(int height);  
} 

具体产品

代码语言:javascript复制
public class Aircraft implements Flyable {  
  
    @Override  
    public void fly(int height) {  
        System.out.println("我是一架客运机,我目前的飞行高度为:"   height   "千米。");  
    }  
  
} 

测试代码

代码语言:javascript复制
public class FactoryTest {  
  
    public static void main(String[] args) {  
        AbstractFactory factory = new Factory1();  
        Flyable flyable = factory.createFlyable();  
        flyable.fly(1589);  
          
        Moveable moveable = factory.createMoveable();  
        moveable.run(87.6);  
          
        Writeable writeable = factory.createWriteable();  
        writeable.write("Hello World.");  
    }  
}

总结

以上就是工厂模式的基本实现和详细说明。包括了简单工厂模式、工厂方法模式、抽象工厂模式。我们可以基于需求来选择合适的工厂模式

0 人点赞