工厂模式
优点:
- 一个调用者想创建一个对象,只要知道其名称就可以了。
- 扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。
- 屏蔽产品的具体实现,调用者只关心产品的接口。
1. 简单工厂模式
静态工厂模式
public class StaticFactory {
public enum VehicleType {
Car, Bike, Truck
}
public static Vehicle create(VehicleType type) {
if (type.equals(VehicleType.Car))
return new Car();
else if (type.equals(VehicleType.Bike))
return new Bike();
else if (type.equals(VehicleType.Truck))
return new Truck();
else
return null;
}
}
工厂类逻辑简单,只负责产品类的实例化,符合单一职责原则,用户只需要调用产品类的接口,减少了耦合,符合依赖倒置原则,但是当增加一个新的产品时,就需要对工厂类进行修改,这样就打破了开闭原则。
以下两种就是改进过的工厂模式。
使用反射机制进行类注册的简单工厂模式
public class ReflectFactory {
private Map<String, Class> registeredProducts = new HashMap<>();
public void registerVehicle(String vehicleId, Class vehicleClass){
registeredProducts.put(vehicleId, vehicleClass);
}
public Vehicle create(String type) throws IllegalAccessException, InstantiationException {
Class productClass = registeredProducts.get(type);
return (Vehicle) productClass.newInstance();
}
public static void main(String[] args) throws InstantiationException, IllegalAccessException {
ReflectFactory reflectFactory = new ReflectFactory();
reflectFactory.registerVehicle("car", Car.class);
reflectFactory.registerVehicle("bike", Bike.class);
reflectFactory.registerVehicle("truck", Truck.class);
Vehicle vehicle = reflectFactory.create("car");
}
}
但是某些情况下反射机制并不适用,比如当反射机制需要权限时或者对性能要求较高时。
使用newInstance方法进行类注册的简单工厂模式
首先在产品父类中增加一个抽象方法newInstance()
public abstract class Vehicle {
public abstract Vehicle newInstance();
}
子类中实现这个方法
public class Bike extends Vehicle {
@Override
public Vehicle newInstance() {
return new Bike();
}
}
工程类
public class ReflectInstanceFactory {
private Map<String, Vehicle> registeredProducts = new HashMap<>();
public void registerVehicle(String vehicleId, Vehicle vehicle) {
registeredProducts.put(vehicleId, vehicle);
}
public Vehicle create(String type) {
return registeredProducts.get(type).newInstance();
}
public static void main(String[] args) {
ReflectInstanceFactory reflectFactory = new ReflectInstanceFactory();
reflectFactory.registerVehicle("car", new Car());
reflectFactory.registerVehicle("bike", new Bike());
reflectFactory.registerVehicle("truck", new Truck());
Vehicle vehicle = reflectFactory.create("car");
}
}
2. 工厂方法模式
工厂方法模式就是在静态工厂模式上的改进,工程类被抽象化,用于实例化特定产品类的代码被转移到实现抽象方法的子类中。这样不需要修改就可以扩展工程类。
interface People {
void say();
}
class Man implements People{
@Override
public void say() {
System.out.println("Man");
}
}
class Woman implements People{
@Override
public void say() {
System.out.println("Woman");
}
}
abstract class PeopleFactory{
public abstract People create();
}
class ManFactory extends PeopleFactory{
@Override
public People create() {
return new Man();
}
}
class WomanFactory extends PeopleFactory{
@Override
public People create() {
return new Woman();
}
}
public class FactoryMethod {
public static void main(String[] args) {
PeopleFactory manFactory = new ManFactory();
People people = manFactory.create();
people.say();
}
}
3. 抽象工厂模式
抽象工厂模式时工厂方法模式的扩展版本,它不再是创建单一类型的对象,而是创建一系列相关联的对象。
工厂方法类中只有一个抽象方法,在不同的具体工厂类中分别实现抽象产品的实例化,而抽象工厂类中,每个抽象产品都有一个实例化方法。
如果我们采用抽象工厂模式并将其用于包含单个对象的簇,那么就成为了工厂方法模式,所以说工厂方法模式只是抽象工厂模式的一种特例。
抽象工厂模式类的组成
- AbstractFactory(抽象工厂类):抽象类,用于声明创建不同类型产品的方法,它针对不同的抽象产品类都有对应的创建方法。
- ConcreteFactory(具体工程类):具体类,用于实现抽象工厂基类中声明的方法,针对每个系列的产品都有一个对应的具体工厂类。
- AbstractProduct(抽象产品类):对像所需的基本接口或类。一簇相关的产品类由来自不同层级的相似产品类组成。比如,ProductA1和ProductA2来自第一个类簇,有ConcreteFactory1实例化,ProductB1和ProductB2来自第二个类簇,有ConcreteFactory2实例化.
UML图
//Shape.java 抽象产品类
public interface Shape {
void draw();
}
//Color.java 抽象产品类
public interface Color {
void fill();
}
//...各具体产品类
//AbstractFactory.java 抽象工厂类
public abstract class AbstractFactory {
public abstract Color getColor(String color);
public abstract Shape getShape(String shape);
public static void main(String[] args) {
}
}
//ShapeFactory.java 具体工厂类
public class ShapeFactory extends AbstractFactory {
@Override
public Color getColor(String color) {
return null;
}
@Override
public Shape getShape(String shape) {
if (shape == null)
return null;
if (shape.equalsIgnoreCase("CIRCLE"))
return new Circle();
else if (shape.equalsIgnoreCase("RECTANGLE"))
return new Rectangle();
return null;
}
}
//ColorFactory.java 具体工厂类
public class ColorFactory extends AbstractFactory {
@Override
public Color getColor(String color) {
if (color == null)
return null;
if (color.equalsIgnoreCase("RED"))
return new Red();
else if (color.equalsIgnoreCase("GREEN"))
return new Green();
return null;
}
@Override
public Shape getShape(String shape) {
return null;
}
}
//FactoryProducer.java
public class FactoryProducer {
public static AbstractFactory getFactory(String choice){
if(choice == null)
return null;
if(choice.equalsIgnoreCase("SHAPE")){
return new ShapeFactory();
} else if(choice.equalsIgnoreCase("COLOR")){
return new ColorFactory();
}
return null;
}
}