设计模式--工厂模式(简单工厂/工厂方法/抽象工厂)
工厂模式是什么?
工厂模式的定义:定义一个创建产品对象的工厂接口,将产品对象的实际创建工作推迟到具体子工厂类当中
具体可划分为简单工厂(Simple Factory Pattern)工厂方法/抽象工厂(AbstractFactory)
1.简单工厂:一个工厂类就可以完成创建产品(实例)的需求,创建实例的方法通常为静态(static)方法,
所以又称静态工厂方法模式(Static Factory Method Pattern)。
2.工厂方法:对简单工厂模式的进一步抽象化,可以使系统在不修改原来代码的情况下引进新的产品
3.抽象工厂:为访问类提供一个创建一组相关或相互依赖对象的接口,且访问类无须指定所要产品的具体类就能得到同族的不同等级的产品的模式结构
工厂模式的特点是什么?
1.简单工厂:产品可直接创建使用,容易违反开闭原则
2.工厂方法:对简单工厂的进一步抽象,框架解耦,灵活性增强
3.抽象工厂:是工厂方法模式的升级版本,工厂方法模式只生产一个等级的产品,而抽象工厂模式可生产多个等级的产品
工厂模式优缺点
简单工厂:
优点:1.包含必要的逻辑判断,客户端可以很方便的创建出相应的产品,工厂和产品的职责区分明确。2.可引入配置文件,在不修改客户端代码的情况下更换和添加新的具体产品类。
缺点:1.工厂类产品单一,职责过重,产品过多会导致代码臃肿,违背高聚合原则。2.系统扩展困难,增加新产品需修改原工厂逻辑
3.使用了 static 工厂方法,造成工厂角色无法形成基于继承的等级结构。
工厂方法:
优点:1.用户只需要知道具体工厂的名称就可得到所要的产品,无须知道产品的具体创建过程。2.灵活性增强,对于新产品的创建,只需多写一个相应的工厂类。
3.典型的解耦框架。高层模块只需要知道产品的抽象类,无须关心其他实现类
缺点:1.类的个数容易过多,增加复杂度2.增加了系统的抽象性和理解难度3.抽象产品只能生产一种产品,此弊端可使用抽象工厂模式解决。
抽象工厂:
优点:1.可以在类的内部对产品族中相关联的多等级产品共同管理,而不必专门引入多个新的类来进行管理。2.当需要产品族时,抽象工厂可以保证客户端始终只使用同一个产品的产品组。3.抽象工厂增强了程序的可扩展性,当增加一个新的产品族时,不需要修改原代码,满足开闭原则。
缺点:1.当产品族中需要增加一个新的产品时,所有的工厂类都需要进行修改。增加了系统的抽象性和理解难度
日常用途有哪些?
产品较少使用简单工厂,产品较多使用工厂方法,产品较多且种类多使用抽象工厂。
三种工厂方式可根据具体的业务场景选择使用
工厂模式的代码示例
1.简单工厂
/**
* 简单工厂的可扩展性不好
* 一般获取产品方法为静态的
*/
public class SimpleVehicleFactory {
public static Car createCar(String color) {
//可以添加入参作为产品的具体属性配置
//可以通过配置文件等方法读取需要创建的产品
return new Car(color);
}
public static class Car {
String color;
public Car(String color) {
this.color = color;
}
}
}
2.工厂方法
工厂方法中的抽象工厂有时可以不要,一个具体工厂就够用了
抽象工厂(Abstract Factory)
/**
* 抽象工厂(Abstract Factory)
* 提供了创建产品的接口,调用者通过它访问具体工厂的工厂方法来创建产品
*/
public interface VehicleFactory {
Moveable createVehicle();
}
具体工厂(ConcreteFactory)
/**
* 具体工厂(ConcreteFactory)
* 主要是实现抽象工厂中的抽象方法,完成具体产品的创建。
*/
public class CarFactory implements VehicleFactory {
@Override
public Moveable createVehicle() {
return new Car();
}
}
抽象产品(Product)
/**
* 抽象产品(Product)
* 定义了产品的规范,描述了产品的主要特性和功能
*/
public interface Moveable {
void go();
}
具体产品(ConcreteProduct)
/**
* 具体产品(ConcreteProduct)
* 实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间一一对应
*/
public class Car implements Moveable {
public void go() {
System.out.println("Car go wuwuwuwuw....");
}
}
3.抽象工厂
同工厂方法模式一样,也是由抽象工厂、具体工厂、抽象产品和具体产品等 4 个要素构成,但抽象工厂中方法个数不同,抽象产品的个数也不同
抽象工厂
/**
* 抽象工厂(Abstract Factory)
* 提供了创建产品的接口,它包含多个创建产品的方法,可以创建多个不同等级的产品
*/
public abstract class AbastractFactory {
abstract Food createFood();
abstract Vehicle createVehicle();
}
具体工厂
具体工厂1
/**
* 具体工厂(Concrete Factory)
* 主要是实现抽象工厂中的多个抽象方法,完成具体产品的创建
*/
public class ModernFactory extends AbastractFactory {
@Override
Food createFood() {
return new Bread();
}
@Override
Vehicle createVehicle() {
return new Car();
}
}
具体工厂2
/**
* 具体工厂(Concrete Factory)
* 主要是实现抽象工厂中的多个抽象方法,完成具体产品的创建
*/
public class MagicFactory extends AbastractFactory {
@Override
Food createFood() {
return new MushRoom();
}
@Override
Vehicle createVehicle() {
return new Broom();
}
}
抽象产品
使用抽象类
/**
* 抽象产品(Product)
* 定义了产品的规范,描述了产品的主要特性和功能,抽象工厂模式有多个抽象产品。
*/
public abstract class Food {
abstract void printName();
}
使用接口
/**
* 抽象产品(Product)
* 定义了产品的规范,描述了产品的主要特性和功能,抽象工厂模式有多个抽象产品。
*/
public interface Vehicle { //interface
void go();
}
具体产品
贴在一起,懒得写了。。。
/**
* 具体产品(ConcreteProduct)
* 实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间是多对一的关系。
*/
public class Bread extends Food{
public void printName() {
System.out.println("wdm");
}
}
public class MushRoom extends Food{
public void printName() {
System.out.println("dmg");
}
}
public class Broom implements Vehicle{
@Override
public void go() {
System.out.println("Car go wuwuwuwuw....");
}
}
public class Car implements Vehicle {
@Override
public void go() {
System.out.println("Car go wuwuwuwuw....");
}
}