简体   繁体   English

面向对象的方法设计选项

[英]Object Oriented Method Design options

I want to develop a process() method. 我想开发一个process()方法。 The method takes some data in the form of a data class, and processes it. 该方法以数据类的形式获取一些数据,并对其进行处理。 The data classes are similar, but slightly different. 数据类相似,但略有不同。

For example we have the following classes of data processDataObject_A, processDataObject_B and processDataObject_C. 例如,我们具有以下类别的数据:processDataObject_A,processDataObject_B和processDataObject_C。

Is it better to overload the method: 重载该方法是否更好:

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
}

OR have the concrete data classes extend some Abstract Data Class, and pass that to the process method and then have the method check the type and act accordingly: 或让具体的数据类扩展某些抽象数据类,并将其传递给处理方法,然后使该方法检查类型并采取相应的行动:

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

OR is there some better way to address it? 还是有更好的解决方法? Would the approach change if this were to be a Web Method? 如果这将是一个Web方法,方法是否会改变?

Thanks in advance 提前致谢

I would go with: 我会去:

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

The fact that your methods return void lead me to believe that you may have your responsibilities turned around. 您的方法返回无效的事实使我相信您可能会承担责任。 I think it may be better to think about this as having each of your classes implement an interface, IProcessable , that defines a Process method. 我认为最好考虑一下,因为让每个类都实现一个接口IProcessable ,该接口定义了Process方法。 Then each class would know how to manipulate it's own data. 然后,每个类都将知道如何处理自己的数据。 This, I think, is less coupled than having a class which manipulates data inside each object. 我认为,这比拥有一个在每个对象中操纵数据的类要少。 Assuming all of theses classes derive from the same base class you could put the pieces of the processing algorithm that are shared in the base class. 假设所有这些类都源自同一基类,则可以将在基类中共享的处理算法片段放入其中。

This is slightly different than the case where you may have multiple algorithms that operate on identical data. 这可能与您有多个对相同数据进行运算的算法有所不同。 If you need this sort of functionality then you may still want to implement the interface, but have the Process method take a strategy type parameter and use a factory to create an appropriate strategy based on its type. 如果需要这种功能,则可能仍要实现该接口,但让Process方法采用策略类型参数,并使用工厂根据其类型创建适当的策略。 You'd end up having a strategy class for each supported algorithm and data class pair this way, but you'd be able keep the code decoupled. 这样,您最终将为每个受支持的算法和数据类对都有一个策略类,但是您可以使代码保持解耦。 I'd probably only do this if the algorithms were reasonably complex so that separating the code makes it more readable. 我可能只会在算法相当复杂的情况下才这样做,以便将代码分开使代码更具可读性。 If it's just a few lines that are different, using the switch statement on the strategy type would probably suffice. 如果只是几行不同,则在策略类型上使用switch语句可能就足够了。

With regard to web methods, I think I'd have a different signature per class. 关于网络方法,我想我每个班级都有不同的签名。 Getting the data across the wire correctly will be much easier if the methods take concrete classes of the individual types so it knows how to serialize/deserialize it properly. 如果这些方法采用了各个类型的具体类,则可以更轻松地正确获取数据,从而知道如何正确地对数据进行序列化/反序列化。 Of course, on the back end the web methods could use the approach described above. 当然,在后端,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();

Implementing the strategy-based mechanism is a little more complex. 实施基于策略的机制要复杂一些。

Web interface, using data access objects 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();
    }

}

I second Marko's design. 我支持Marko的设计。 Imagine you need to add another type of data structure and process logic, say processDataObject_D. 假设您需要添加另一种类型的数据结构和流程逻辑,例如processDataObject_D。 With your first proposed solution (method overloading), you will have to modify the class by adding another method. 使用第一个建议的解决方案(方法重载),您将必须通过添加另一个方法来修改类。 With your second proposed solution, you will have to add another condition to the type checking and execution statement. 使用第二个建议的解决方案,您将不得不在类型检查和执行语句中添加另一个条件。 Both requires you to modify the existing code. 两者都需要您修改现有代码。 Marko's solution is to avoid modifying the existing code by leveraging polymorphism . Marko的解决方案是避免利用多态来修改现有代码。 You don't have to code if-else type checking. 您无需编写if-else类型检查代码。 It allows you to add new data structure and process logic without modifying the existing code as long as the new class inherits the same super class. 只要新类继承了相同的超类,就可以在不修改现有代码的情况下添加新的数据结构和过程逻辑。

Studying Strategy Pattern of the design patterns will give you full theoritical understanding of the problem you are facing. 学习设计模式的策略模式将使您对所面临的问题有完整的理论理解。 The book "Head First Design Pattern" from O'Reilly is the best introduction I know of. O'Reilly的《 Head First设计模式》一书是我所知道的最好的介绍。

How about polymorphism on AbstractProcessDataObject - ie a virtual method? 如何在AbstractProcessDataObject多态-即虚拟方法? If this isn't appropriate (separation of concerns etc), then the overload would seem preferable. 如果这不合适(关注点分离等),那么过载似乎是可取的。

Re web-methods; 重新网络方法; very different: neither polymorphism nor overloading are very well supported (at least, not on basic-profile). 非常不同:既没有很好地支持多态性也没有支持重载(至少在基本配置文件中没有)。 The detection option "Check for type here and do something" might be the best route. 检测选项“在此处检查类型并执行某些操作”可能是最好的方法。 Or have different named methods for each type. 或为每种类型使用不同的命名方法。


per request: 每个请求:

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();

我相信该策略模式会为您提供帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM