【COCOMO基本模型计算】

本文详细探讨了COCOMO(Constructive Cost Model)基本模型的原理,阐述了如何使用COCOMO模型来估算软件开发成本。通过实例分析,展示了在Java项目中如何应用该模型进行成本预测,帮助读者理解COCOMO模型在实际开发中的重要性和实用性。
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Locale;
import java.util.Scanner;

public class CocomoApp {

    public static void main(String[] args) {
        System.out.println(NOTICE);
        Scanner scanner = new Scanner(System.in);

        String inputLine;
        while (null != (inputLine = scanner.nextLine()) && isNotExit(inputLine)) {
            //Select COCOMO Mode to use
            int mode = getCocoMode(inputLine);
            System.out.println("User selected: " + inputLine);

            //BASE COCOMO MODE
            if (mode == COCO_MODE_BASE) {
                //get value of kdsi for develop
                double devKdsi = getDevKdsi(scanner);

                //let user choose what develop mode they use
                mode = getDevMode(scanner, mode);

                //get predict of modify kdsi
                double modifyKdsi = getModifyKdsi(scanner);

                //calculate
                base(devKdsi, mode, modifyKdsi);
            } else {
                System.out.println("WOW HOO! NOT YET!");
            }
            System.out.println(NOTICE);
        }
    }

    /**
     * get predict of modify kdsi
     *
     * @param scanner
     * @return
     */
    private static double getModifyKdsi(Scanner scanner) {
        double act = DEFAULT_MODIFY;
        try {
            System.out.println("Please type modify KDSI (Default " + DEFAULT_MODIFY + "): ");
            act = Double.parseDouble(scanner.nextLine());
        } catch (Exception e) {
            System.out.println("Use default modify KDSI of" + DEFAULT_MODIFY + ". ");
        }
        return act;
    }

    /**
     * When user leave they can text for these two commands
     *
     * @param inputLine
     * @return
     */
    private static boolean isNotExit(String inputLine) {
        return !CMD_EXIT.equals(inputLine.toLowerCase(Locale.ROOT)) &&
                !CMD_QUIT.equals(inputLine.toLowerCase(Locale.ROOT));
    }

    /**
     * let user choose what develop mode they use
     *
     * @param scanner
     * @param mode    default mode
     * @return
     */
    private static int getDevMode(Scanner scanner, int mode) {
        String inputLine;
        System.out.println("Please type develop mode: [1]organize(default) [2]half-separate [3]embed");
        inputLine = scanner.nextLine();
        try {
            mode = Integer.parseInt(inputLine);
        } catch (Exception e) {
            System.out.println("Use organize mode for calculate.");
        }
        return mode;
    }

    /**
     * get value of kdsi for develop
     *
     * @param scanner
     * @return
     */
    private static double getDevKdsi(Scanner scanner) {
        String inputLine;
        System.out.println("Please type develop KDSI(Default 5 KDSI): ");
        inputLine = scanner.nextLine();
        double devKdsi = DEFAULT_DEV_KDSI;
        try {
            devKdsi = Double.parseDouble(inputLine);
        } catch (Exception e) {
            System.out.println("Use default develop KDSI of 5");
        }
        return devKdsi;
    }

    /**
     * Select COCOMO Mode to use
     *
     * @param modeInputted user input
     * @return mode fixed
     */
    private static int getCocoMode(String modeInputted) {
        int mode;
        try {
            mode = Integer.parseInt(modeInputted);
            mode = (mode < COCO_MODE_BASE || mode > COCO_MODE_MIDDLE) ? COCO_MODE_BASE : mode;
        } catch (Exception e) {
            System.out.println("Use default mode of Base");
            mode = COCO_MODE_BASE;
        }
        return mode;
    }

    /**
     * calculate (MM)D & TDEV & (MM)AM
     *
     * @param devKdsi devKdsi
     * @param mode mode
     * @param modifyKdsi modifyKdsi
     */
    private static void base(double devKdsi, int mode, double modifyKdsi) {
        printConstants(--mode);
        //get (MM)D
        double mmd = getMm(devKdsi, mode);
        //get TDEV from (MM)D
        getTdev(mmd, mode);
        //get (MM)AM from (MM)D and DEV-KDSI and MODIFY-KDSI
        getMmam(devKdsi, modifyKdsi, mmd);
    }

