应用场景
适配器模式通常应用于以下情况:
- 当你希望使用某个类,但是它的接口与其他代码不兼容时。
- 当你想创建一个可重用的类,该类可以与未知的或未来的类(即那些接口可能不兼容的类)协同工作。
- 当你需要使用几个现有的子类,但是子类化每个类以适配它们的接口会导致代码可复用性降低时。
优势
- 提高类的复用性:通过适配器,可以使原本因接口不兼容而不能一起工作的类可以一起工作。
- 增加了类的透明性和灵活性:隐藏了具体实现,用户只需要关注接口。
- 系统的可扩展性较好:在实现新的适配器时,不必修改原有代码,符合开闭原则。
劣势
- 过多的使用适配器会使系统非常凌乱:不仅会产生很多小类,而且在维护时可能会造成困难。
- 不易于理解:尤其是涉及到多重适配时,适配器的引入可能会让系统的复杂性大大增加。
例子1:电源适配器
想象一下,我们有一个IUSPowerSource美国电源接口,它提供110V电压,而我们有一个设备是IEUPowerDevice欧洲设备,它需要220V电压。为了让这个设备在美国使用,我们需要一个适配器。
首先,我们定义两个接口:
public interface IUSPowerSource
{
int Provide110V();
}
public interface IEUPowerDevice
{
void PowerOn(int voltage);
}
两个类:
public class EUPowerDevice : IEUPowerDevice
{
public void PowerOn(int voltage)
{
MessageBox.Show(voltage.ToString());
}
}
public class USPowerSource : IUSPowerSource
{
public int Provide110V()
{
return 110;
}
}
然后,我们实现一个适配器:
public class PowerAdapter: IUSPowerSource
{
private IEUPowerDevice _device;
public PowerAdapter(IEUPowerDevice device)
{
_device = device;
}
public int Provide110V()
{
// 适配器逻辑,将110V转换为220V
int voltage110 = 110;
int voltage220 = Convert110VTo220V(voltage110);
_device.PowerOn(voltage220);
return voltage110;
}
private int Convert110VTo220V(int voltage110)
{
// 假设这里有复杂的转换逻辑
return voltage110 * 2;
}
}
最后,使用适配器让欧洲设备在美国电源上工作:
private void btnConvert_Click(object sender, EventArgs e)
{
IEUPowerDevice europeanDevice = new EUPowerDevice();
IUSPowerSource adapter = new PowerAdapter(europeanDevice);
var ret = adapter.Provide110V(); // 设备可以在110V电源上工作了
}
图片
例子2:日志系统适配器
假设你有一个老旧的日志系统,它只支持输出日志到控制台,但是现在需要将日志输出到文件中。我们可以通过适配器模式来实现这一需求,而不是修改原有的日志系统。
首先,定义日志接口:
public interface ILogger
{
void Log(string message);
}
旧的日志系统实现:
public class ConsoleLogger : ILogger
{
public void Log(string message)
{
Console.WriteLine("Log to console: " + message);
}
}
现在,我们需要一个适配器来实现文件日志功能:
public class FileLoggerAdapter : ILogger
{
private FileLogger _fileLogger;
public FileLoggerAdapter(FileLogger fileLogger)
{
_fileLogger = fileLogger;
}
public void Log(string message)
{
_fileLogger.WriteToFile(message);
}
}
public class FileLogger
{
public void WriteToFile(string message)
{
// 实现将消息写入文件的逻辑
}
}
使用适配器输出日志到文件:
ILogger logger = new FileLoggerAdapter(new FileLogger());
logger.Log("This is a log message."); // 现在日志被写入到文件中