抽象工厂模式👍
1、定义与核心思想
(1)定义
- 抽象工厂模式(Abstract Factory Pattern)是一种创建型设计模式。核心目标是通过统一的接口创建一系列相关或依赖的对象(产品族),而无需指定具体实现类。
- 关键在于分离“对象创建逻辑”与“业务使用逻辑”,确保同一工厂生成的对象具有内在兼容性。适用于需要动态切换对象组合的场景。
(2)核心概念
- 产品族(Product Family):功能关联的一组对象(如Windows风格的按钮、文本框、滚动条),由同一工厂生成。
- 产品等级结构(Product Hierarchy):同一抽象产品的不同实现(如按钮的Windows和Mac版本)。
(3)结构与角色
- 抽象工厂(AbstractFactory):声明创建产品族的抽象方法集合(如
CreateButton()和CreateTextBox())。 - 具体工厂(ConcreteFactory):实现抽象工厂接口,生产特定产品族的对象(如
WindowsUIFactory生成Windows组件)。 - 抽象产品(AbstractProduct):定义产品的接口规范(如
IButton接口声明Render()方法)。 - 具体产品(ConcreteProduct):实现抽象产品接口的具体功能(如
WindowsButton类实现Render()方法)。
(3)应用场景
- 跨平台开发:动态切换UI风格(如Windows到macOS),仅需替换工厂实例,客户端代码无需修改。
- 游戏开发:生成同一风格的场景元素(如中世纪风格的房屋、武器),确保视觉一致性。
- 数据库访问:支持多数据库(MySQL、SQL Server),封装连接、命令等对象的创建逻辑。
- 配置驱动系统:通过配置文件动态加载工厂类,实现环境切换(如开发环境到生产环境)。
2、C#代码实现
(1)基础实现
public interface IButton { void Render(); }
public interface ITextBox { void Display(); }
public class WindowsButton : IButton {public void Render() => Console.WriteLine("Windows风格按钮");
}
public class WindowsTextBox : ITextBox {public void Display() => Console.WriteLine("Windows风格文本框");
}
public interface IUIFactory {IButton CreateButton();ITextBox CreateTextBox();
}
public class WindowsUIFactory : IUIFactory {public IButton CreateButton() => new WindowsButton();public ITextBox CreateTextBox() => new WindowsTextBox();
}
var factory = new WindowsUIFactory();
var button = factory.CreateButton();
button.Render();
(2)设计原则
- 开闭原则:通过扩展(新增工厂类)而非修改现有代码支持新功能。
- 依赖倒置原则:高层模块依赖抽象接口而非具体实现。
(3)实战案例
- 需求:支持不同品牌(Benz、BMW)生产引擎和轮胎组件。
public interface IEngine { void Start(); }
public interface ITyre { void Inflate(); }
public class BenzEngine : IEngine {public void Start() => Console.WriteLine("Benz引擎启动");
}
public class BenzTyre : ITyre {public void Inflate() => Console.WriteLine("Benz轮胎充气");
}
public interface ICarFactory {IEngine CreateEngine();ITyre CreateTyre();
}
public class BenzFactory : ICarFactory {public IEngine CreateEngine() => new BenzEngine();public ITyre CreateTyre() => new BenzTyre();
}
ICarFactory factory = new BenzFactory();
var engine = factory.CreateEngine();
engine.Start();
(4)优化策略
- 依赖注入(DI):通过IoC容器管理工厂实例,避免硬编码。
- 配置文件驱动:将工厂类型存储在配置文件中,动态加载。
- 组合工厂:将小规模工厂组合使用,降低复杂度(如将UI组件和网络组件分离)。
3、优缺点分析
(1)优点
- 高内聚低耦合:客户端仅依赖抽象接口,与具体实现解耦。
- 一致性保障:同一工厂生成的对象天然兼容(如Windows按钮与文本框风格统一)。
- 扩展性:新增产品族只需实现新工厂和产品类,符合开闭原则。
(2)缺点
- 新增产品等级困难:若需新增产品类型(如“复选框”),需修改所有工厂接口。
- 类数量膨胀:每个产品族需一个具体工厂,代码量随产品族增长而增加。
(3)对比其他模式
| 模式类型 | 核心差异 | 适用场景 |
|---|
| 简单工厂模式 | 单一工厂类通过参数区分产品类型 | 对象种类少,无需动态扩展 |
| 工厂方法模式 | 每个产品对应一个工厂类,解决单一产品的扩展 | 单一产品等级结构的扩展 |
| 抽象工厂模式 | 一个工厂创建多个相关产品,解决产品族的扩展 | 多产品等级结构需组合使用 |
建造者模式👍
1、定义与核心思想
(1)定义
- 建造者模式(Builder Pattern)是一种创建型设计模式,旨在将复杂对象的构建过程分解为多个独立步骤。
- 通过统一的接口实现不同配置的灵活组合,最终生成具有不同表示的对象。
(2)核心角色
- Product(产品):最终构建的复杂对象(如电脑、汽车、报告)。
- Builder(抽象建造者):定义构建步骤的接口。
- ConcreteBuilder(具体建造者):实现构建步骤的具体逻辑。
- Director(指挥者):控制构建流程(可选)。
(3)应用场景
- 对象包含多个部件,且需要灵活组合(如电子邮件、游戏角色)。
- 构建过程需分步骤控制(如文档生成、订单处理)。
(4)行业应用
- UI框架:如Android的
AlertDialog.Builder。 - ORM工具:动态构建SQL查询语句。
- 游戏开发:角色装备系统(不同部件组合)。
2、C#代码实现
(1)构建电脑
- 解耦了对象的构建逻辑与产品本身。
- 支持通过不同Builder实现(如
OfficeComputerBuilder)生成不同配置。
public class Computer {public string CPU { get; set; }public string Motherboard { get; set; }public string RAM { get; set; }public string Storage { get; set; }public void DisplaySpecs() {Console.WriteLine($"CPU: {CPU}\n主板: {Motherboard}\n内存: {RAM}\n存储: {Storage}");}
}
public interface IComputerBuilder {void SetCPU(string cpu);void SetMotherboard(string motherboard);void SetRAM(string ram);void SetStorage(string storage);Computer GetComputer();
}
public class GamingComputerBuilder : IComputerBuilder {private Computer _computer = new Computer();public void SetCPU(string cpu) => _computer.CPU = cpu;public void SetMotherboard(string motherboard) => _computer.Motherboard = motherboard;public void SetRAM(string ram) => _computer.RAM = ram;public void SetStorage(string storage) => _computer.Storage = storage;public Computer GetComputer() => _computer;
}
public class ComputerDirector {public Computer Build(IComputerBuilder builder) {builder.SetCPU("Intel i9");builder.SetMotherboard("Z690");builder.SetRAM("32GB DDR5");builder.SetStorage("1TB NVMe SSD");return builder.GetComputer();}
}
var builder = new GamingComputerBuilder();
var director = new ComputerDirector();
var gamingPC = director.Build(builder);
gamingPC.DisplaySpecs();
(2)绘制人物
public abstract class PersonBuilder {protected Graphics Graphics { get; }protected Pen Pen { get; }public PersonBuilder(Graphics g, Pen p) {Graphics = g;Pen = p;}public abstract void BuildHead();public abstract void BuildBody();public abstract void BuildArms();public abstract void BuildLegs();
}
public class PersonThinBuilder : PersonBuilder {public PersonThinBuilder(Graphics g, Pen p) : base(g, p) {}public override void BuildHead() => Graphics.DrawEllipse(Pen, 50, 20, 30, 30);public override void BuildBody() => Graphics.DrawRectangle(Pen, 60, 50, 10, 50);public override void BuildArms() => Graphics.DrawLine(Pen, 60, 50, 40, 100);public override void BuildLegs() => Graphics.DrawLine(Pen, 60, 100, 50, 150);
}
var bitmap = new Bitmap(200, 200);
using (var g = Graphics.FromImage(bitmap)) {var pen = new Pen(Color.Black);var builder = new PersonThinBuilder(g, pen);builder.BuildHead();builder.BuildBody();builder.BuildArms();builder.BuildLegs();
}
pictureBox.Image = bitmap;
(3)链式调用
- 通过链式方法调用简化客户端代码,常见于配置类库(如HTTP请求构建)
public class Car {public string Engine { get; set; }public int Wheels { get; set; }public string Color { get; set; }
}public class CarBuilder {private Car _car = new Car();public CarBuilder SetEngine(string engine) { _car.Engine = engine; return this; }public CarBuilder SetWheels(int wheels) { _car.Wheels = wheels; return this; }public CarBuilder SetColor(string color) { _car.Color = color; return this; }public Car Build() => _car;
}
var car = new CarBuilder().SetEngine("V8").SetWheels(4).SetColor("Red").Build();
3、进阶技巧
(1)省略Director
- 直接通过客户端调用Builder方法(适用于简单流程)。
(2)参数校验
- 在
Build()方法中加入校验逻辑,确保对象完整性。
public Car Build() {if (_car.Wheels < 4) throw new ArgumentException("车轮不足");return _car;
}
(3)不可变对象
- 通过私有构造函数 + Builder实现(线程安全)。
public class ImmutableCar {public string Engine { get; }private ImmutableCar(CarBuilder builder) {Engine = builder.Engine;}public class CarBuilder {public string Engine { get; set; }public ImmutableCar Build() => new ImmutableCar(this);}
}
4、优缺点分析
| 优点 | 缺点 |
|---|
| 构建逻辑与产品解耦 | 增加代码复杂度(需定义多个类) |
| 支持扩展新表示(新增Builder) | 适用于复杂对象,简单场景不适用 |
工厂方法模式👍
1、定义与核心思想
(1)核心概念
- 工厂方法模式(Factory Method Pattern)是一种创建型设计模式,其核心思想是通过抽象化对象的创建过程,将具体实例化逻辑延迟到子类,从而解耦客户端代码与具体类的依赖关系。
- 该模式通过定义一个创建对象的接口(抽象工厂),但由子类决定具体实例化的类。
(2)模式的动机
- 在软件开发中,某些对象的创建可能因需求变化而频繁调整(例如不同数据库连接、日志记录方式等)。若直接在客户端代码中通过
new操作符创建对象,会导致代码高度耦合,违反开闭原则。工厂方法模式通过封装对象的创建过程,使得系统可以灵活扩展新类型的产品,而无需修改现有代码。
(3)核心角色
- 抽象产品(Product):定义产品接口的基类或接口。
- 具体产品(ConcreteProduct):实现抽象产品的具体类。
- 抽象工厂(Creator):声明创建产品的抽象方法。
- 具体工厂(ConcreteCreator):实现抽象工厂接口,生成具体的产品实例。
(4)应用场景
- 对象创建逻辑复杂:例如需要依赖配置、环境参数或动态条件。
- 产品类型频繁扩展:如插件系统、多态组件的实现。
- 框架设计:允许框架用户自定义对象的创建方式(如ASP.NET Core中的依赖注入)。
2、C#代码实现
(1)定义抽象与具体产品
public interface ILog
{void Write(string message);
}
public class FileLog : ILog
{public void Write(string message){Console.WriteLine($"FileLog: {message}");}
}
public class EventLog : ILog
{public void Write(string message){Console.WriteLine($"EventLog: {message}");}
}
(2)定义抽象与具体工厂
public interface ILogFactory
{ILog CreateLog();
}
public class FileLogFactory : ILogFactory
{public ILog CreateLog(){return new FileLog();}
}
public class EventLogFactory : ILogFactory
{public ILog CreateLog(){return new EventLog();}
}
(3)客户端调用
class Program
{static void Main(string[] args){ILogFactory factory = new FileLogFactory();ILog logger = factory.CreateLog();logger.Write("Test message"); factory = new EventLogFactory();logger = factory.CreateLog();logger.Write("Test message"); }
}
(4)模式扩展:新增类型
- 若需支持数据库日志,只需添加新的产品类和工厂类,而无需修改原有代码:
public class DatabaseLog : ILog
{public void Write(string message){Console.WriteLine($"DatabaseLog: {message}");}
}
public class DatabaseLogFactory : ILogFactory
{public ILog CreateLog(){return new DatabaseLog();}
}
3、进阶技巧
(1)结合依赖注入
(2)泛型工厂
public interface IGenericFactory<T> where T : ILog, new()
{T Create() => new T();
}
(3)动态工厂注册
4、优缺点分析
(1)优点
- 符合开闭原则:新增产品类型时只需扩展工厂和产品类,无需修改已有代码。
- 解耦性高:客户端仅依赖抽象接口,与具体产品实现解耦。
- 灵活性增强:可通过子类动态切换产品类型(如配置文件驱动工厂选择)。
(2)缺点
- 类数量增加:每个产品需对应一个工厂类,可能导致类膨胀。
- 复杂度上升:对于简单场景可能引入不必要的设计复杂性。
(3)对比其他模式
- 简单工厂:单一工厂类负责所有产品的创建,不符合开闭原则。
- 工厂方法:每个产品对应一个工厂类,支持扩展。
- 抽象工厂:用于创建产品族(多个相关产品),而工厂方法模式针对单个产品。