    private static void getMmam(double devKdsi, double modifyKdsi, double mm) {
        //ACT = MODIFY / (MM)D
        double act = new BigDecimal(modifyKdsi / devKdsi).setScale(2, RoundingMode.FLOOR).doubleValue();
        System.out.println("ACT ≈ " + act);
        //(MM)AM = ACT * (MM)D
        double mmam = Math.ceil(act * mm);
        System.out.println("(MM)AM ≈ " + new BigDecimal(mmam).intValue() + "(Man-Month)");
    }

    private static void printConstants(int index) {
        System.out.println(System.lineSeparator() +
                "C1 = " + CC_BASE_CONS[index][INDEX_C1] +
                ", K1 = " + CC_BASE_CONS[index][INDEX_K1] +
                ", C2 = " + CC_BASE_CONS[index][INDEX_C2] +
                ", K2 = " + CC_BASE_CONS[index][INDEX_K2]);
    }

    private static void getTdev(double mm, int index) {
        double tdev = CC_BASE_CONS[index][INDEX_C2] * Math.pow(mm, CC_BASE_CONS[index][INDEX_K2]);
        tdev = BigDecimal.valueOf(tdev).setScale(2, RoundingMode.FLOOR).doubleValue();
        System.out.println("TDEV = C2 * (MM)^K2 = " +
                CC_BASE_CONS[index][INDEX_C2] + " * " +
                mm + "^" +
                CC_BASE_CONS[index][INDEX_K2] +
                " ≈ " + BigDecimal.valueOf(tdev).setScale(2, RoundingMode.FLOOR) + "(M)");
    }

    private static double getMm(double devKdsi, int index) {
        double mm = CC_BASE_CONS[index][INDEX_C1] * Math.pow(devKdsi, CC_BASE_CONS[index][INDEX_K1]);
        mm = BigDecimal.valueOf(mm).setScale(2, RoundingMode.FLOOR).doubleValue();
        System.out.println("MM = C1 * (KDSI)^K1 = " +
                CC_BASE_CONS[index][INDEX_C1] + " * " +
                devKdsi + "^" +
                CC_BASE_CONS[index][INDEX_K1] +
                " ≈ " + mm + "(Man-Month)");
        return mm;
    }

    private static final String NOTICE = System.lineSeparator() + "Choose COCOMO [1]Base(Default) [2]Middle, type \"exit\" or \"quit\" for exit:";
    private static final double[][] CC_BASE_CONS = new double[3][4];
    private static final int INDEX_ORG = 0;
    private static final int INDEX_HALF_SEP = 1;
    private static final int INDEX_EMBED = 2;
    private static final int INDEX_C1 = 0;
    private static final int INDEX_K1 = 1;
    private static final int INDEX_C2 = 2;
    private static final int INDEX_K2 = 3;
    private static final int COCO_MODE_BASE = 1;
    private static final int COCO_MODE_MIDDLE = 2;
    private static final String CMD_EXIT = "exit";
    private static final String CMD_QUIT = "quit";
    private static final double DEFAULT_MODIFY = 1.0;
    private static final double DEFAULT_DEV_KDSI = 5.0;

    static {
        //ORGANIZE CONSTANTS
        CC_BASE_CONS[INDEX_ORG][INDEX_C1] = 2.4;
        CC_BASE_CONS[INDEX_ORG][INDEX_K1] = 1.05;
        CC_BASE_CONS[INDEX_ORG][INDEX_C2] = 2.5;
        CC_BASE_CONS[INDEX_ORG][INDEX_K2] = 0.38;
        
        //HALF-SEPARATE CONSTANTS
        CC_BASE_CONS[INDEX_HALF_SEP][INDEX_C1] = 3.0;
        CC_BASE_CONS[INDEX_HALF_SEP][INDEX_K1] = 1.12;
        CC_BASE_CONS[INDEX_HALF_SEP][INDEX_C2] = 2.5;
        CC_BASE_CONS[INDEX_HALF_SEP][INDEX_K2] = 0.35;
        
        //EMBED CONSTANTS
        CC_BASE_CONS[INDEX_EMBED][INDEX_C1] = 3.6;
        CC_BASE_CONS[INDEX_EMBED][INDEX_K1] = 1.2;
        CC_BASE_CONS[INDEX_EMBED][INDEX_C2] = 2.5;
        CC_BASE_CONS[INDEX_EMBED][INDEX_K2] = 0.32;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值