设计模式-创建型设计模式(简单工厂、工厂方法、抽象工厂)
简单工厂
简单工厂模式(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");
}
}
}