Language agnostic 如何设计一个只有一个重载工作方法和数据返回其他方法的类?
我想设计一个类,将字符串解析为对我的应用程序有意义的标记 我该如何设计它Language agnostic 如何设计一个只有一个重载工作方法和数据返回其他方法的类?,language-agnostic,oop,Language Agnostic,Oop,我想设计一个类,将字符串解析为对我的应用程序有意义的标记 我该如何设计它 提供一个接受字符串的ctor,提供一个解析方法,并提供返回单个令牌、令牌计数等的方法(我们称之为“minor”),或者 提供一个不接受任何内容的ctor,提供一个接受字符串的解析方法和上面提到的次要方法。或 提供一个接受字符串且只提供次要方法但不提供解析方法的ctor。解析由ctor完成 1和2的缺点是,用户可以调用次要方法而不调用解析方法。我必须检查调用解析方法的每个次要方法 我在3中看到的问题是,parse方法可能会做
谢谢我将拥有一个单独的类,该类带有一个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) 解析会失败吗 如果是这样,并且如果你把它放在构造函数中,那么它必须抛出一个异常。解析方法