工厂模式总述
工厂模式属于类的创建模式,工厂模式专门负责将大量有共同接口的类实例化。工厂模式可以动态决定将哪一个类实例化,而不必事先知道每次要实例化哪一个类。工厂模式有三个基本形态:
1. 简单工厂(Simple Factory)模式,又称静态工厂方法模式(Static Factory Method Pattern)。
2. 工厂方法(Factory Method)模式,又称多态性工厂(Polymorphic Factory)模式或虚拟构造子(Virtual Constructor)模式。
3. 抽象工厂(Abstract Factory)模式,又称工具箱(Kit 或Toolkit)模式。
工厂方法模式
工厂方法模式是简单工厂模式的进一步抽象化和推广,工厂方法模式里不再只由一个工厂类决定那一个产品类应当被实例化,这个决定被交给抽象工厂的子类去做。
来看下它的组成:
1. 抽象工厂角色:这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。在java中它由抽象类或者接口来实现。
2. 具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。
3. 抽象产品角色:它是具体产品继承的父类或者是实现的接口。在java中一般有抽象类或者接口来实现。
4. 具体产品角色:具体工厂角色所创建的对象就是此角色的实例。在java中由具体的类来实现。
工厂方法模式使用继承自抽象工厂角色的多个子类来代替简单工厂模式中的“上帝类”。正如上面所说,这样便分担了对象承受的压力;而且这样使得结构变得灵活起来——当有新的产品(即暴发户的汽车)产生时,只要按照抽象产品角色、抽象工厂角色提供的合同来生成,那么就可以被客户使用,而不必去修改任何已有的代码。可以看出工厂角色的结构也是符合开闭原则的!
好了,废话不多说,直接上代码。首先抽象一下场景:
某影视公司要拍一部战争题材的电视剧,要求XXX军工厂建造模型,包括能飞的飞机,能跑的坦克和能下水的船。然后XXX军工厂按照要求开始建造模型。
抽象的产品角色
public interface Moveable {
void move();
}
抽象的工厂角色
public abstract class VehicleFactory{
public abstract Moveable creat();
}
具体的产品角色
public class Plane implements Moveable {
@Override
public void move() {
System.out.println("plane fly...");
}
}
public class Tank implements Moveable {
@Override
public void move() {
System.out.println("tank run...");
}
}
public class Boat implements Moveable {
@Override
public void move() {
System.out.println("boat swim...");
}
}
具体的工厂角色
public class PlaneFactory extends VehicleFactory {
@Override
public Moveable creat() {
return new Plane();
}
}
public class TankFactory extends VehicleFactory {
@Override
public Moveable creat() {
return new Tank();
}
}
public class BoatFactory extends VehicleFactory {
@Override
public Moveable creat() {
return new Boat();
}
}
具体的实现,这里是基于android实现的,java中单独写一个测试类在main方法中实现。
VehicleFactory planeFactory = new PlaneFactory();
Moveable planeMove = planeFactory.creat();
planeMove.move();
VehicleFactory tankFactory = new TankFactory();
Moveable tankMove = tankFactory.creat();
tankMove.move();
VehicleFactory boatFactory = new BoatFactory();
Moveable boatMove = boatFactory.creat();
boatMove.move();
看看输出:
然后大家又可以看到狗血的战争题材电视剧了......