了解适配器模式 (c#)
Understanding the adaptor pattern (c#)
我正在编写一个场景,我觉得适配器模式会很有用。我有一个服务有多个可能的提供者,我想在我喜欢的时候切换,所以只要每个 "Adapter" 遵循相同的规则(接口),底层代码对调用者是隐藏的。
考虑到这一点,我一直在研究许多示例。 This code snippet is taken from this stack overflow example:
Interface ITarget
{
public void GetData();
}
//Decision to use MSDAO
class AdaptorMS : ITarget
{
public void GetData()
{
MSDAO objmsdao = new MSDAO();
objmsdao.GetDataMethod();
}
}
// calling code
class Client
{
static void Main(string[] args)
{
ITarget objAdaptor = new AdaptorMS();
object dummyObject = objAdaptor.GetData();
}
}
然后我们决定创建一个新的适配器,我们将更改为:
//After a month, the decision to use OracaleDAO was taken, so create a new adapter
class AdaptorOracle: ITarget
{
public void GetData()
{
OracleDAO objrracledao = new OracleDAO();
objoracledao.GetSomeData();
}
}
// Calling code
class Client
{
static void Main(string[] args)
{
ITarget objAdaptor = new AdaptorOracle();
object dummyObject = objAdaptor.GetData();
}
}
我也看过这个例子:
public class AdaptorA : ITarget
{
private TargetA A { get; set; }
public AdaptorA( TargetA a )
{
this.A = a;
}
public void GetData() {
return this.A.SomeGetDataCall();
}
}
public class AdaptorB : ITarget
{
private TargetB B { get; set; }
public AdaptorB( TargetB a )
{
this.B = a;
}
public void GetData() {
this.B.MakeDataCall();
}
}
我们有两个新的适配器,但我对上面的示例不理解的是,适配器 class 为它将调用的底层系统(TargetA 或 TargetB)获取一个参数。这两个例子有什么区别?我得到了第一个示例,从调用代码中隐藏了所有实现(OracleDAO 的实例在适配器内部),但不是第二个。有根本的区别还是我误解了模式?
提前感谢您的任何建议!
Adaptor 的上述两种实现之间存在一个关键区别。
总而言之,Adapter 只不过是不同 classes 的包装器,其目的是提供一个通用接口。它可以使用双重继承(class 适配器)或通过在适配器(对象适配器)中组合和实例化适配器来实现。
上面的例子都是"object adaptors"(根据GoF定义)。
然而,示例 2 实际上是 Strategy 和 Adaptor 的组合,在 Adapter classes 和 Adaptees 之间提供了一个额外的解耦层。这更灵活,更符合 SOLID 中的 "D"。
考虑到这一点,现在邀请 reader 设想每个版本比另一个版本更合适的用例。但是当像上面那样孤立地呈现时,它们的不同和用途不同的事实很容易被忽视。
不确定上面的评论是否涵盖了这一点?
我正在编写一个场景,我觉得适配器模式会很有用。我有一个服务有多个可能的提供者,我想在我喜欢的时候切换,所以只要每个 "Adapter" 遵循相同的规则(接口),底层代码对调用者是隐藏的。
考虑到这一点,我一直在研究许多示例。 This code snippet is taken from this stack overflow example:
Interface ITarget
{
public void GetData();
}
//Decision to use MSDAO
class AdaptorMS : ITarget
{
public void GetData()
{
MSDAO objmsdao = new MSDAO();
objmsdao.GetDataMethod();
}
}
// calling code
class Client
{
static void Main(string[] args)
{
ITarget objAdaptor = new AdaptorMS();
object dummyObject = objAdaptor.GetData();
}
}
然后我们决定创建一个新的适配器,我们将更改为:
//After a month, the decision to use OracaleDAO was taken, so create a new adapter
class AdaptorOracle: ITarget
{
public void GetData()
{
OracleDAO objrracledao = new OracleDAO();
objoracledao.GetSomeData();
}
}
// Calling code
class Client
{
static void Main(string[] args)
{
ITarget objAdaptor = new AdaptorOracle();
object dummyObject = objAdaptor.GetData();
}
}
我也看过这个例子:
public class AdaptorA : ITarget
{
private TargetA A { get; set; }
public AdaptorA( TargetA a )
{
this.A = a;
}
public void GetData() {
return this.A.SomeGetDataCall();
}
}
public class AdaptorB : ITarget
{
private TargetB B { get; set; }
public AdaptorB( TargetB a )
{
this.B = a;
}
public void GetData() {
this.B.MakeDataCall();
}
}
我们有两个新的适配器,但我对上面的示例不理解的是,适配器 class 为它将调用的底层系统(TargetA 或 TargetB)获取一个参数。这两个例子有什么区别?我得到了第一个示例,从调用代码中隐藏了所有实现(OracleDAO 的实例在适配器内部),但不是第二个。有根本的区别还是我误解了模式?
提前感谢您的任何建议!
Adaptor 的上述两种实现之间存在一个关键区别。
总而言之,Adapter 只不过是不同 classes 的包装器,其目的是提供一个通用接口。它可以使用双重继承(class 适配器)或通过在适配器(对象适配器)中组合和实例化适配器来实现。
上面的例子都是"object adaptors"(根据GoF定义)。
然而,示例 2 实际上是 Strategy 和 Adaptor 的组合,在 Adapter classes 和 Adaptees 之间提供了一个额外的解耦层。这更灵活,更符合 SOLID 中的 "D"。
考虑到这一点,现在邀请 reader 设想每个版本比另一个版本更合适的用例。但是当像上面那样孤立地呈现时,它们的不同和用途不同的事实很容易被忽视。
不确定上面的评论是否涵盖了这一点?