设计模式-创建型设计模式(简单工厂、工厂方法、抽象工厂)

简单工厂

简单工厂模式(Simple Factory Pattern)是一种创建型设计模式,它通过一个工厂类来封装对象的创建逻辑,客户端只需传入参数即可获取所需对象,而无需关心具体实现细节。

​核心概念​

​抽象产品​:定义产品的公共接口(如IShape),所有具体产品必须实现该接口。
​具体产品​:实现抽象产品的具体类(如Circle、Square)。
​工厂类​:包含静态方法,根据输入参数返回具体产品实例(如ShapeFactory.CreateShape)。

​#### 核心思想​
​封装变化​:将对象的创建逻辑集中到工厂类中,客户端仅依赖抽象接口,与具体类解耦。
​静态方法​:工厂类通常通过静态方法实现,因此也称为“静态工厂方法模式”。

案例1:几何图形绘制​

using System;

// 抽象产品
public interface IShape {
    void Draw();
}

// 具体产品
public class Circle : IShape {
    public void Draw() => Console.WriteLine("绘制圆形");
}

public class Square : IShape {
    public void Draw() => Console.WriteLine("绘制方形");
}

// 工厂类
public class ShapeFactory {
    public static IShape CreateShape(string shapeType) {
        switch (shapeType.ToLower()) {
            case "circle": return new Circle();
            case "square": return new Square();
            default: throw new ArgumentException("不支持的图形类型");
        }
    }
}

// 客户端
class Program {
    static void Main() {
        IShape circle = ShapeFactory.CreateShape("circle");
        circle.Draw(); // 输出:绘制圆形

        IShape square = ShapeFactory.CreateShape("square");
        square.Draw(); // 输出:绘制方形
    }
}

工厂方法

工厂方法模式通过将对象创建的职责分配给子类,有效解决了简单工厂模式违反开闭原则的问题。

核心概念与角色​

​抽象产品(Product)​​
定义产品的公共接口,所有具体产品必须实现该接口。例如,Button接口声明了render()和onClick()方法。
​具体产品(Concrete Product)​​
实现抽象产品接口的具体类。如WindowsButton和MacOSButton分别实现不同平台的按钮渲染逻辑。
​抽象工厂(Creator)​​
声明工厂方法(如createProduct()),返回抽象产品类型。通常是一个接口或抽象类。
​具体工厂(Concrete Creator)​​
重写工厂方法,返回具体产品实例。例如,WindowsDialog工厂生产WindowsButton,而MacOSDialog生产MacOSButton。

​#### 关键特点​
​延迟实例化​
工厂方法将对象的创建推迟到子类,避免客户端直接依赖具体类。
​符合开闭原则​
新增产品时只需扩展新的工厂和产品类,无需修改现有代码。
​多态性​
通过抽象接口调用工厂方法,运行时动态绑定具体实现。

案例1:跨平台UI组件工厂(Windows/Mac风格按钮)

using System;

// 抽象产品:按钮
public interface IButton {
    void Render();
    void OnClick();
}

// 具体产品:Windows按钮
public class WindowsButton : IButton {
    public void Render() => Console.WriteLine("Windows风格按钮渲染完成");
    public void OnClick() => Console.WriteLine("Windows按钮点击事件");
}

// 具体产品:Mac按钮
public class MacButton : IButton {
    public void Render() => Console.WriteLine("Mac风格按钮渲染完成");
    public void OnClick() => Console.WriteLine("Mac按钮点击事件");
}

// 抽象工厂
public abstract class Dialog {
    // 工厂方法(核心)
    public abstract IButton CreateButton();
    
    // 业务逻辑
    public void RenderDialog() {
        IButton button = CreateButton();
        button.Render();
    }
}

// 具体工厂:Windows对话框
public class WindowsDialog : Dialog {
    public override IButton CreateButton() => new WindowsButton();
}

// 具体工厂:Mac对话框
public class MacDialog : Dialog {
    public override IButton CreateButton() => new MacButton();
}

// 客户端
class Program {
    static void Main() {
        // 根据配置选择工厂(实际可通过依赖注入配置)
        Dialog dialog = Environment.OSVersion.Platform == PlatformID.Win32NT 
            ? new WindowsDialog() 
            : new MacDialog();
        
        dialog.RenderDialog(); // 输出对应平台的按钮渲染结果
    }
}

抽象工厂

抽象工厂模式是一种创建型设计模式,抽象工厂模式的核心是产品族的概念,即一组相互关联或依赖的对象(如不同操作系统的UI组件、不同品牌的汽车及其配件)。该模式通过统一的接口创建这些对象,确保它们之间的兼容性和一致性。

解耦客户端与具体产品实现​

客户端代码仅依赖抽象工厂和抽象产品的接口,无需关心具体产品的类名或实现细节。这种解耦使得系统更灵活,便于切换不同的产品族(如从Windows风格切换到Mac风格)而无需修改客户端代码。
例如,数据库访问层可以通过抽象工厂支持MySQL、Oracle等不同数据库的连接对象和查询对象,客户端仅通过抽象接口操作,与具体数据库无关。

