面向对象的方法设计选项

时间:2009-02-03 12:11:26

标签: c# oop

我想开发一个process()方法。该方法以数据类的形式获取一些数据并对其进行处理。数据类很相似,但略有不同。

例如,我们有以下数据类processDataObject_A,processDataObject_B和processDataObject_C。

重载方法是否更好:

void process(processDataObject_A data)
{
//Process processDataObject_A here
}

void process(processDataObject_B data)
{
//Process processDataObject_B here
}

void process(processDataObject_C data)
{
//Process processDataObject_C here
}

或者让具体数据类扩展一些抽象数据类,并将其传递给流程方法,然后让方法检查类型并采取相应的行动:

void process(AbstractProcessDataObject data)
{
//Check for type here and do something  
}

还有更好的解决方法吗?如果这是一个Web方法,那么方法会改变吗?

提前致谢

5 个答案:

答案 0 :(得分:8)

我会选择:

process (data) {
   data.doProcessing();
}

答案 1 :(得分:1)

你的方法失效的事实让我相信你可能会让你的责任得到扭转。我认为考虑这一点可能会更好,因为让每个类都实现一个定义IProcessable方法的接口Process。然后每个类都知道如何操纵它自己的数据。我认为,这比一个操纵每个对象内部数据的类更少耦合。假设所有这些类派生自相同的基类,您可以放置​​在基类中共享的处理算法片段。

这与您可能有多个算法操作相同数据的情况略有不同。如果您需要此类功能,那么您可能仍希望实现该接口,但让Process方法采用策略类型参数并使用工厂根据其类型创建适当的策略。你最终会以这种方式为每个支持的算法和数据类对建立一个策略类,但是你可以保持代码解耦。如果算法相当复杂,我可能只会这样做,因此分离代码使其更具可读性。如果它只是几行不同,那么在策略类型上使用switch语句可能就足够了。

关于网络方法,我认为每个班级都有不同的签名。如果方法采用各个类型的具体类,那么正确地通过线路获取数据会更容易,因此它知道如何正确地序列化/反序列化它。当然,在后端,Web方法可以使用上述方法。

public interface IProcessable
{
    public void Process() {....}
}

public abstract class ProcessableBase : IProcessable
{
    public virtual void Process()
    {
        ... standard processing code...
    }
}

public class FooProcessable : ProcessableBase
{
    public override void Process()
    {
        base.Process();
        ... specific processing code
    }
}

...

IProcessable foo = new FooProcessable();
foo.Process();

实施基于策略的机制有点复杂。

使用数据访问对象的Web界面

[WebService]
public class ProcessingWebService
{
    public void ProcessFoo( FooDataObject foo )
    {
        // you'd need a constructor to convert the DAO
        // to a Processable object.
        IProcessable fooProc = new FooProcessable( foo );
        fooProc.Process();
    }

}

答案 2 :(得分:1)

我是Marko的第二个设计。 想象一下,您需要添加另一种类型的数据结构和流程逻辑,比如processDataObject_D。使用您的第一个提议的解决方案(方法重载),您将不得不通过添加另一个方法来修改该类。使用第二个提议的解决方案,您将不得不在类型检查和执行语句中添加另一个条件。两者都要求您修改现有代码。 Marko的解决方案是避免通过利用多态来修改现有代码。您不必编写if-else类型检查代码。它允许您添加新的数据结构和流程逻辑,而无需修改现有代码,只要新类继承相同的超类。

研究设计模式的战略模式将使您对所面临的问题有充分的理论认识。 O'Reilly的“Head First Design Pattern”这本书是我所知道的最好的介绍。

答案 3 :(得分:0)

AbstractProcessDataObject上的多态性如何 - 即虚拟方法?如果这不合适(关注点分离等),那么过载似乎更合适。

网络方法;非常不同:既不支持多态也不重载(至少不支持基本配置文件)。检测选项“在此处检查并执行某些操作”可能是最佳途径。或者为每种类型使用不同的命名方法。


按要求:

abstract class SomeBase { // think: AbstractProcessDataObject
    public abstract void Process();
}
class Foo : SomeBase {
    public override void Process() { /* do A */ }
}
class Bar : SomeBase {
    public override void Process() { /* do B */ }
}
SomeBase obj = new Foo();
obj.Process();

答案 4 :(得分:0)

我相信Strategy pattern可以帮到你。