2.2 简单工厂模式(Factory Method Pattern)
2.2.1 定义
简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现。
试想一下,当我们在coding的时候,在A类里面只要NEW了一个B类的对象,那么A类就会从某种程度上依赖B类。如果在后期需求发生变化或者是维护的时候,需要修改B类的时候,我们就需要打开源代码修改所有与这个类有关的类了,做过重构的朋友都知道,这样的事情虽然无法完全避免,但确实是一件让人心碎的事情。
2.2.2 模拟场景
欧美主导的以赛车为主题的系列电影《速度与激情》系列相信大家都看过,里面的男主角(zhǔ jué,加个拼音,经常听到有人说什么主脚主脚的,虽然之前我也不确定是zhǔ jué还是主脚,但是我没念过主脚,我在不确定的情况下我都是念男一号)范·迪塞尔在每一集里面做不同的事情都是开不同的车子,相信大家都觉得很酷吧。
人家酷也没办法,谁叫人家是大佬呢。这里我们试想一下,如果这是一套程序,我们该怎么设计?每次不同的画面或者剧情范·迪塞尔都需要按照导演的安排开不一样的车,去参加赛车需要开的是跑车,可能导演就会说下一场戏:范·迪塞尔下一场戏需要开跑车(参数),要去参加五环首届跑车拉力赛,这时候场务(工厂类)接到导演的命令(跑车参数)后需要从车库开出一辆跑车(具体产品)交到范·迪塞尔手上让他去准备五环首届跑车拉力赛。这套程序的整个生命周期就算完成了。(什么?没完成?难不成你还真想来个五环首届跑车拉力赛了啊:)
根据导演不同的指令,开的车是不一样的,但是车都是在车库中存在的。车都属于同一种抽象,车库里所有的车都有自己的特征,这些特征就是条件。导演发出指令的时候,只要告诉场务特征,场务就知道提什么车。这就简单工厂模式的典型案例。
2.2.3 简单工厂模式的UML类图
2.2.4 代码演示
抽象产品类代码:
using System; namespace SimpleFactoryPattern { /// <summary> /// 抽象产品类: 汽车 /// </summary> public interface ICar { void GetCar(); } }
具体产品类代码:
using System; using System.Collections.Generic; using System.Text; namespace SimpleFactoryPattern { public enum CarType { SportCarType = 0, JeepCarType = 1, HatchbackCarType = 2 } /// <summary> /// 具体产品类: 跑车 /// </summary> public class SportCar : ICar { public void GetCar() { Console.WriteLine("场务把跑车交给范·迪塞尔"); } } /// <summary> /// 具体产品类: 越野车 /// </summary> public class JeepCar : ICar { public void GetCar() { Console.WriteLine("场务把越野车交给范·迪塞尔"); } } /// <summary> /// 具体产品类: 两箱车 /// </summary> public class HatchbackCar : ICar { public void GetCar() { Console.WriteLine("场务把两箱车交给范·迪塞尔"); } } }
简单工厂核心代码:
using System; using System.Collections.Generic; using System.Text; namespace SimpleFactoryPattern { public class CarFactory { 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("爱上一匹野马,可我的家里没有草原. 你走吧!"); } } } }
客户端调用代码:
class Program { static void Main(string[] args) { ICar car; try { Factory factory = new Factory(); Console.WriteLine("范·迪塞尔下一场戏开跑车。"); car = factory.GetCar(CarType.SportCarType); car.GetCar(); } catch (Exception ex) { Console.WriteLine(ex.Message); } } }
2.2.5 优缺点
优点:简单工厂模式能够根据外界给定的信息,决定究竟应该创建哪个具体类的对象。明确区分了各自的职责和权力,有利于整个软件体系结构的优化。
缺点:很明显工厂类集中了所有实例的创建逻辑,容易违反GRASPR的高内聚的责任分配原则