抽象工厂模式👍
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(); }
// 具体产品(Windows家族)
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(); // 输出:Windows风格按钮
(2)设计原则
- 开闭原则:通过扩展(新增工厂类)而非修改现有代码支持新功能。
- 依赖倒置原则:高层模块依赖抽象接口而非具体实现。
(3)实战案例
- 需求:支持不同品牌(Benz、BMW)生产引擎和轮胎组件。
// 抽象产品
public interface IEngine { void Start(); }
public interface ITyre { void Inflate(); }
// 具体产品(Benz家族)
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();
}
// 具体工厂(Benz工厂)
public class BenzFactory : ICarFactory {
public IEngine CreateEngine() => new BenzEngine();
public ITyre CreateTyre() => new BenzTyre();
}
// 客户端调用
ICarFactory factory = new BenzFactory();
var engine = factory.CreateEngine();
engine.Start(); // 输出:Benz引擎启动
(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)生成不同配置。
// 1. 产品类:Computer
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}");
}
}
// 2. 抽象建造者:IComputerBuilder
public interface IComputerBuilder {
void SetCPU(string cpu);
void SetMotherboard(string motherboard);
void SetRAM(string ram);
void SetStorage(string storage);
Computer GetComputer();
}
// 3. 具体建造者:GamingComputerBuilder
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;
}
// 4. 指挥者(可选):ComputerDirector
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)绘制人物
// 1. 抽象建造者:PersonBuilder
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();
}
// 2. 具体建造者:PersonThinBuilder
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);
}
// 3. 客户端调用(Windows窗体示例)
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)定义抽象与具体产品
// 抽象产品接口:ILog
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)定义抽象与具体工厂
// 抽象工厂接口:ILogFactory
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"); // 输出:FileLog: Test message
// 切换工厂类型
factory = new EventLogFactory();
logger = factory.CreateLog();
logger.Write("Test message"); // 输出:EventLog: 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)对比其他模式
- 简单工厂:单一工厂类负责所有产品的创建,不符合开闭原则。
- 工厂方法:每个产品对应一个工厂类,支持扩展。
- 抽象工厂:用于创建产品族(多个相关产品),而工厂方法模式针对单个产品。