Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Language agnostic 如何设计一个只有一个重载工作方法和数据返回其他方法的类?_Language Agnostic_Oop - Fatal编程技术网

Language agnostic 如何设计一个只有一个重载工作方法和数据返回其他方法的类?

Language agnostic 如何设计一个只有一个重载工作方法和数据返回其他方法的类?,language-agnostic,oop,Language Agnostic,Oop,我想设计一个类,将字符串解析为对我的应用程序有意义的标记 我该如何设计它 提供一个接受字符串的ctor,提供一个解析方法,并提供返回单个令牌、令牌计数等的方法(我们称之为“minor”),或者 提供一个不接受任何内容的ctor,提供一个接受字符串的解析方法和上面提到的次要方法。或 提供一个接受字符串且只提供次要方法但不提供解析方法的ctor。解析由ctor完成 1和2的缺点是,用户可以调用次要方法而不调用解析方法。我必须检查调用解析方法的每个次要方法 我在3中看到的问题是,parse方法可能会做

我想设计一个类,将字符串解析为对我的应用程序有意义的标记

我该如何设计它

  • 提供一个接受字符串的ctor,提供一个解析方法,并提供返回单个令牌、令牌计数等的方法(我们称之为“minor”),或者
  • 提供一个不接受任何内容的ctor,提供一个接受字符串的解析方法和上面提到的次要方法。或
  • 提供一个接受字符串且只提供次要方法但不提供解析方法的ctor。解析由ctor完成
  • 1和2的缺点是,用户可以调用次要方法而不调用解析方法。我必须检查调用解析方法的每个次要方法

    我在3中看到的问题是,parse方法可能会做很多事情。把它放在ctor里似乎是不对的

    2很方便,因为用户可以解析任意数量的字符串,而无需反复实例化该类

    什么是好方法?有哪些考虑因素

    (如果有人在乎的话,语言是c#)


    谢谢

    我将拥有一个单独的类,该类带有一个Parse方法,该方法接受一个字符串,并将其转换为一个单独的新对象,该对象中的每个值都有一个属性

    ValueObject values = parsingClass.Parse(theString);
    

    我认为这是一个非常好的问题

    一般来说,我会选择类似于上面选项3的东西。基本上,想想你的班级和它做什么;除了要解析的数据和解析的令牌之外,它是否有任何有效的数据?如果没有,那么我通常会说,如果你没有这些东西,那么你就没有你的类的实例;您有一个不完整的类实例;你想避免的事情

    您指出的一个注意事项是,令牌的解析可能是一个计算相对复杂的过程;这可能需要一段时间。我同意你的观点,你可能不想因为在构造器中这样做而受到打击;在这种情况下,使用Parse()方法可能有意义。然而,问题是在parse()方法完成之前,是否可以对类执行任何合理的操作。如果没有,那么你回到了原点;在parse()方法完成之前,您实际上处于类的“不完整实例”状态;也就是说,它实际上是无用的。当然,如果您愿意并且能够在应用程序中使用一些多线程,这一切都会改变;如果您愿意将计算复杂的操作卸载到另一个线程上,并在完成之前在类方法/访问器上保持某种同步,那么整个parse()工作就更有意义,因为您可以选择在一个新线程中完全生成它。不过,您仍然会遇到一些问题,即在完全解析类之前尝试使用它

    不过,我认为这个设计中还有一个更广泛的问题,那就是这个代码的使用范围有多大?这段代码的用途是什么?我的意思是,不仅仅是现在,在预期用途中,这段代码是否有可能随着应用程序的发展而增长或改变?就实现的稳定性而言,您能期望它是完全稳定的吗,或者您希望解析的数据集、要解析的数据的大小或您将解析到的令牌是否可能在将来发生变化?如果实施有可能改变,考虑所有可能改变的方式;根据我的经验,这些考虑因素可能会导致一种或另一种实现。考虑到这些事情并不是微不足道的;不可能


    为了避免你认为这只是吹毛求疵,我会说,保守估计,在我编写的类中,大约10-15%的类甚至在项目完成之前就需要某种程度的重构;很少有一个设计,我工作过的幸存下来的实现出来的另一面,它看起来像以前一样。因此,考虑实现的可能排列对于确定您的实现应该是什么非常有用。比如说,如果您的实现永远不可能改变要标记化的字符串的大小,那么您可以假设计算复杂性,这可能会导致您在总体设计上出现这样或那样的情况。

    如果类的唯一目的是将输入字符串解析为一组属性,那么我看不出选项3有任何真正的缺点。解析操作可能很昂贵,但如果要使用它,您必须在某个时候执行它

    您提到选项2很方便,因为您可以在不重新实例化对象的情况下解析新值,但是如果解析操作非常昂贵,我认为这没有多大区别。比较以下代码:

    // Using option 3
    ParsingClass myClass = new ParsingClass(inputString);
    
    // Parse a new string.
    myClass = new ParsingClass(anotherInputString);
    
    // Using option 2
    ParsingClass myClass = new ParsingClass();
    myClass.Parse(inputString);
    
    // Parse a new string.
    myClass.Parse(anotherInputString);
    
    在使用上并没有太大区别,但对于选项2,您必须检查所有次要方法和属性,以查看是否已进行解析,然后才能继续。(选项1要求您在内部完成选项2所做的一切,但也允许您在使用它时编写选项3样式的代码。)

    或者,您可以将构造函数设置为私有,并将解析方法设置为静态,让解析方法返回对象的实例

    // Option 4
    ParsingClass myClass = ParsingClass.Parse(inputString);
    
    // Parse a new string.
    myClass = ParsingClass.Parse(anotherInputString);
    

    选项1和2提供了更大的灵活性,但需要更多的代码来实现。选项3和4的灵活性较低,但要编写的代码也较少。基本上,这个问题没有一个正确的答案。这实际上是一个什么最适合您现有的代码的问题。

    两个重要的注意事项:

    1) 解析会失败吗

    如果是这样,并且如果你把它放在构造函数中,那么它必须抛出一个异常。解析方法