2013-05-29 48 views
3

我正在为内部需求编写一个API,因此易用性是其中的重中之重。我想知道在下面的例子中我是否推得太过分了。具有许多参数的函数 - 将它们作为结构体

解决逆大地测量问题的函数需要两点的地理坐标,并计算它们之间的距离以及从每个点到另一个点的假设(角度)。

的易于使用的优化传统的解决方案可能看起来像(请不要介意名的长度,我知道有改进的余地):

class Angle; 
class GeoCoordinate; 
... 

struct InverseGeodeticOut 
{ 
    Angle forwardAzimuth; 
    Angle backAzimuth; 
    double distance; 
}; 

InverseGeodeticOut inverseGeodetic(const GeoCoordinate &firstPoint, 
            const GeoCoordinate &secondPoint); 
// or 
void inverseGeodetic(const GeoCoordinate &firstPoint, 
        const GeoCoordinate &secondPoint, 
        InverseGeodeticOut *result); 

我的问题是如何合理的将它是把它一步,以节省用户的一些打字:

class Angle; 
class GeoCoordinate; 
... 

struct InverseGeodetic 
{ 
    InverseGeodetic(); 
    InverseGeodetic(const GeoCoordinate &firstPoint, 
        const GeoCoordinate &secondPoint); 

    Angle forwardAzimuth; 
    Angle backAzimuth; 
    double distance; 
}; 

// so the usages would be 
InverseGeodeticOut inverse = inverseGeodetic(firstPoint, secondPoint); 

InverseGeodeticOut inverse; 
inverseGeodetic(firstPoint, secondPoint, &inverse); 

InverseGeodetic inverse(firstPoint, secondPoint); 

也许,在这个特殊的例子差别太小,不值得谈论,但我不知道这样的结构是一般的好。

+4

我对变量名长度没有问题。我宁愿立即知道我在看什么,然后猜测什么是invGeoOut意味着:) –

+1

一般来说,我不会设计我的代码以减少打字次数。为了清晰,可读性和可重用性,我设计了我的代码。所以选择最容易理解和使用的版本。 –

+1

这是重构[引入参数对象](http://sourcemaking.com/refactoring/introduce-parameter-object)。当然,一旦你这样做了,你也可以将行为移到它上面,并且不要传递它,并且你不敢写任何getter/setter。 –

回答

2

我喜欢你的第二个代码示例,但我发现公共构造函数有点令人困惑。特别是如果有其他方法来构建InverseGeodetic。我宁愿使用静态工厂方法来构造它。这样你就可以给方法一个更有意义的名字:

struct InverseGeodetic 
{ 
    Angle forwardAzimuth; 
    Angle backAzimuth; 
    double distance; 

    static InverseGeodetic FromTwoPoints(const GeoCoordinate &, const GeoCoordinate &); 
}; 

// usage 
auto inverse = InverseGeodetic::FromTwoPoints(a, b); 

但是那么这可能是我的C#背景流血通过。

+0

其实只有一种形式的逆大地问题总是需要两点。因此,预测用户混淆或未来扩展的原因并不多。但我仍然借用你的方式命名:)谢谢! –

相关问题