我有一个用于ldap操作的第三方C#库。它对连接对象执行所有操作,如下所示:
LdapConnection connection = new LdapConnetion(Settings settings);
connection.Search(searchOU, filter,...);
我认为这是不可读的。我想写一个包装器,以便我能够编写如下代码:
因为我想拥有不同的Ldap类,比如
public class AD: LdapServer { }
public class OpenLdap: LdapServer { }
然后
AD myldap = new AD(Settings settings);
myldap.Users.Search(searchOU, filter,...)
myldap.Users.Add(searchOU, filter,...)
myldap.Users.Delete(searchOU, filter,...)
我正在考虑代理设计模式,但事情并没有让我感到热心。我应该有什么课程等。
任何帮助?
答案 0 :(得分:0)
好的,如果您只是想将方法拆分为它们所依据的对象(例如在您的示例中,在方法调用之前添加.Users。)您可以执行与此类似的操作。您需要获取正确的库方法参数和返回类型,我刚刚在这里使用了对象。
这是你要找的东西吗?
public class AD : LdapConnection
{
private UsersWrapper users;
public AD(Settings settings) : base(settings)
{
this.users = new UsersWrapper(this);
}
public UsersWrapper Users
{
get
{
return this.users;
}
}
public class UsersWrapper
{
private AD parent;
public UsersWrapper(AD parent)
{
this.parent = parent;
}
public object Search()
{
return this.parent.Search();
}
public void Add(object something)
{
this.parent.Add(something);
}
public void Delete(object something)
{
this.parent.Delete(something);
}
}
}
然后可以按如下方式使用:
Settings settings = new Settings();
AD myAD = new AD(settings);
object results = myAD.Users.Search();
请记住,这不是严格意义上的“包装器”,因为它实际上是从底层类继承的。
答案 1 :(得分:0)
上面发布的解决方案继承自LdapConnection。如果你想维护继承链,这很好,但我认为在你的情况下这是必要的。您只想自定义和简化界面。
代理设计模式继承自底层对象,因此代理对象可以在需要底层对象的任何地方使用,如果你想在类中“注入”额外的功能而没有实现该类的客户端,这是很好的。我不认为这是你的意图吗?
上面发布的解决方案的一个大问题是(因为它直接从LdapConnection继承),您可以通过两种方式调用搜索:
Settings settings = new Settings();
AD myAD = new AD(settings);
object results = myAD.Users.Search();
// OR
object results2 = myAD.Search();
我确信你可以从代码中看到,这两个都调用完全相同的底层方法。但在我看来,这对开发人员来说比使用vanilla LdapConnection对象更加困惑。我会一直在想“这些看似相同的方法之间的区别是什么?”更糟糕的是,如果在UsersWrapper Search方法中添加一些自定义代码,则无法始终保证它将被调用。开发人员可以直接调用搜索,而无需通过UsersWrapper。
Fowler在他的书PoEAA中定义了一种名为Gateway的模式。这是一种简化和自定义外部系统或库接口的方法。
public class AD
{
private LdapConnection ldapConn;
private UsersWrapper users;
public AD()
{
this.ldapConn = new LdapConnection(new Settings(/* configure settings here*/));
this.users = new UsersWrapper(this.ldapConn);
}
public UsersWrapper Users
{
get
{
return this.users;
}
}
public class UsersWrapper
{
private LdapConnection ldapConn;
public UsersWrapper(LdapConnection ldapConn)
{
this.ldapConn = ldapConn;
}
public object Search()
{
return this.ldapConn.Search();
}
public void Add(object something)
{
this.ldapConn.Add(something);
}
public void Delete(object something)
{
this.ldapConn.Delete(something);
}
}
}
然后可以这样使用:
AD myAD = new AD();
object results = myAD.Users.Search();
在这里,您可以看到LdapConnection对象被完全封装在类中,并且只有一种方法可以调用每个方法。更好的是,LdapConnection的设置也是完全封装的。使用此类的代码不必担心如何设置它。这些设置仅在一个地方定义(在此课程中,而不是在整个应用程序中传播)。
唯一的缺点是你将继承链松散回LdapConnection,但我认为这不是必要的。