繁体   English   中英

如何在java中扩展这种通用转换器的设计?

[英]How to extend this design for a generic converter in java?

这是一个小货币转换器代码段:

 public enum CurrencyType {

        DOLLAR(1),
        POUND(1.2),
        RUPEE(.25);

        private CurrencyType(double factor) {
            this.factor = factor;
        }
        private double factor; 

        public double getFactor() {
            return factor;
        }

    }

    public class Currency {

        public Currency(double value, CurrencyType type) {
            this.value = value;
            this.type = type;
        }

        private CurrencyType type;
        private double value;

        public CurrencyType getCurrencyType() {
            return type;
        }

        public double getCurrencyValue() {
            return value;
        }

        public void setCurrenctyValue(double value){
            this.value = value;
        }

    }

public class CurrencyConversion {


    public static Currency convert(Currency c1, Currency c2)
            throws Exception {
        if (c1 != null && c2 != null) {
            c2.setCurrenctyValue(c1.getCurrencyValue()
                    * c1.getCurrencyType().getFactor()
                    * c2.getCurrencyType().getFactor());
            return c2;
        } else
            throw new Exception();
    }


}

我想改进这个代码,使其适用于不同的转换单位,例如:kgs到磅,英里到公里等等。看起来像这样的东西:

public class ConversionManager<T extends Convertible> {


    public T convert(T c1, T c2) 
    {
        //return null;
    }
}

感谢您的想法和建议。

在我看来,这是面向对象的方式。 请注意,您也可以对数据类型进行模板化,但我在这里只使用了双精度数,因为它们可以表示任何标量单位。 这提供了一种处理不同指标单位之间转换的好方法,如您所问:距离,货币,质量等。

public interface Metric {
    public String getReferenceUnit();
}

public class Distance implements Metric {
    public String getReferenceUnit() {
        return new String("Meters");
    }
}

public interface Units<T extends Metric> {
    public double getToReferenceFactor();
}

public class Kilometers implements Units<Distance> {
    public double getToReferenceFactor() {
        return 1000;
    }
}

static <T extends Metric> double convert(Units<T> from, Units<T> to) {
    return from.getToReferenceFactor() * (1.0 / to.getToReferenceFactor());
}

遗憾的是,java中的枚举不支持接口或超类(我想找出正确的原因)。

你可以做的是在你的枚举类型上声明一个注释(例如@Convertible),并使用反射访问它的因子。 这非常难看,你将无法在泛型中使用“T extends Convertible”表达式。

这是一个使用空心矩阵的通用转换器,它使用传递闭合来组合已知的转换器。 在这种情况下,它转换长度单位:

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Converter {
    private static final Map<String, Map<String, Double>> FACTOR_MAP
            = new HashMap<String, Map<String, Double>>();

    public static double convert(String from, String to, double value) {
        List<Step> stack = new ArrayList<Step>();
        stack.add(new Step(from, value));
        while (!stack.isEmpty()) {
            Step s = stack.remove(0);
            double val = s.value;
            String source = s.unit;
            if (source.equals(to)) {
                return val;
            }
            Map<String, Double> map = FACTOR_MAP.get(source);
            if (map != null) {
                for (Map.Entry<String,Double> entry: map.entrySet()) {
                    stack.add(new Step(entry.getKey(), val*entry.getValue()));
                }
            }
        }
        throw new IllegalArgumentException("Cannot not convert from " + from
                + " to " + to);
    }

    public static void registerFactor(String from, String to, double factor) {
        putFactor(from, to, factor);
        putFactor(to, from, 1.0/factor);
    }

    private static void putFactor(String from, String to, double factor) {
        Map<String, Double> map = FACTOR_MAP.get(from);
        if (map == null) {
            map = new HashMap<String, Double>();
            FACTOR_MAP.put(from, map);
        }
        map.put(to, factor);
    }

    static {
        registerFactor("cm", "mm", 10);
        registerFactor("in", "cm", 2.54);
        registerFactor("in", "pt", 72);
        registerFactor("pc", "pt", 12);
        registerFactor("px", "mm", 0.28);
    }

    private static class Step {
        private String unit;
        private double value;

        Step(String unit, double value) {
            this.unit = unit;
            this.value = value;
        }
    }
}

以下程序:

public class Main {
    private static final String UNITS[] = {"cm", "mm", "in", "pt", "pc", "px"};

    public static void main(String[] args) {
        for (String unit1: UNITS) {
            for (String unit2: UNITS) {
                System.out.println("1" + unit1 + " = "
                        + Converter.convert(unit1, unit2, 1) + unit2);
            }
        }
    }
}

给出以下结果:

1cm = 1.0cm
1cm = 10.0mm
1cm = 0.39370078740157477in
1cm = 28.346456692913385pt
1cm = 2.3622047244094486pc
1cm = 35.71428571428571px
1mm = 0.1cm
1mm = 1.0mm
1mm = 0.03937007874015748in
1mm = 2.8346456692913384pt
1mm = 0.23622047244094485pc
1mm = 3.571428571428571px
1in = 2.54cm
1in = 25.4mm
1in = 1.0in
1in = 72.0pt
1in = 6.0pc
1in = 90.71428571428571px
1pt = 0.035277777777777776cm
1pt = 0.35277777777777775mm
1pt = 0.013888888888888888in
1pt = 1.0pt
1pt = 0.08333333333333333pc
1pt = 1.2599206349206347px
1pc = 0.42333333333333334cm
1pc = 4.233333333333333mm
1pc = 0.16666666666666666in
1pc = 12.0pt
1pc = 1.0pc
1pc = 15.119047619047619px
1px = 0.028000000000000004cm
1px = 0.28mm
1px = 0.011023622047244094in
1px = 0.7937007874015748pt
1px = 0.06614173228346457pc
1px = 1.0px

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM