Определение эфферентной связи между объектами (CBO Metric) с использованием проанализированного байт-кода, сгенерированного BCEL

Я построил программу, которая берет предоставленный файл ".class" и анализирует его с использованием BCEL, теперь я научился вычислять значение LCOM4. Теперь я хотел бы знать, как рассчитать значение CBO(Связь между объектами) файла класса. Я обыскивал всю сеть, пытаясь найти подходящий учебник по этому поводу, но пока не смог (я прочитал весь javadoc относительно BCEL, и был похожий вопрос по stackru, но он был удалены). Поэтому я хотел бы помочь с этой проблемой, например, в некоторых подробных руководствах или фрагментах кода, которые помогут мне понять, как это сделать.

1 ответ

Хорошо, здесь вы должны вычислить CBO классов в целом наборе классов. Набор может быть содержимым каталога, файла JAR или всех классов в пути к классам.

Я бы заполнил Map> именем класса в качестве ключа и классами, на которые он ссылается:

private void addClassReferees(File file, Map<String, Set<String>> refMap)
        throws IOException {
    try (InputStream in = new FileInputStream(file)) {
        ClassParser parser = new ClassParser(in, file.getName());
        JavaClass clazz = parser.parse();
        String className = clazz.getClassName();
        Set<String> referees = new HashSet<>();
        ConstantPoolGen cp = new ConstantPoolGen(clazz.getConstantPool());
        for (Method method: clazz.getMethods()) {
            Code code = method.getCode();
            InstructionList instrs = new InstructionList(code.getCode());
            for (InstructionHandle ih: instrs) {
                Instruction instr = ih.getInstruction();
                if (instr instanceof FieldOrMethod) {
                    FieldOrMethod ref = (FieldInstruction)instr;
                    String cn = ref.getClassName(cp);
                    if (!cn.equals(className)) {
                        referees.add(cn);
                    }
                }
            }
        }
        refMap.put(className, referees);
    }
}

Когда вы добавили все классы на карту, вам нужно отфильтровать рефери каждого класса, чтобы ограничить их набором рассматриваемых классов, и добавить обратные ссылки:

            Set<String> classes = new TreeSet<>(refMap.keySet());
            for (String className: classes) {
                Set<String> others = refMap.get(className);
                others.retainAll(classes);
                for (String other: others) {
                    refMap.get(other).add(className);
                }
            }
Другие вопросы по тегам