一、概述
工厂模式呢其实是一个笼统的概念,具体划分的话可分为三类:简单工厂模式、工厂方法模式和抽象工厂模式。其中简单工厂模式不输入23种设计模式之一,但他们又都属于创建型
模式。
二、简单工厂模式
简单工厂模式,又叫做静态工厂模式(Static Factory Method)。上面已经说过了,简单工厂模式并不属于23种设计模式之一。但是它又属于创建型
模式,它是工厂模式家族中最简单实用的模式,可以理解是不同工厂模式的一个特殊实现。其UML类图如下:
根据UML图便可知道,首先需要有一个接口,其次是具体的产品去实现这个接口,然后有一个
Factory
工厂类来生产这些产品。由于该模式不是本文着重点,所以只放一段核心工厂类代码在这里就好了:
public class Factory {
public ICar GetCar(CarType carType) {
switch (carType)
{
case CarType.SportCarType:
return new SportCar();
case CarType.JeepCarType:
return new JeepCar();
case CarType.HatchbackCarType:
return new HatchbackCar();
default:
throw new Exception("爱上一匹野马,可我的家里没有草原. 你走吧!");
}
}
}
三、工厂方法模式
工厂方法模式(Factory Method),又称多态性工厂模式,属于设计模式三大分类中的创建型模式
,作为抽象工厂模式的孪生兄弟,工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个,也就是说工厂模式让实例化推迟到子类。
在工厂模式中,核心的工厂类不再负责所有的产品的创建,而是将具体的工作交给子类去做。该核心类成为一个抽象工厂角色,仅负责给出具体工厂子类必须实现的接口,而不接触哪一个产品应当被实例化这种细节。
工厂方法模式非常符合“开闭原则”,当需要增加一个新产品时,我们只需要增加一个具体的产品类和与之对应的具体工厂即可,无须关系产品的创建过程,甚至连具体的产品类名称都不需要知道。
虽然他很好的符合了“开闭原则”,但是由于每新增一个新产品时就需要增加两个类,这样势必就会导致系统的复杂度增加。其UML结构图如下:
示例:
产品类相关:
//抽象产品类 车
public interface Car {
/**
* 上班函数
*/
void gotowork();
}
//具体产品类 自行车
public class Bike implements Car {
@Override
public void gotowork() {
System.out.println("骑自行车去上班!");
}
}
//具体产品类 公交车
public class Bus implements Car {
@Override
public void gotowork() {
System.out.println("坐公交车去上班!");
}
}
工厂类相关:
//抽象工厂
public interface ICarFactory {
/**
* 获取交通工具
*
* @return
*/
Car getCar();
}
//具体工厂类 生产自行车
public class BikeFactory implements ICarFactory {
@Override
public Car getCar() {
return new Bike();
}
}
//具体工厂类 生产公交车
public class BusFactory implements ICarFactory {
@Override
public Car getCar() {
return new Bus();
}
}
使用测试:
public static void main(String[] args){
ICarFactory factory = null;
// bike
factory = new BikeFactory();
Car bike = factory.getCar();
bike.gotowork();
// bus
factory = new BusFactory();
Car bus = factory.getCar();
bus.gotowork();
}
输出结果:
骑自行车去上班!
坐公交车去上班!
使用场景:日志记录器;数据库访问等。
四、抽象工厂模式
同样的抽象工厂模式也是属于创建型
设计模式。所谓抽象工厂模式就是提供一个接口,用于创建相关或者依赖对象的家族,而不需明确指定具体类。他允许客户端使用抽象的接口来创建一组相关的产品,而不需要关系实际产出的具体产品是什么。这样一来,客户就可以从具体的产品中被解耦。
他的优点是隔离了具体类的生成,使得客户端不需要知道什么被创建了,而缺点就在于新增的行为会比较麻烦,因为当添加一个新产品对象时,需要更改接口及其下所有子类。其UML结构图如下:
具体示例:
形状接口/类
//形状接口
public interface Shape {
void draw();
}
//具体实现类 矩形
public class Rectangle implements Shape {
@Override
public void draw() {
System.out.println("Inside Rectangle::draw() method.");
}
}
//具体实现类正方形
public class Square implements Shape {
@Override
public void draw() {
System.out.println("Inside Square::draw() method.");
}
}
//具体实现类 圆形
public class Circle implements Shape {
@Override
public void draw() {
System.out.println("Inside Circle::draw() method.");
}
}
颜色接口/类:
//颜色接口
public interface Color {
void fill();
}
//具体实现类 红色
public class Red implements Color {
@Override
public void fill() {
System.out.println("Inside Red::fill() method.");
}
}
//具体实现类 绿色
public class Green implements Color {
@Override
public void fill() {
System.out.println("Inside Green::fill() method.");
}
}
//具体实现类 蓝色
public class Blue implements Color {
@Override
public void fill() {
System.out.println("Inside Blue::fill() method.");
}
}
工厂类:
//抽象工厂类
public abstract class AbstractFactory {
public abstract Color getColor(String color);
public abstract Shape getShape(String shape) ;
}
//形状工厂
public class ShapeFactory extends AbstractFactory {
@Override
public Shape getShape(String shapeType){
if(shapeType == null){
return null;
}
if(shapeType.equalsIgnoreCase("CIRCLE")){
return new Circle();
} else if(shapeType.equalsIgnoreCase("RECTANGLE")){
return new Rectangle();
} else if(shapeType.equalsIgnoreCase("SQUARE")){
return new Square();
}
return null;
}
@Override
public Color getColor(String color) {
return null;
}
}
//颜色工厂
public class ColorFactory extends AbstractFactory {
@Override
public Shape getShape(String shapeType){
return null;
}
@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();
} else if(color.equalsIgnoreCase("BLUE")){
return new Blue();
}
return null;
}
工厂生产器:
public class FactoryProducer {
public static AbstractFactory getFactory(String choice){
if(choice.equalsIgnoreCase("SHAPE")){
return new ShapeFactory();
} else if(choice.equalsIgnoreCase("COLOR")){
return new ColorFactory();
}
return null;
}
}
测试类:
public class AbstractFactoryPatternDemo {
public static void main(String[] args) {
//获取形状工厂
AbstractFactory shapeFactory = FactoryProducer.getFactory("SHAPE");
//获取形状为 Circle 的对象
Shape shape1 = shapeFactory.getShape("CIRCLE");
//调用 Circle 的 draw 方法
shape1.draw();
//获取形状为 Rectangle 的对象
Shape shape2 = shapeFactory.getShape("RECTANGLE");
//调用 Rectangle 的 draw 方法
shape2.draw();
//获取形状为 Square 的对象
Shape shape3 = shapeFactory.getShape("SQUARE");
//调用 Square 的 draw 方法
shape3.draw();
//获取颜色工厂
AbstractFactory colorFactory = FactoryProducer.getFactory("COLOR");
//获取颜色为 Red 的对象
Color color1 = colorFactory.getColor("RED");
//调用 Red 的 fill 方法
color1.fill();
//获取颜色为 Green 的对象
Color color2 = colorFactory.getColor("Green");
//调用 Green 的 fill 方法
color2.fill();
//获取颜色为 Blue 的对象
Color color3 = colorFactory.getColor("BLUE");
//调用 Blue 的 fill 方法
color3.fill();
}
}
输出结果:
Inside Circle::draw() method.
Inside Rectangle::draw() method.
Inside Square::draw() method.
Inside Red::fill() method.
Inside Green::fill() method.
Inside Blue::fill() method.
使用场景:QQ换肤,一套一起换;生成不同操作系统的程序。