将工厂定义为接口,它提供创建一系列相关对象的方法。
接口Car、Ship是要得到的抽象产品类型,BigCar、BigShip、MiniCar、MiniShip是可能的不同具体的产品,有可能扩展。 ProductFactory定义了不同类型Car、Ship的获取方式。
interface Car {
String getBrand();
}
interface Ship {
String getBrand();
}
class BigCar implements Car {
@Override
public String getBrand() {
return "Big";
}
}
class BigShip implements Ship {
@Override
public String getBrand() {
return "Big";
}
}
class MiniCar implements Car {
@Override
public String getBrand() {
return "Mini";
}
}
class MiniShip implements Ship {
@Override
public String getBrand() {
return "Mini";
}
}
interface ProductFactory {
Car makeCar();
Ship makeShip();
}
ProductFactory的特点是,它是接口,定义了提供一系列相关的产品的获取。
之后提供不同的BigProductFactory和MiniProductFactory来实现工厂接口。以提供不同品牌的Car和Ship。
class BigFactory implements ProductFactory {
@Override
public Car makeCar() {
return new BigCar();
}
@Override
public Car makeShip() {
return new BigShip();
}
}
class MiniFactory implements ProductFactory {
@Override
public Car makeCar() {
return new MiniCar();
}
@Override
public Car makeShip() {
return new MiniShip();
}
}
对应客户端代码,获取Car、Ship时以某种方式获得具体的ProductFactory对象。 在需要提供不同品牌的产品时,使用不同的工厂类即可。
ProductFactory factory = new MiniProductFactory();
Car car = factory.makeCar();
Ship ship = factory.makeShip();
工厂类的获取是唯一可能改动客户端的地方,但对于使用抽象的Car、Ship的客户端代码来说,大多情况下工厂类的选择也应该抽象掉。 可以使用一个简单工厂模式来提供工厂:
class ProductFactoryProvider {
public static ProductFactory getFactory() {
// .. 读取配置,修改,反射等 ,根据环境,作出选择提供具体的工厂
if (...) {
return BigProductFactory();
}
return MiniProductFactory();
}
}
抽象工厂一次性提供若干相关对象的创建,所以适合在不同环境下提供不同系列类型的场景。 比如DAO对象,可以为oracle和mysql数据库提供不同的工厂。 工厂类的获取也可以抽象化,比如反射得到。 客户端对具体的数据库类型和具体的工厂都不需要知道,所以替换不同数据库是无需改变调用者代码。