Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/418.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
带验证的JavaScript链接生成器_Java_Javascript_Validation_Interface_Builder - Fatal编程技术网

带验证的JavaScript链接生成器

带验证的JavaScript链接生成器,java,javascript,validation,interface,builder,Java,Javascript,Validation,Interface,Builder,在这个Java类中,请注意构造函数是如何被禁止使用的,并被指导实例化和进行验证的接口驱动构建器所取代 public class Position implements Serializable { private BigDecimal capital; private BigDecimal tolerableRiskInPercentOfCapitalPerTrade; private Direction direction; private BigDecima

在这个Java类中,请注意构造函数是如何被禁止使用的,并被指导实例化和进行验证的接口驱动构建器所取代

public class Position implements Serializable {

    private BigDecimal capital;
    private BigDecimal tolerableRiskInPercentOfCapitalPerTrade;
    private Direction direction;
    private BigDecimal pricePerUnit;
    private BigDecimal stopLossPricePerUnit;

    private Position(){}

    public final BigDecimal getTotalTolerableRiskPerTrade() {
        return capital.multiply(tolerableRiskInPercentOfCapitalPerTrade.divide(new BigDecimal(100)));
    }

    public final BigDecimal getStopLossPerUnitLoss() {
        if (direction.equals(Direction.LONG)){
            return pricePerUnit.subtract(stopLossPricePerUnit);
        } else {
            return stopLossPricePerUnit.subtract(pricePerUnit);
        }
    }

    public final BigDecimal getStopLossTotalLoss() {
        return getStopLossPerUnitLoss().multiply(getUnitsToBuy());
    }

    public final BigDecimal getUnitsToBuy() {
        BigDecimal result = getTotalTolerableRiskPerTrade().divide(getStopLossPerUnitLoss(), 0, BigDecimal.ROUND_DOWN);
        if (capital.compareTo(result.multiply(pricePerUnit)) != 1){
            return new BigDecimal(0);
        } else {
            return result;
        }
    }

    public final BigDecimal getTotal() {
        return getUnitsToBuy().multiply(pricePerUnit);
    }

    public static ICapital builder(){
        return new Builder();
    }

    public interface ICapital {
        ITolerableRiskInPercentOfCapitalPerTrade capital(final BigDecimal capital);
    }

    public interface ITolerableRiskInPercentOfCapitalPerTrade {
        IDirection tolerableRiskInPercentOfCapitalPerTrade(final BigDecimal tolerableRiskInPercentOfCapitalPerTrade);
    }

    public interface IDirection {
        IPricePerUnit direction(final Direction direction);
    }

    public interface IPricePerUnit {
        IStopLossPricePerUnit pricePerUnit(final BigDecimal pricePerUnit);
    }

    public interface IStopLossPricePerUnit {
        IBuild stopLossPricePerUnit(final BigDecimal stopLossPricePerUnit);
    }

    public interface IBuild {
        Position build();
    }

    private static class Builder implements ICapital, ITolerableRiskInPercentOfCapitalPerTrade, IDirection, IPricePerUnit, IStopLossPricePerUnit, IBuild {
        private final Position instance = new Position();

        @Override
        public Position build() {
            return instance;
        }

        @Override
        public ITolerableRiskInPercentOfCapitalPerTrade capital(final BigDecimal capital) {
            basicValidate(capital);
            instance.capital = capital;
            return this;
        }

        @Override
        public IDirection tolerableRiskInPercentOfCapitalPerTrade(final BigDecimal tolerableRiskInPercentOfCapitalPerTrade) {
            basicValidate(tolerableRiskInPercentOfCapitalPerTrade);
            if (tolerableRiskInPercentOfCapitalPerTrade.compareTo(new BigDecimal(100)) != -1) {
                throw new IllegalArgumentException("riskInPercent must be lower than 100");
            }
            instance.tolerableRiskInPercentOfCapitalPerTrade = tolerableRiskInPercentOfCapitalPerTrade;
            return this;
        }

        @Override
        public IPricePerUnit direction(final Direction direction) {
            if (direction==null) {
                throw new IllegalArgumentException("argument can't be null");
            }
            instance.direction = direction;
            return this;
        }

        @Override
        public IStopLossPricePerUnit pricePerUnit(final BigDecimal pricePerUnit) {
            basicValidate(pricePerUnit);
            instance.pricePerUnit = pricePerUnit;
            return this;
        }

        @Override
        public IBuild stopLossPricePerUnit(final BigDecimal stopLossPricePerUnit) {
            basicValidate(stopLossPricePerUnit);
            if (instance.direction.equals(Direction.LONG) && instance.pricePerUnit.compareTo(stopLossPricePerUnit) != 1) {
                throw new IllegalArgumentException("price must be higher than stopLossPrice");
            }

            if (instance.direction.equals(Direction.SHORT) && stopLossPricePerUnit.compareTo(instance.pricePerUnit) != 1) {
                throw new IllegalArgumentException("stopLossPrice must be higher than price");
            }
            instance.stopLossPricePerUnit = stopLossPricePerUnit;
            return this;
        }
    }

    protected static void basicValidate(final BigDecimal bigDecimal) {
        if (bigDecimal == null) {
            throw new IllegalArgumentException("argument can't be null");
        }
        if (!(bigDecimal.signum() > 0)) {
            throw new IllegalArgumentException("argument must have positive signum");
        }
    }
}
导致像这样的实例化

Position.builder()
        .capital(new BigDecimal(10000))
        .tolerableRiskInPercentOfCapitalPerTrade(new BigDecimal(2))
        .direction(Direction.LONG)
        .pricePerUnit(new BigDecimal(25))
        .stopLossPricePerUnit(new BigDecimal(24))
        .build();

尝试在不同语言之间移植代码并不容易,相同的功能不可能也不应该出现。也就是说,有没有办法在JavaScript中模拟类似的功能?(如有必要,也可以通过一些模块/库)

有几种方法可以做到这一点

一种选择是几乎完全相同的方式:使用具有指定细节的方法的生成器对象和调用以获取最终对象的
build
方法(或类似方法)。生成对象的结果调用看起来几乎完全相同(模类型名称等等)

另一个选项是利用JavaScript的对象初始值设定项语法(也称为“对象文字”)来拥有一个“选项”对象,您可以将其传递到
位置的构造函数中,如下所示:

function Position(options) {
    if (/*...the options aren't valid...*/) {
        throw new Error(/*...*/);
    }
    this.capital = options.capital;
    // ...
}
用法:

var p = new Position({
    capital: 10000,
    tolerableRiskInPercentOfCapitalPerTrade: 2,
    direction: Direction.LONG,
    pricePerUnit: 25,
    stopLossPricePerUnit: 24
});
在构造函数中,如果要将
选项中的数据直接用作新实例的属性,可以使用函数top将其复制到:

function applyOptions(instance, options) {
    Object.keys(options).forEach(function(key) {
        instance[key] = options[key];
    });
    return instance;
}
然后:

(如果使用jQuery,它有一个基本上可以做到这一点的函数;如果使用下划线,它有和。)


但是,如果要在将选项存储为新实例的属性之前对其进行一些操作,那么像这样的盲拷贝就不太理想了。

旁注:我看到您在上面使用了大量的
BigDecimal
。JavaScript的本机数字类型使用IEEE-754双精度值(就像Java的
double
一样),因此存在
double
所具有的精度问题。如果这是一个问题,您将需要为JavaScript找到一个类似于
BigDecimal
的库(有几种选择,包括[我没有使用过它,也不能担保,但它已经存在了一段时间])。
function Position(options) {
    if (/*...the options aren't valid...*/) {
        throw new Error(/*...*/);
    }
    applyOptions(this, options);
}