2008-10-05 45 views
3

我正在处理跨两个名称空间提供几乎重复的代码的web服务。比方说,例如PigFeet和HorseFeet,两个名称空间都包含一个Feet类,其他代码与Feet类一起工作,要求它成为同一名称空间的一部分。相同的类,不同的名称空间,一种简化的方法?

现在在我的代码,我不得不做这样的事情:

if(_animalType == AnimalType.Pig) 
{ 
    //namespace is pigfeet 
    PigFeet.Feet feet = new Feet(); 
    feet.WashFeet(); 
} 

if(_animalType == AnimalType.Horse) 
{ 
    //namespace is horsefeet 
    HorseFeet.Feet feet = new Feet(); 
    feet.WashFeet(); 
} 

这是留给我,有很多重复的代码。有没有办法更动态地选择一个名称空间?

+0

HorseFeet.Feet和PigFeet.Feet是否有共同的基类?如果是这样,我可以用更多的重构更新我的答案。 – 2008-10-05 17:34:19

回答

2

命名空间不是问题 - 只是这两个类没有关系,所以没有可用于多态的继承链。

您需要看看duck typingadapter pattern之类的东西,或者构建自己的代理类以使自己进入通用接口。为了实现小的数字,我只建立一个单独的适配器类委托给它的任何非空实例侥幸:

interface IFeet { 
    void WashFeet(); 
} 

class FeetAdapter : IFeet { 
    private PigFeet.Feet _pigFeet; 
    private HorseFeet.Feet _horseFeet; 

    private FeetAdapter(PigFeet.Feet pigFeet) { 
     _pigFeet = pigFeet; 
    } 

    private FeetAdapter(HorseFeet.Feet horseFeet) { 
     _horseFeet = horseFeet; 
    } 

    public void WashFeet() { 
     if (_pigFeet != null) { 
     _pigFeet.WashFeet(); 
     } else { 
     _horseFeet.WashFeet(); 
     } 
    } 

    public static FeetAdapter Create(AnimalType animalType) { 
     switch (animalType) { 
     case AnimalType.Pig: 
      return new FeetAdapter(new PigFeet.Feet()); 
     case AnimalType.Horse: 
      return new FeetAdapter(new HorseFeet.Feet()); 
     } 
    } 
} 

对于较大的情况下,你会是一个单独的PigFeetAdapter更好和HorseFeetAdapter,它们都实现了IFeet,还有一个FeetAdapterFactory来创建它们 - 但是这个概念和我上面展示的一样。

3

在您的命名空间导入中,您可以将alias分配给特定的命名空间或成员。

using PigFeet = PigFeet.Feet; 
using HorseFeet = HorseFeet.Feet; 

//now your sample code should look something like 

if(_animalType == AnimalType.Pig) 
{ 
    //namespace is pigfeet 
    PigFeet feet = new PigFeet(); 
    feet.WashFeet(); 
} 

if(_animalType == AnimalType.Horse) 
{ 
    //namespace is horsefeet 
    HorseFeet feet = new HorseFeet(); 
    feet.WashFeet(); 
} 
+0

我不明白这是如何帮助代码重复的问题。 – Cosmin 2015-02-20 13:42:28

0

命名空间只是一种组织类型的方法。在你的情况下,你有两个或更多不同的类具有相同签名但没有通用接口的方法。如果您无法更改类的代码,那么避免重复的唯一方法就是在释放编译时类型安全性的同时使用反射。

0

在让它们变得更好之前,我让事情变得更糟。

您可以将所有的AnimalType决策逻辑封装在一个类中。

两种类型(PigsFeet和HorseFeet),也有一些similiar方法... 由于WashFeet具有共同签名(空隙无PARAMS)之间,System.Action可用于引用该方法。其他具有公共签名(和参数)的方法可能需要System.Func(T)。没有共同签名的其他方法可能需要强制成一个共同的签名。

这里的客户端代码:

AnimalFeetFacade myFacade = new AnimalFeetFacade(_animalType); 
myFacade.WashFeet(); 

这里的封装类。

public class AnimalFeetFacade 
{ 
    public AnimalFeetFacade(AnimalType theType) 
    { 
    if (theType == AnimalType.Pig) 
    { 
     _washFeet = WashPigFeet; 
     //TODO reference more PigFeet methods here 
    } 
    else if (theType == AnimalType.Horse) 
    { 
     _washFeet = WashHorseFeet; 
     //TODO reference more HorseFeet methods here 
    } 
    else 
    { 
     throw new NotImplementedException("AnimalFeetFacade only works with PigFeet and HorseFeet"); 
    } 
    } 

    protected Action _washFeet; 

    public void WashFeet() 
    { 
    _washFeet.Invoke(); 
    } 

    protected void WashPigFeet() 
    { 
    PigFeet.Feet = new PigFeet.Feet() 
    feet.WashFeet() 
    } 

    protected void WashHorseFeet() 
    { 
    HorseFeet.Feet = new HorseFeet.Feet() 
    feet.WashFeet() 
    } 
} 
相关问题