大家好,
在我的场景中,要根据一列给定的参数组成的规则去对数据进行计算。
由于参数之间会有多种不同的组合,即会很多种不同的规则,那么计算方法自然就会不同。
请问,是否有成熟的程序设计经验(或设计模式)来解决此类问题?
谢谢!

解决方案 »

  1.   

    如果仅仅是计算,用shell试试
      

  2.   

    > java开源的规则引擎 Drools
    有点儿小题大作了orz> 你这个是算法的问题
    > 跟设计模式有什么关系呢
    我觉得这还谈不上算法。主要是希望把程序写得更优雅些。
    程序便于扩展,便于维护。
    因为在未来可能会添加新的参数和规则。
      

  3.   

    for example
    class Control {
        public static void main(String[] args) {
            Control control = new Control();
            Algorithm algorithm = AlgorithmManager.getAlgorithm(args);
            control.control(algorithm);
        }    public void control(Algorithm algorithm) {
            Object[] result = algorithm.calc();
            System.out.println(Arrays.toString(result));
        }
    }interface Algorithm {
        Object[] cacl();
    }class AlgorithmOne implements Algorithm {
        Object[] data;
        public AlgorithmOne(Object[] data) {
            this.data = Arrays.copyOf(data, data.length);
        }
        public Object[] cacl() {
            //do some calculation
        }
    }class AlgorithmTow implements Algorithm {
        Object[] data;
        public AlgorithmTow(Object[] data) {
            this.data = Arrays.copyOf(data, data.length);
        }
        public Object[] cacl() {
            //do some calculation
        }
    }
    ...
    class AlgorithmManager {
        static Algorithm getAlgorithm(Object[] data) {
            if (xxx) {
                return new AlgorithmOne(data);
            } else {
                return new AlgorithmTow(data);
            }
        }
    }
      

  4.   

    前几天学习了一下命令模式,你这个需求好像能用命令模式解。1. 意图
    将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队
    或记录请求日志,以及支持可撤消的操作。每一个算法可以看作不同的命令,命令模式的参与者。记录请求日志,以及支持可撤消的操作没实装
    • C o m m a n d
    — 声明执行操作的接口。
    • C o n c r e t e C o m m a n d 
    — 将一个接收者对象绑定于一个动作。
    — 调用接收者相应的操作,以实现E x e c u t e。
    • C l i e n t 
    — 创建一个具体命令对象并设定它的接收者。
    • Invoker 
    — 要求该命令执行这个请求。
    • R e c e i v e r 
    — 知道如何实施与执行一个请求相关的操作。任何类都可能作为一个接收者。
    7. 协作
    • C l i e n t创建一个C o n c r e t e C o m m a n d对象并指定它的R e c e i v e r对象。
    • 某I n v o k e r对象存储该C o n c r e t e C o m m a n d对象。与此对应的java• C o m m a n dpackage Algorism.Command;import Algorism.Result.Result;/**
     * 算法 命令
     * @author oushuuryuu
     */
    public interface Algorism<T> {
        /**
         * 执行计算
         * @return 计算结果
         */
        Result calculate();
    }• C o n c r e t e C o m m a n dpackage Algorism.ConcreteCommand;import Algorism.Command.Algorism;
    import Algorism.Receiver.Calculator;
    import Algorism.Result.ResultA;/**
     * 算法1 命令1
     * @author oushuuryuu
     */
    public class AlgorismOne<T> implements Algorism {    /**
         * 命令的接收者
         */
        Calculator _calculator;    /**
         * 参数保存
         */
        private T[] _params;    /**
         * 构造函数
         * @param params 本计算执行时需要的参数
         */
        public AlgorismOne(Calculator calculator, T[] params) {
            this._calculator = calculator;
            this._params = params;
        }    /**
         * 计算并返回结果,该结果为ResultA型
         * @return 计算器返回的结果
         */
        public ResultA calculate() {        return _calculator.calculateOne(_params);
        }}package Algorism.ConcreteCommand;import Algorism.Command.Algorism;
    import Algorism.Receiver.Calculator;
    import Algorism.Result.ResultB;/**
     * 算法2 命令2
     * @author oushuuryuu
     */
    public class AlgorismTwo<T> implements Algorism {    /**
         * 命令的接收者
         */
        Calculator _calculator;    /**
         * 参数保存
         */
        private T[] _params;    /**
         * 构造函数
         * @param params 本计算执行时需要的参数
         */
        public AlgorismTwo(Calculator calculator, T[] params) {
            this._calculator = calculator;
            this._params = params;
        }    /**
         * 计算并返回结果,该结果为ResultB型
         * @return 计算器返回的结果
         */
        public ResultB calculate() {        return _calculator.calculateTwo(_params);
        }}
    • C l i e n t ( A p p l i c t i o n )package Algorism.Client;import Algorism.Command.Algorism;
    import Algorism.ConcreteCommand.AlgorismOne;
    import Algorism.ConcreteCommand.AlgorismTwo;
    import Algorism.Invoker.Executor;
    import Algorism.Receiver.Calculator;
    import Algorism.Result.ResultA;
    import Algorism.Result.ResultB;
    import java.math.BigDecimal;/**
     * 调用者 客户
     * @author oushuuryuu
     */
    public class User {
        /**
         * 算法使用
         * @param args
         */
        public static void main(String[] args) {
            // 计算器 命令的接收者
            Calculator calculator = new Calculator();
            //算法1 命令1
            BigDecimal[] paramOne = new BigDecimal[]{new BigDecimal(1)};
            Algorism<BigDecimal> algorismOne = new AlgorismOne<BigDecimal>(calculator, paramOne);        //算法1 命令1
            String[] paramTwo = new String[]{"#ffffff"};
            Algorism<String> algorismTwo = new AlgorismTwo<String>(calculator, paramTwo);        //执行者
            Executor executor = new Executor(algorismOne, algorismTwo);        //算法1执行
            ResultA resultA = (ResultA)executor.calculateOne();
            resultA.print();        //算法2执行
            ResultB resultB = (ResultB)executor.calculateTwo();
            resultB.print();    }
    }
    • Invokerpackage Algorism.Invoker;import Algorism.Command.Algorism;
    import Algorism.Result.Result;/**
     * 命令的执行者
     * @author oushuuryuu
     */
    public class Executor {
        /**
         * 需执行的命令
         */
        private Algorism[] _algorisms;    /**
         * 构造函数
         * @param algorisms 需要执行的命令
         */
        public Executor(Algorism ... algorisms) {
            this._algorisms = algorisms;
        }    /**
         * 算法1 命令1执行
         * @return
         */
        public Result calculateOne() {
            return _algorisms[0].calculate();
        }    /**
         * 算法2 命令2执行
         * @return
         */
        public Result calculateTwo() {
            return _algorisms[1].calculate();
        }
    }
    • R e c e i v e rpackage Algorism.Receiver;import Algorism.Result.ResultA;
    import Algorism.Result.ResultB;/**
     * 计算器 命令的接收者
     * @author oushuuryuu
     */
    public class Calculator {
        /**
         * 算法1执行
         * @param params
         * @return
         */
        public ResultA calculateOne(Object ... params) {
            ResultA result = new ResultA();        /*-------------         在这里写具体计算逻辑
             *
             */        return result;
        }    /**
         * 算法2执行
         * @param params
         * @return
         */
        public ResultB calculateTwo(Object ... params) {
            ResultB result = new ResultB();        /*-------------         在这里写具体计算逻辑
             *
             */        return result;
        }
    }
    • 增加灵活性的自创类与接口package Algorism.Result;/**
     * 计算结果
     * @author oushuuryuu
     */
    public interface Result<T> {
        /**
         * 计算结果取得
         * @return
         */
        T getResult();    /**
         * 结果设定
         * @param t
         */
        void setResult(T result);    /**
         * 结果打印
         */
        void print();
    }package Algorism.Result;import java.math.BigDecimal;/**
     * 结果种类1 BigDecimal
     * @author oushuuryuu
     */
    public class ResultA implements Result<BigDecimal> {    /**
         * 结果
         */
        private BigDecimal _result;    /**
         * 结果取得
         * @return
         */
        public BigDecimal getResult() {
            return _result;
        }    /**
         * 结果设定
         * @param result
         */
        public void setResult(BigDecimal result) {
            _result = result;
        }    /**
         * 结果打印
         */
        public void print() {
            /**
             * 结果打印实装
             */
        }}package Algorism.Result;import java.math.BigDecimal;/**
     * 结果种类1 BigDecimal数组
     * @author oushuuryuu
     */
    public class ResultB implements Result<BigDecimal[]> {    /**
         * 结果
         */
        private BigDecimal[] _result;    /**
         * 结果取得
         * @return
         */
        public BigDecimal[] getResult() {
            return _result;
        }    /**
         * 结果设定
         * @param result
         */
        public void setResult(BigDecimal[] result) {
            _result = result;
        }    /**
         * 结果打印
         */
        public void print() {
            /**
             * 结果打印实装
             */
        }}
      

  5.   

    ……
    不知道楼主想要做什么。
    你有具体应用再说吧。
    如果是为了学习可以用23种模式分别解一次,然后就知道好坏了。
    做程序也好,用模式也好绝对不是把简单的问题复杂化。
    我用模式解也纯粹是为了练习一下自己的学习成果。
    其实,在真正的项目里,你的这个需求只需要做到一个util的类里,不同的算法用不同的方法来处理就可以了。如果想提高扩展性做个接口就行了。
    如果用模式把你的这个功能集成到项目中根本就没有意义,而且还会造成项目的总体结构混乱。