适配器设计模式如何在c#中工作
本文关键字:工作 设计模式 适配器 | 更新日期: 2023-09-27 18:03:50
我这里有一个适配器模式的例子(是的,您可以检查它是否正确实现),但我真正的问题是在这里,据说适配器设计模式做以下事情:"将类的接口转换为客户端期望的另一个接口。适配器允许类一起工作,否则由于接口不兼容而无法工作。"但是我对这句话有点困惑,根据我下面的代码,我不太明白,我想知道它发生在哪里。
这是我的类/接口:
public interface ILogger
{
void Write(string data);
}
public class InfrastructureDebugLogger : ILogger
{
public void Write(string data)
{
Debug.WriteLine(data);
}
}
public class InfrastructureLoggerToDatabaseAdapter : ILogger
{
private IRepository<Log> adaptee;
public InfrastructureLoggerToDatabaseAdapter(IRepository<Log> adaptee)
{
this.adaptee = adaptee;
}
public void Write(string data)
{
var log = new Log() { Value = data };
adaptee.Create(log);
}
}
public interface IRepository<T>
{
void Create(T item);
void Update(T item);
T Find(int id);
}
public class Log
{
public int ID { get; set; }
public string Value { get; set; }
}
public class LogRepository : IRepository<Log>
{
public void Create(Log item)
{
Console.WriteLine("Created an item inside the LogRepository");
}
public void Update(Log item)
{
throw new NotImplementedException();
}
public Log Find(int id)
{
throw new NotImplementedException();
}
}
class Program
{
static void Main(string[] args)
{
ILogger logger = new InfrastructureDebugLogger();
Console.Write("Data: ");
string data = Console.ReadLine();
logger.Write(data);
InfrastructureLoggerToDatabaseAdapter loggerToDatabaseAdapter =
new InfrastructureLoggerToDatabaseAdapter(new LogRepository());
loggerToDatabaseAdapter.Write(data);
Console.ReadKey();
}
}
您的代码显示了适配器,但没有显示使用作为适配器。
为了使用这个适配器,您需要使用您的LogRepository
,它通过适配器实现IRepository<Log>
作为ILogger
。比如:
class Program
{
static void Main(string[] args)
{
Console.Write("Data: ");
string data = Console.ReadLine();
InfrastructureLoggerToDatabaseAdapter loggerToDatabaseAdapter =
new InfrastructureLoggerToDatabaseAdapter(new LogRepository());
// Here, you're using a IRepository<Log>, but adapting it to be used as an ILogger...
ILogger logger = loggerToDatabaseAdapter;
logger.Write(data);
Console.ReadKey();
}
}
用简单的话来说-
-
重命名你的适配器,因为它不是一个真正的InfrastructureLoggerToDatabaseAdapter,而是一个Repository to Logger类型。因为你正在传递一个IRepository类型的对象,并期望它的行为像一个ILogger.
-
由于存储库现在已被更新为ILog类型对象,您应该使用ILogger变量对其进行操作。
public class RepositoryToLoggerAdapter : ILogger
{
private IRepository adaptee;
public InfrastructureLoggerToDatabaseAdapter(IRepository adaptee)
{
this.adaptee = adaptee;
}
public void Write(string data)
{
var log = new Log() { Value = data };
adaptee.Create(log);
}
}
class Program
{
static void Main(string[] args)
{
ILogger logger = new InfrastructureDebugLogger();
Console.Write("Data: ");
string data = Console.ReadLine();
//This step is redundant as the text will be shown on the screen as you type
logger.Write(data);
//Create an object of IRepository type.
IRepository repository= new LogRepository();
//The create method works as it should
repository.Create(data);
//You could not have stored the repository object in the logger variable if you did not have this adapter.
logger = new RepositoryToLoggerAdapter(repository);
//Effectively you now are calling the Create method of the Repository by calling the Write method of the logger.
logger.Write(data);
Console.ReadKey();
}
}
希望这是有意义的。如果有什么不清楚的地方请告诉我。
将类的接口转换为客户端期望的另一个接口。适配器允许类一起工作,否则由于接口不兼容而无法工作。
在这种情况下,你有一个IRepository<Log>
,但你需要成为一个ILogger
,即。"另一个客户端期望的接口"。适配器类通过封装IRepository<Log>
并将ILogger
调用转换为IRepository<Log>
调用来实现这一点。
从您的示例中不清楚,因为您没有需要logger的客户端。考虑下面的类:
public class Foo
{
private ILogger _logger;
public Foo(ILogger logger)
{
_logger = logger;
}
public void Bar()
{
_logger.Write("Bar is called");
// do something
}
}
你不能把LogRepository
传递给这个类。因为LogRepository
不实现ILogger
接口。但是使用适配器,您可以将IRepository<Log>
接口"转换"为Foo
类所需的ILogger
接口:
class Program
{
static void Main(string[] args)
{
// you can't pass repository to Foo
LogRepository repository = new LogRepository();
InfrastructureLoggerToDatabaseAdapter loggerToDatabaseAdapter =
new InfrastructureLoggerToDatabaseAdapter(repository);
// but you can pass adapter
Foo foo = new Foo(loggerToDatabaseAdapter);
foo.Bar();
Console.ReadKey();
}
}
实际工作仍由LogRepository
班完成。适配器只是将它的接口适配到客户端所需的接口。与插座适配器的工作方式相同。如果你的电动剃须刀应该插在美国的插座上,如果没有适配器,你就不能在欧洲使用。