0 设计模式
不了解设计模式的小伙伴可以通过这篇文章先了解一下什么是设计模式
https://blog.csdn.net/qq_42874315/article/details/120006447?spm=1001.2014.3001.5502
1 工厂模式
创造型的设计模式,主要是用于创造对象的,它代替我们完成了new对象的操作,交给工厂来创造和管理对象有利于我们降低代码的耦合度以及提高代码的可扩展性,并且我们可以灵活的去控制对象的生产过程。任何可以产生对象的方法或类都可以称之为工厂。
工厂模式分为两大类:工厂方法、抽象工厂。
2 实现思路
2.1 工厂方法实现思路
我们将创建一个 Moveable接口和实现 Moveable 接口的实体类。
下一步是定义工厂类 CarFactory和CarFactory。
Test 类使用 CarFactory 来获取 Car 对象,使用 PlaneFactory 来获取 Plane对象
2.2 抽象工厂实现思路
创建抽象工厂,由子工厂继承,通过子工厂去创建具体的抽象实现,这样可以实现一族的扩展,例如,下图中,现代工厂和魔法工厂生产出的武器和移动工具是不同的
在测试类中,通过子工厂的createXX()方法去创建具体的对象
3 需要的类
3.1 工厂方法所需类
- 由多个具体类抽象出来的接口
- 具体的实现类
- 简单工厂
3.2 抽象方法所需类
- 抽象工厂(定义了抽象方法,返回值都是返回抽象类)
- 抽象类
- 继承了抽象类的实现类
- 工厂方法(继承抽象工厂)
4 具体实现
4.1 工厂方法的实现
4.1.1 Moveable接口
public interface Moveable {
void go();
}
4.1.2 Moveable接口的实现类
Car
public class Car implements Moveable{
public void go() {
System.out.println("Car go wuwuwuwuwu....");
}
}
Plane
public class Plane implements Moveable{
public void go(){
System.out.println("plane flying shuashuashua........");
}
}
4.1.3 简单工厂
PlaneFactory
public class PlaneFactory {
public Moveable create(){
System.out.println("日志操作 ===== a car created!! ");
return new Plane();
}
}
CarFactory
public class CarFactory {
public Moveable create(){
System.out.println("日志操作 ===== a car created!! ");
return new Car();
}
}
4.1.4 测试类
public class Main {
public static void main(String[] args) {
Moveable m = new CarFactory().create();
m.go();
Moveable moveable = new PlaneFactory().create();
moveable.go();
}
}
4.2 抽象工厂的实现
4.2.1 AbstractFactory
public abstract class AbstractFactory {
abstract Food createFood();
abstract Vehicle createVehicle();
abstract Weapon createWeapon();
}
4.2.2 抽象类
Vehicle
public abstract class Vehicle {
abstract void go();
}
Weapon
public abstract class Weapon {
abstract void shoot();
}
4.2.3 实现类
Broom
public class Broom extends Vehicle{
public void go(){
System.out.println("Broom go shuashuashua.........");
}
}
Car
public class Car extends Vehicle{
public void go() {
System.out.println("Car go wuwuwuwuwu....");
}
}
AK47
public class AK47 extends Weapon{
public void shoot(){
System.out.println("凸凸凸凸凸凸凸....");
}
}
MagicStick
public class MagicStick extends Weapon {
public void shoot(){
System.out.println("diandian.....");
}
}
4.2.4 工厂方法(继承抽象工厂)
ModernFactory
public class ModernFactory extends AbstractFactory {
@Override
Vehicle createVehicle() {
return new Car();
}
@Override
Weapon createWeapon() {
return new AK47();
}
}
MagicFactory
public class MagicFactory extends AbstractFactory {
@Override
Vehicle createVehicle() {
return new Broom();
}
@Override
Weapon createWeapon() {
return new MagicStick();
}
}
4.2.5 测试类
public class Main {
public static void main(String[] args) {
// 现代工厂
AbstractFactory factory = new ModernFactory();
factory.createVehicle().go();
factory.createWeapon().shoot();
// 魔法工厂
AbstractFactory magicFactory = new MagicFactory();
magicFactory.createVehicle().go();
magicFactory.createWeapon().shoot();
}
}
5 扩展
5.1 工厂方法扩展
5.1.1 对于工厂方法的设想
- 每个工厂没有规范,里面的方法都可以随便写
- 如果两个工厂的方法名称不一样,同一套代码就不可行了
- 假设给每个工厂增加一个抽象父类去统一一下每个工厂的生产名
5.1.2 改造工厂方法(有点像抽象工厂了,又有点像策略模式了)
-
增加一个抽象类TrafficFactory
public abstract class TrafficFactory { abstract Moveable create(); }
-
CarFactory继承TrafficFactory
public class CarFactory extends TrafficFactory{ public Moveable create(){ System.out.println("日志操作 ===== a car created!! "); return new Car(); } }
-
PlaneFactory继承TrafficFactory
public class PlaneFactory extends TrafficFactory { public Moveable create(){ System.out.println("日志操作 ===== a car created!! "); return new Plane(); } }
-
这样就使两个简单工厂中的方法名统一了,但是没有使测试类中的两行代码统一,继续改造
-
给TrafficFactory中增加一个Map(神奇的Map)
public abstract class TrafficFactory { static Map<String,TrafficFactory> trafficFactoryMap = new HashMap<>(); abstract Moveable create(); }
-
测试类(注意,需要手动先将工厂初始化到TrafficFactory的Map中,在Spring中可以通过继承InitializingBean实现自动注册)
public class Main { static{ TrafficFactory.trafficFactoryMap.put("PlaneFactory",new PlaneFactory()); TrafficFactory.trafficFactoryMap.put("CarFactory",new CarFactory()); } public static void main(String[] args) { Moveable m = TrafficFactory.trafficFactoryMap.get("PlaneFactory").create(); m.go(); } }
5.2 抽象工厂扩展
需要创建新的一族只需要修改new后面的工厂,加类,加方法…(总体来说,还是得改源码)
和工厂方法一样,如果能灵活的控制new的工厂,就可以实现代码复用了(不用改源码了)
6 总结
- 工厂方法是抽象方法的一种情况
- 形容词用接口,名词用抽象类
- 任意定制交通工具,继承Moveable
- 任意定义生产过程,XXXFactory.create()
- 任意定制产品一族(抽象工厂)
- 工厂方法
优点:产品维度好扩展,缺点:不好扩族 - 抽象工厂
优点:产品一族号扩展,缺点不好扩展单个产品(Spring IOC可以解决)
7 思维导图
8 示例源码地址
https://github.com/ChenJiahao0205/design-pattern/tree/master
最后
我是通过马士兵老师的视频和菜鸟教程学习的,部分内容可能会有雷同
想阅读更多设计模式相关文章,欢迎到我的专栏【设计模式学习笔记】、【设计模式】中去查看
在23篇设计模式文章发布完成之后,我会公开完整的思维导图,点关注,不迷路
感谢大家看到这里,文章如有不足,欢迎大家指出;彦祖点个赞吧彦祖点个赞吧彦祖点个赞吧,欢迎大家关注和转发文章!