适配器模式是一种 结构型设计模式
,它允许不兼容的接口协同工作。通过创建一个适配器类
来解决不同接口之间的不兼容问题,使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
使用方式及用途
- 接口转换:将一个类的接口转换成客户端期望的另一个接口。
- 类适配器:通过继承目标接口和被适配者类来实现。
- 对象适配器:通过组合被适配者类来实现。
适配器模式在实际开发中有很多应用场景,主要适用于以下情况:
• 接口不兼容:需要将一个类的接口转换成客户端期望的另一个接口。
• 多平台支持:需要支持多个平台或框架,每个平台的接口不同。
• 扩展性:需要在不修改现有代码的情况下,增加新的功能或支持新的接口。
实现方式
继承或依赖:推荐使用依赖关系,而不是继承,以保持灵活性
。
结构
适配器模式包含以下几个主要角色:
目标接口(Target):定义客户需要的接口。
适配者类(Adaptee):定义一个已经存在的接口,这个接口需要适配。
适配器类(Adapter):实现目标接口,并通过组合或继承的方式调用适配者类中的方法,从而实现目标接口。
开发过程中的实际案例
案例1: 数据库适配器
假设一个应用程序,需要支持多种数据库(如 MySQL 和 SQLite)。我们可以使用适配器模式来适配不同的数据库驱动。
示例代码
目标接口(Target)
// 抽象数据库接口
public interface IDatabase
{
void Connect(string connectionString);
void ExecuteQuery(string query);
}
适配者类(Adaptee)
// MySQL 数据库实现
public class MySQLDatabase
{
public void ConnectToMySQL(string connectionString)
{
Console.WriteLine($"Connecting to MySQL database with connection string: {connectionString}");
}
public void ExecuteMySQLQuery(string query)
{
Console.WriteLine($"Executing query on MySQL: {query}");
}
}
// SQLite 数据库实现
public class SQLiteDatabase
{
public void ConnectToSQLite(string connectionString)
{
Console.WriteLine($"Connecting to SQLite database with connection string: {connectionString}");
}
public void ExecuteSQLiteQuery(string query)
{
Console.WriteLine($"Executing query on SQLite: {query}");
}
}
适配器类(Adapter)
// MySQL 数据库适配器
public class MySQLDatabaseAdapter : IDatabase
{
private readonly MySQLDatabase _mysqlDatabase;
public MySQLDatabaseAdapter(MySQLDatabase mysqlDatabase)
{
_mysqlDatabase = mysqlDatabase;
}
public void Connect(string connectionString)
{
_mysqlDatabase.ConnectToMySQL(connectionString);
}
public void ExecuteQuery(string query)
{
_mysqlDatabase.ExecuteMySQLQuery(query);
}
}
// SQLite 数据库适配器
public class SQLiteDatabaseAdapter : IDatabase
{
private readonly SQLiteDatabase _sqliteDatabase;
public SQLiteDatabaseAdapter(SQLiteDatabase sqliteDatabase)
{
_sqliteDatabase = sqliteDatabase;
}
public void Connect(string connectionString)
{
_sqliteDatabase.ConnectToSQLite(connectionString);
}
public void ExecuteQuery(string query)
{
_sqliteDatabase.ExecuteSQLiteQuery(query);
}
}
客户端代码
//创建客户端端
public class DatabaseClient
{
private IDatabase _database;
public DatabaseClient(IDatabase database)
{
_database = database;
}
public void PerformOperations()
{
_database.Connect("connection_string");//数据库
_database.ExecuteQuery("SELECT * FROM table");//随意一个表
}
}
// 使用示例
public class Program
{
public static void Main()
{
MySQLDatabase mysqlDatabase = new MySQLDatabase();
IDatabase mysqlAdapter = new MySQLDatabaseAdapter(mysqlDatabase);
DatabaseClient clientForMySQL = new DatabaseClient(mysqlAdapter);
clientForMySQL.PerformOperations();
SQLiteDatabase sqliteDatabase = new SQLiteDatabase();
IDatabase sqliteAdapter = new SQLiteDatabaseAdapter(sqliteDatabase);
DatabaseClient clientForSQLite = new DatabaseClient(sqliteAdapter);
clientForSQLite.PerformOperations();
}
}
类图:
案例2:UI 控件适配器
假设一个需要支持多个平台(如 Windows 和 macOS),每个平台的 UI 控件接口不同。使用适配器模式来适配不同的 UI 控件。
示例代码
目标接口(Target)
// 抽象 UI 控件接口
public interface IButton
{
void Render();
void Click();
}
适配者类(Adaptee)
// Windows 按钮实现
public class WindowsButtonControl
{
public void RenderWindowsButton()
{
Console.WriteLine("Rendering Windows Button");
}
public void ClickWindowsButton()
{
Console.WriteLine("Windows Button clicked");
}
}
// macOS 按钮实现
public class MacOSButtonControl
{
public void RenderMacOSButton()
{
Console.WriteLine("Rendering macOS Button");
}
public void ClickMacOSButton()
{
Console.WriteLine("macOS Button clicked");
}
}
适配器类(Adapter)
// Windows 按钮适配器
public class WindowsButtonAdapter : IButton
{
private readonly WindowsButtonControl _windowsButtonControl;
public WindowsButtonAdapter(WindowsButtonControl windowsButtonControl)
{
_windowsButtonControl = windowsButtonControl;
}
public void Render()
{
_windowsButtonControl.RenderWindowsButton();
}
public void Click()
{
_windowsButtonControl.ClickWindowsButton();
}
}
// macOS 按钮适配器
public class MacOSButtonAdapter : IButton
{
private readonly MacOSButtonControl _macOSButtonControl;
public MacOSButtonAdapter(MacOSButtonControl macOSButtonControl)
{
_macOSButtonControl = macOSButtonControl;
}
public void Render()
{
_macOSButtonControl.RenderMacOSButton();
}
public void Click()
{
_macOSButtonControl.ClickMacOSButton();
}
}
客户端代码
public class UIController
{
private IButton _button;
public UIController(IButton button)
{
_button = button;
}
public void ShowUI()
{
_button.Render();
_button.Click();
}
}
// 使用示例
public class Program
{
public static void Main()
{
WindowsButtonControl windowsButtonControl = new WindowsButtonControl();
IButton windowsButtonAdapter = new WindowsButtonAdapter(windowsButtonControl);
UIController controllerForWindows = new UIController(windowsButtonAdapter);
controllerForWindows.ShowUI();
MacOSButtonControl macosButtonControl = new MacOSButtonControl();
IButton macosButtonAdapter = new MacOSButtonAdapter(macosButtonControl);
UIController controllerForMacOS = new UIController(macosButtonAdapter);
controllerForMacOS.ShowUI();
}
}
类图:
案例3. 文件读写适配器
假设程序需要支持多种文件格式(如 CSV 和 JSON),也可以使用适配器模式来适配不同的文件读写操作。
示例代码目标接口(Target)
// 抽象日志记录接口
public interface ILogger
{
void Log(string message