工厂模式
简单工厂
简介
简单工厂模式(Simple Factory Pattern)
简单工厂模式提供了一个用于创建对象的统一接口,但将具体对象的创建逻辑隐藏在工厂类的内部。
在简单工厂模式中,客户端通过向工厂类传递参数来请求所需的对象,而无需直接创建对象。
简单工厂模式适用于对象创建逻辑相对简单,不需要频繁变更的情况下。
示例
假设我们有一个汽车定制工厂,客户可以根据自己的需求定制不同类型的汽车,比如家用轿车、越野SUV等。
在这个例子中,汽车定制工厂可以被视为一个简单工厂,它负责根据客户的需求定制不同类型的汽车。客户不需要知道汽车是如何生产的,也不需要知道工厂的具体生产流程,只需要告诉工厂自己想要什么类型的汽车,工厂就会为客户定制出符合要求的汽车。
using System; // 定义汽车类 public abstract class Car { public abstract void Assemble(); } // 定义不同类型的汽车类 public class Sedan : Car { public override void Assemble() { Console.WriteLine("组装家用轿车"); } } public class SUV : Car { public override void Assemble() { Console.WriteLine("组装越野SUV"); } }
// 定义汽车定制工厂类 public class CarFactory { // 根据汽车类型创建对应的汽车对象 public static Car CreateCar(string type) { switch (type.ToLower()) { case "sedan": return new Sedan(); case "suv": return new SUV();default: throw new ArgumentException("不支持的汽车类型"); } } } class Program { static void Main(string[] args) { // 客户定制一辆家用轿车 Car sedan = CarFactory.CreateCar("sedan"); sedan.Assemble(); // 客户定制一辆越野SUV Car suv = CarFactory.CreateCar("suv"); suv.Assemble(); } }
那如果工厂又可以组装商务车该怎么办?
增加商务车组装类
public class Minivan : Car { public override void Assemble() { Console.WriteLine("组装商务车"); } }
改变工厂类 添加 case "minivan":
// 定义汽车定制工厂类 public class CarFactory { // 根据汽车类型创建对应的汽车对象 public static Car CreateCar(string type) { switch (type.ToLower()) { case "sedan": return new Sedan(); case "suv": return new SUV(); case "minivan": return new Minivan(); default: throw new ArgumentException("不支持的汽车类型"); } } }
每增加一种汽车类型都需要改变工厂类
优点:
-
简单工厂模式实现简单,易于理解和使用。
-
将对象的创建逻辑集中在一个工厂类中,便于管理和维护。
-
客户端无需直接创建对象,只需通过工厂类获取所需对象,降低了对象之间的耦合度。
缺点:
-
违反开闭原则(OCP):当需要添加新的产品类型时,通常需要修改工厂类的代码,这违反了开闭原则,即系统应该对扩展开放,对修改关闭的原则。
-
责任过重:简单工厂模式的工厂类负责创建多种产品类型的对象,导致工厂类的责任过重,随着产品类型的增多,工厂类的代码可能会变得庞大、复杂,不利于维护和扩展。
-
耦合度高:客户端代码与具体产品类型紧密耦合,因为客户端需要知道可用的产品类型,并且直接依赖于工厂类来创建对象,导致了耦合度的增加。
工厂方法模式
简介
工厂方法模式(Factory Method Pattern)
工厂方法模式定义了一个用于创建对象的接口,但允许子类决定要实例化的具体类。
在工厂方法模式中,客户端通过调用工厂类的方法来创建对象,而具体创建逻辑由子类工厂来实现。
工厂方法模式提供了一种延迟实例化的方式,使得系统更具有灵活性,并且能够轻松地扩展和维护。
示例
在工厂方法模式中,每个具体产品都有对应的工厂类,工厂类负责创建特定类型的产品对象。这样一来,当需要添加新的产品类型时,只需创建对应的新产品类和工厂类即可,无需修改原有的工厂类,符合开闭原则。
这个示例演示了如何使用工厂方法模式来创建不同类型的汽车对象。在这个例子中,我们有三种不同类型的汽车:家用轿车(Sedan)、越野SUV(SUV)和商务车(Minivan)。
using System; // 定义汽车接口 public interface ICar { void Assemble(); } // 具体的汽车类 public class Sedan : ICar { public void Assemble() { Console.WriteLine("组装家用轿车"); } } public class SUV : ICar { public void Assemble() { Console.WriteLine("组装越野SUV"); } } public class Minivan : ICar { public void Assemble() { Console.WriteLine("组装商务车"); } } // 定义汽车工厂接口 public interface ICarFactory { ICar CreateCar(); } // 具体的汽车工厂类 public class SedanFactory : ICarFactory { public ICar CreateCar() { return new Sedan(); } } public class SUVFactory : ICarFactory { public ICar CreateCar() { return new SUV(); } } public class MinivanFactory : ICarFactory { public ICar CreateCar() { return new Minivan(); } } class Program { static void Main(string[] args) { // 创建家用轿车 ICarFactory sedanFactory = new SedanFactory(); ICar sedan = sedanFactory.CreateCar(); sedan.Assemble(); // 创建越野SUV ICarFactory suvFactory = new SUVFactory(); ICar suv = suvFactory.CreateCar(); suv.Assemble(); // 创建商务车 ICarFactory minivanFactory = new MinivanFactory(); ICar minivan = minivanFactory.CreateCar(); minivan.Assemble(); } }
优点:
- 符合开闭原则(OCP):工厂方法模式允许系统在不修改现有代码的情况下引入新的产品类型,通过添加新的具体工厂类和产品类来扩展系统,因此符合开闭原则。
- 降低了客户端与具体产品类之间的耦合:客户端只依赖于抽象的工厂接口和产品接口,不需要直接与具体的产品类耦合,从而降低了耦合度,提高了系统的灵活性和可维护性。
- 具体产品的创建延迟到具体工厂类:工厂方法模式将具体产品的创建推迟到具体工厂类中,每个具体工厂类负责创建特定类型的产品对象,使得系统的结构更加清晰,易于理解和扩展。
缺点:
- 类的数量增加:工厂方法模式引入了多个工厂类和产品类,导致了类的数量增加,增加了系统的复杂度。
- 可能会导致类的层次结构复杂化:如果产品类的种类过多,可能会导致工厂类的层次结构变得复杂,不利于系统的管理和维护。
- 每个具体产品都需要一个具体工厂类:每种具体产品都需要对应的具体工厂类,当产品种类较多时,可能会导致工厂类的数量增加,不利于系统的管理和维护。