创建型设计模式1

文章目录

抽象工厂模式👍

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)基础实现
csharp 复制代码
// 抽象产品接口
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)生产引擎和轮胎组件。
csharp 复制代码
// 抽象产品
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)生成不同配置。
csharp 复制代码
// 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)绘制人物
  • 应用场景: 图形界面中分步绘制复杂图形
csharp 复制代码
// 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请求构建)
csharp 复制代码
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()方法中加入校验逻辑,确保对象完整性。
csharp 复制代码
public Car Build() {
    if (_car.Wheels < 4) throw new ArgumentException("车轮不足");
    return _car;
}
(3)不可变对象
  • 通过私有构造函数 + Builder实现(线程安全)。
csharp 复制代码
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)定义抽象与具体产品
csharp 复制代码
// 抽象产品接口: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)定义抽象与具体工厂
csharp 复制代码
// 抽象工厂接口: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)客户端调用
csharp 复制代码
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)模式扩展:新增类型
  • 若需支持数据库日志,只需添加新的产品类和工厂类,而无需修改原有代码:
csharp 复制代码
// 新增具体产品:数据库日志
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)结合依赖注入
  • 通过IoC容器管理工厂和产品的生命周期。
(2)泛型工厂
  • 利用C#泛型简化工厂类的实现。
csharp 复制代码
public interface IGenericFactory<T> where T : ILog, new()
{
    T Create() => new T();
}
(3)动态工厂注册
  • 通过反射或配置自动加载工厂类。

4、优缺点分析

(1)优点
  • 符合开闭原则:新增产品类型时只需扩展工厂和产品类,无需修改已有代码。
  • 解耦性高:客户端仅依赖抽象接口,与具体产品实现解耦。
  • 灵活性增强:可通过子类动态切换产品类型(如配置文件驱动工厂选择)。
(2)缺点
  • 类数量增加:每个产品需对应一个工厂类,可能导致类膨胀。
  • 复杂度上升:对于简单场景可能引入不必要的设计复杂性。
(3)对比其他模式
  • 简单工厂:单一工厂类负责所有产品的创建,不符合开闭原则。
  • 工厂方法:每个产品对应一个工厂类,支持扩展。
  • 抽象工厂:用于创建产品族(多个相关产品),而工厂方法模式针对单个产品。
相关推荐
std860212 小时前
嵌入式软件与单片机的核心技术与应用
单片机·嵌入式硬件
李宥小哥2 小时前
结构型设计模式2
网络·数据库·设计模式
Shylock_Mister2 小时前
弱函数:嵌入式回调的最佳实践
c语言·单片机·嵌入式硬件·物联网
bbxyliyang2 小时前
基于430单片机多用途定时提醒器设计
单片机·嵌入式硬件·51单片机
d111111111d2 小时前
STM32外设学习-ADC模数转换器(代码部分)四个模块,光敏,热敏,电位,反射式红外。
笔记·stm32·单片机·嵌入式硬件·学习
范纹杉想快点毕业2 小时前
STM32百问百答:从硬件到软件全面解析
单片机·嵌入式硬件
三品吉他手会点灯3 小时前
STM32F103学习笔记-16-RCC(第3节)-使用HSE配置系统时钟并使用MCO输出监控系统时钟
c语言·笔记·stm32·单片机·嵌入式硬件·学习
朱嘉鼎3 小时前
GPIO中断编程
单片机·嵌入式硬件
straw_hat.4 小时前
32HAL——万年历
stm32·单片机·学习