典型应用场景

  • ​跨平台UI组件库​:如创建Windows/Mac风格的按钮、窗口等。
  • ​数据库访问层​:支持多种数据库的连接和查询对象。
  • ​游戏开发​:为不同种族生成配套的角色、武器和场景。
  • ​主题切换系统​:如切换应用的亮色/暗色主题,保证所有组件风格统一。

案例1:跨平台UI组件(Windows/Mac风格按钮和文本框)

using System;

// 抽象产品:按钮
public interface IButton {
    void Render();
    void OnClick();
}

// 抽象产品:文本框
public interface ITextBox {
    void Render();
    void OnInput();
}

// 具体产品:Windows风格组件
public class WindowsButton : IButton {
    public void Render() => Console.WriteLine("Windows风格按钮渲染完成");
    public void OnClick() => Console.WriteLine("Windows按钮点击事件");
}

public class WindowsTextBox : ITextBox {
    public void Render() => Console.WriteLine("Windows风格文本框渲染完成");
    public void OnInput() => Console.WriteLine("Windows文本框输入事件");
}

// 具体产品:Mac风格组件
public class MacButton : IButton {
    public void Render() => Console.WriteLine("Mac风格按钮渲染完成");
    public void OnClick() => Console.WriteLine("Mac按钮点击事件");
}

public class MacTextBox : ITextBox {
    public void Render() => Console.WriteLine("Mac风格文本框渲染完成");
    public void OnInput() => Console.WriteLine("Mac文本框输入事件");
}

// 抽象工厂
public interface IUIFactory {
    IButton CreateButton();
    ITextBox CreateTextBox();
}

// 具体工厂:Windows组件工厂
public class WindowsUIFactory : IUIFactory {
    public IButton CreateButton() => new WindowsButton();
    public ITextBox CreateTextBox() => new WindowsTextBox();
}

// 具体工厂:Mac组件工厂
public class MacUIFactory : IUIFactory {
    public IButton CreateButton() => new MacButton();
    public ITextBox CreateTextBox() => new MacTextBox();
}

// 客户端代码
class Program {
    static void Main(string[] args) {
        // 根据配置选择工厂(实际项目中可通过依赖注入配置)
        IUIFactory factory = Environment.OSVersion.Platform == PlatformID.Win32NT 
            ? new WindowsUIFactory() 
            : new MacUIFactory();

        // 创建并使用组件
        var button = factory.CreateButton();
        var textBox = factory.CreateTextBox();
        button.Render();    // 输出平台对应风格
        textBox.OnInput();  // 触发平台对应事件
    }
}

案例2:多数据库访问(SQL Server/Oracle连接)

using System;
using System.Data;

// 抽象产品:数据库连接
public interface IDbConnection {
    void Open();
    void Close();
    void ExecuteCommand(string sql);
}

// 抽象产品:数据查询器
public interface IDataQuery {
    object QuerySingle(string sql);
}

// 具体产品:SQL Server实现
public class SqlConnection : IDbConnection {
    public void Open() => Console.WriteLine("SQL Server连接已打开");
    public void Close() => Console.WriteLine("SQL Server连接已关闭");
    public void ExecuteCommand(string sql) => Console.WriteLine($"执行SQL Server命令: {sql}");
}

public class SqlDataQuery : IDataQuery {
    public object QuerySingle(string sql) {
        Console.WriteLine($"SQL Server查询: {sql}");
        return new object();
    }
}

// 具体产品:Oracle实现
public class OracleConnection : IDbConnection {
    public void Open() => Console.WriteLine("Oracle连接已打开");
    public void Close() => Console.WriteLine("Oracle连接已关闭");
    public void ExecuteCommand(string sql) => Console.WriteLine($"执行Oracle命令: {sql}");
}

public class OracleDataQuery : IDataQuery {
    public object QuerySingle(string sql) {
        Console.WriteLine($"Oracle查询: {sql}");
        return new object();
    }
}

// 抽象工厂
public interface IDbFactory {
    IDbConnection CreateConnection();
    IDataQuery CreateQuery();
}

// 具体工厂
public class SqlDbFactory : IDbFactory {
    public IDbConnection CreateConnection() => new SqlConnection();
    public IDataQuery CreateQuery() => new SqlDataQuery();
}

public class OracleDbFactory : IDbFactory {
    public IDbConnection CreateConnection() => new OracleConnection();
    public IDataQuery CreateQuery() => new OracleDataQuery();
}

// 客户端
class Client {
    static void Main(string[] args) {
        // 通过配置文件选择数据库类型
        IDbFactory factory = ConfigurationManager.AppSettings["DBType"] == "Oracle" 
            ? new OracleDbFactory() 
            : new SqlDbFactory();

        // 使用抽象接口操作
        using (var conn = factory.CreateConnection()) {
            conn.Open();
            var query = factory.CreateQuery();
            query.QuerySingle("SELECT * FROM Users");
        }
    }
}
posted @ 2024-10-28 10:16  .Neterr  阅读(18)  评论(0)    收藏  举报