DPJF is a tool for detecting occurrences of design patterns (DP) in Java programs. The acronym DPJF stands for Detection of Patterns by Joining Forces, reflecting that the unusually good results of DPJF are achieved by a novel combination of various well-known static analysis techniques.
The first public release of DPJF detects the following similarity groups (that is, sets of structurally similar patterns):
of a supertype. This similarity group includes the Decorator, Proxy and Chain of Responsibility (CoR) patterns.
objects are involved in conceptual dependency relation and the 'master' object is decoupled
from dependent objects. This similarity group includes the following patterns: **Observer**, **Composite**, **Bridge**, **State**, **Strategy**.
More are being implemented.
The main highlight of DPJF is that it surpasses other known DP detection tools in detection quality (precision and recall), even on programs containing highly unusual pattern implementations or many structurally similar patterns that are easily confused by other tools.
Moreover, DPJF is one of the fastest existing tools. The table below compares its query times (running on JTransformer 2.9.3 and SWI-Prolog >= 5.11.29) to the performance of other tested DP detection tools.
The table above compare pure query times for DPJF to the total run-times of other tools, which includes query and parsing time1). This is justified since, after its initial start, DPJF does not need to re-parse projects. If the project is changed at run-time, the JTransformer factbase (→ implementation) is updated instantly with unnoticeable delays. So use of DPJF will actually incur only the pure query time in all but the very first run of DPJF. To the best of our knowledge, none of the other existing tools supports incremental update of their internal representation. They all need to re-parse the entire project for each new analysis, incurring exactly the total costs shown above.
DPJF was tested on JHotDraw 5.1 and 6.0, Java IO 1.4, AWT 1.14, ArgoUML 0.18 and Eclipse Team Core (from Eclipse 3.6.0). The factbases for these repositories come with our installation packages. However, DPJF can detect patterns in any Java project, as explained here.
The right-hand-side table shows some relevant size indicators for each project. Comparison of project sizes to the measured detection speed (above) reveals the good scalability of DPJF.
DPJF is based on the JTransformer analysis and transformation engine. JTransformer parses the source and byte code of a Java program, creating a database of Prolog facts (called a factbase) that describes the program elements and their relationships.
DPJF consists of several detection modules (DMs). Each DM is responsible for detecting a set of structurally similar patterns (a similarity group). A DM consists of a structural submodule and a behavioral submodule implemented as Prolog queries that analyse the factbase created by JTransformer. The structural submodule identifies candidates for a given similarity group by applying very efficient structural analyses. The behavioral submodule distinguishes the candidates within the same similarity group, classifying them properly or rejecting them.
This architectural decision has allowed us to implement DPJF in very short time and achieve very good performance results by profiting from advances of the underlying infrastructures (JTransformer and SWI-Prolog).
For instance, JTransformer has always provided extremely high query speed but taking advantage of this potential required very deep optimization knowledge that complicated the implementation of efficient detectors. Since the introduction of dynamic multi-argument indexing in SWI-Prolog 5.11.29 even naively written queries can run at very high speed, making it easy for interested developers to extend DPJF by new pattern detection modules.