3

例如,我需要一个计算牛顿定律 F=MA 的函数,所以我在 C# 中编写了以下代码

private double calcForce(double mass, double acceleration){
        return mass * acceleration;
}

private double calcMass(double force, double acceleration){
        return force / acceleration;
}

private double calcAcceleration(double force, double mass){
        return force / mass;
}

如果数学函数具有少量变量(F=MA 只有 3 个),具有更复杂的函数(我的真正任务是处理很容易包含超过 10 个变量的传热/流体力学函数!),这很好用!方法的数量将等于该数学函数中的变量数。

那么,是否有任何好的设计模式可以解决这个问题。我应该使用这样的东西吗?

private double NewtonsLaw(double? force,double? mass,double? acceleration)
{
        if(!force.HasValue)
            return mass*acceleration;
        //else if
}

还有一件事,我需要用objective-c 和java 而不是C# 编写代码。

4

3 回答 3

0

我认为最好为每种可能的组合使用单独的方法,而不是让用户传递可空类型并将一个值设置为空。

如果您提供一个私有构造函数来获取所有值和一组公共静态工厂方法,每个方法都接受除一个值之外的所有值,它将使代码在调用点更清晰,这也意味着您不需要t 需要检查除一个值之外的所有值是否为非空值。

像这样的东西(用 C# 编写,但这个概念很容易转换为 Java 或 Objective C):

public class Newton
{
    readonly double _force;
    readonly double _mass;
    readonly double _accel;

    public double Force
    {
        get { return _force; }
    }

    public double Mass
    {
        get { return _mass; }
    }

    public double Accel
    {
        get { return _accel; }
    }

    public static Newton FromForceAndMass(double force, double mass)
    {
        return new Newton(force, mass, calcAccel(force, mass));
    }

    public static Newton FromForceAndAccel(double force, double accel)
    {
        return new Newton(force, calcMass(force, accel), accel);
    }

    public static Newton FromMassAndAccel(double mass, double accel)
    {
        return new Newton(calcForce(mass, accel), mass, accel);
    }

    private static double calcAccel(double force, double mass)
    {
         return force / mass;
    }

    private static double calcForce(double mass, double acceleration)
    {
        return mass * acceleration;
    }

    private static double calcMass(double force, double acceleration)
    {
        return force / acceleration;
    }

    private Newton(double force, double mass, double accel)
    {
        _force = force;
        _mass  = mass;
        _accel = accel;
    }
}

(不检查这些值是否被零除 - 您必须为此添加错误检查。)

那么在你调用它的地方,发生的事情就更明显了:

var newton = Newton.FromForceAndAccel(1.234, 6423.2);

这对单独方法的数量没有帮助,但它有一个很好的使用模式。

于 2013-07-03T06:47:53.880 回答
0

一种方法是使用您的质量/加速度/力值创建一个对象,并且(取决于设置的值)计算它们或只返回它们

public class NewtonLaw {
    private Double mass;
    private Double acceleration;
    private Double force;

    public NewtonLaw(Double mass, Double acceleration, Double force) {
        this.mass = mass;
        this.acceleration = acceleration;
        this.force = force;
    }

    public Double calcMass() {
        if (mass != null) {
            return mass;
        } else if (acceleration == null) {
            throw new IllegalStateException("Acceleration is not set");
        } else if (acceleration == 0) {
            throw new IllegalStateException("Acceleration is zero, cannot calculate the mass");
        } else if (force == null) {
            throw new IllegalStateException("Force is not set");
        } else {
            return force / acceleration;
        }
    }

    public Double calcAcceleration() {
        if (acceleration != null) {
            return acceleration;
        } else ...
    }

    public Double calcForce() {
        if (force != null) {
            return force;
        } else ...
    }
}

诚然,这只是一些计算的大量代码,但至少逻辑完全封装在对象中

于 2013-07-03T06:24:54.257 回答
0

无论您将使用何种模式,您都必须对新值的计算进行编码。因此,这意味着您的传热/流体力学问题至少有 10 个公式。

将所有这些都放在带有可选参数的同一方法中是一个坏主意,因为它会使您的代码更复杂(因此更多错误,更难维护等)。此外,您的论点顺序可能是错误的,然后计算出与您的东西不同的东西(您认为要计算质量,但您正在计算加速度)。

最好将这 10 个公式封装在单独的方法中。它将更容易实现任何错误检查/处理,并且更容易调试、测试和维护。

现在,您可以将这 10 个方法封装在一个对象中,为您提供一个方便您自己使用的接口。以前的评论包含好主意。选择一个适合你的。

于 2013-07-03T07:39:28.863 回答