366 lines
15 KiB
TeX
366 lines
15 KiB
TeX
% vim: set ts=2 sw=2 et tw=80:
|
|
|
|
\documentclass[10pt,a4paper]{scrartcl}
|
|
\usepackage[utf8]{inputenc}
|
|
\usepackage[margin=2.25cm]{geometry}
|
|
\usepackage{hyperref}
|
|
\usepackage{listings}
|
|
\usepackage{xcolor}
|
|
\usepackage{lmodern}
|
|
\usepackage{booktabs}
|
|
\usepackage{float}
|
|
\usepackage{listings}
|
|
\setlength{\parindent}{0cm}
|
|
\setlength{\parskip}{0.3em}
|
|
\hypersetup{pdfborder={0 0 0}}
|
|
\usepackage[nomessages]{fp}
|
|
|
|
\renewcommand*{\titlepagestyle}{empty}
|
|
|
|
\lstset{
|
|
basicstyle=\small\ttfamily,
|
|
%frame=shadowbox,
|
|
rulesepcolor=\color{black},
|
|
columns=fullflexible,
|
|
commentstyle=\color{gray},
|
|
keywordstyle=\color{blue},
|
|
mathescape=true,
|
|
aboveskip=1em,
|
|
captionpos=b,
|
|
abovecaptionskip=1em,
|
|
belowcaptionskip=1em
|
|
}
|
|
|
|
|
|
\title{Assginment 1 -- Software Design and Modelling}
|
|
|
|
\author{Volodymyr Karpenko \and Claudio Maggioni}
|
|
|
|
\begin{document}
|
|
\begin{titlepage}
|
|
\maketitle
|
|
\pagenumbering{roman}
|
|
\tableofcontents
|
|
\lstlistoflistings
|
|
\end{titlepage}
|
|
|
|
\section{Project selection process}
|
|
\pagenumbering{arabic}
|
|
|
|
We have to choose a Java-based project on GitHub that follows the following
|
|
requirements:
|
|
|
|
\begin{itemize}
|
|
\item 100 or greater number of stars;
|
|
\item 100 or greater number of forks;
|
|
\item 10 or more open issues;
|
|
\item 50.000 or more lines of code.
|
|
\end{itemize}
|
|
|
|
Additionally, we personally added some (less strict) constraints that we thought
|
|
would lead to a more significant and effective analysis:
|
|
|
|
\begin{itemize}
|
|
\item There must be evidence that the project follows business-oriented
|
|
conventions. This excludes amateur or personal projects that due to
|
|
their nature might have less design pattern applications.
|
|
\item Repository data, documentation and comments must be written in the
|
|
english language. Many repositories that are at the top of the search
|
|
results provided by the hard requirements are not in english and this
|
|
drastically hampers our ability to understand the code;
|
|
\item The artifact the project produces must not rely on external components
|
|
and have a streamlined build process, with all code stored in a single
|
|
Maven/Gradle module. This improves both our ability to tinker with the
|
|
project more easily and the pattern detection process, which requires all
|
|
\textit{.class} files related to the project to be stored in a single
|
|
directory tree.
|
|
\end{itemize}
|
|
|
|
Additionally, instead of querying GitHub directly for projects we decided to see
|
|
if libraries we knew already in our Java development career would match both the
|
|
hard and soft requirements we set for ourselves.
|
|
|
|
Therefore, we considered the following GitHub repositories:
|
|
|
|
\begin{description}
|
|
\item[vavr-io/vavr] a Java library for functional programming, discarded as
|
|
the project is less than 20.000 lines of code and does not meet the hard
|
|
requirements;
|
|
\item[bitcoin4j/bitcoin4j] a Java implementation of the bitcoin protocol,
|
|
discarded as the project is distributed in several subprojects and therefore
|
|
the build process is nontrivial;
|
|
\item[FasterXML/jackson-core] the core ``module'' of a Java JSON serialization
|
|
and deserialization library. We chose this project because it meets the
|
|
selection criteria, it does not rely on external components for its
|
|
execution. Finally, the project structure uses a single Maven module for its
|
|
sources and thus easy to analyze.
|
|
\end{description}
|
|
|
|
\subsection {The Jackson Core Project}
|
|
As already mentioned, Jackson is a library that offers serialization
|
|
and deseralization capabilities in JSON format. It is highly extensible
|
|
and customizable through a robust but flexible API. The library is divided in
|
|
what the Jackson developers call ``modules'', i.e.\ plug-ins that can augment
|
|
the serialization and deserialization process. Some modules, like
|
|
\textit{jackson-dataformat-xml} module, even allow to target different encoding
|
|
languages like XML.
|
|
|
|
The chosen repository contains only the \textit{core} module of Jackson. The
|
|
\textit{core} module implements the necessary library abstractions and
|
|
interfaces to allow other modules to be plugged-in. Additionally, the
|
|
\textit{core} module implements the tokenizer and low-level abstractions to work
|
|
with the JSON format. We will refer to this module as ``Jackson'' or ``Jackson
|
|
Core'' interchangeably throughout this report.
|
|
|
|
We choose to analyze version 2.13.4 of the module (i.e.\ the code under the
|
|
\textit{git} tag \textit{jackson-core-2.13.4}) because it is the latest stable
|
|
version available at the time of writing.
|
|
|
|
After verifying that the project meets the hard requirements related to GitHub
|
|
(more than 2000 stars, more than 600 forks, 35 open issues\footnote{as of
|
|
2022-10-19}), we ensured that the project had enough lines of code by using the
|
|
cloc tool, which provided the following output shown in Figure \ref{fig:cloc}.
|
|
By looking at the results we can finally assert that the project contains 58.787
|
|
lines of Java code and this satisfies all the requirements.
|
|
|
|
\begin{figure}[H]
|
|
\centering
|
|
\begin{tabular}{lrrrr}
|
|
\toprule
|
|
Language & Files & Blank & Comment & Code \\
|
|
\midrule
|
|
HTML & 4846 & 18473 & 235544 & 1997020\\
|
|
Java & 285 & 8532 & 20004 & 48783\\
|
|
CSS & 3 & 18 & 69 & 990\\
|
|
Logos & 2 & 260 & 212 & 605\\
|
|
Bourne Shell & 3 & 35 & 62 & 223\\
|
|
XML & 7 & 5 & 1 & 179\\
|
|
DOS Batch & 1 & 35 & 0 & 153\\
|
|
Markdown & 3 & 58 & 0 & 125\\
|
|
Maven & 1 & 13 & 23 & 112\\
|
|
YAML & 3 & 1 & 5 & 71\\
|
|
JavaScript & 1 & 1 & 0 & 29\\
|
|
JSON & 1 & 0 & 0 & 10\\
|
|
Properties & 2 & 0 & 16 & 5\\
|
|
\midrule
|
|
Total & 5158 & 27431 & 255936 & 2048305\\
|
|
\bottomrule
|
|
\end{tabular}
|
|
\caption{Output of the \textit{cloc} tool for the Jackson Core project at revision
|
|
\textit{jackson-core-3.13.4}.}
|
|
\label{fig:cloc}
|
|
\end{figure}
|
|
|
|
\section{TO REWRITE Analysis Implementation}
|
|
|
|
We use
|
|
\href{https://users.encs.concordia.ca/~nikolaos/pattern\_detection.html}{\textit{Pattern4J}}
|
|
as a pattern detection tool. This tool needs compiled \textit{.class} files in
|
|
order to perform analysis. Therefore, as \textit{jackson-core} is a standard
|
|
Maven project, we compile the sources using the command \textit{mvn clean
|
|
compile}. The \textit{pom.xml} of the library specifies Java 1.6 as a
|
|
build target, which is not supported by JDK 17 or above. We used JDK 11
|
|
instead, as it is the previous LTS version.
|
|
|
|
An XML dump of the \textit{Pattern4j} analysis results are included in the
|
|
submission as the file \textit{analysis.xml}.
|
|
|
|
\section{Structural Patterns}
|
|
|
|
\subsection{TO REWRITE Singleton Pattern}
|
|
Lots of false positives for the Singleton pattern. Example,
|
|
com.fasterxml.jackson.core.sym.Name1 has a package private constructor and a
|
|
public static final instance of it, but reading the documentation the class
|
|
represents (short) JSON string literals and therefore is clearly
|
|
initialized by client code.
|
|
|
|
(com.fasterxml.jackson.core omitted for brevity)
|
|
|
|
\begin{description}
|
|
\item[sym.Name1, JsonLocation, DefaultIndenter,
|
|
util.DefaultPrettyPrinter\$FixedSpaceIndenter] not a singleton (detected
|
|
cause of "convenient" default instance given as static final field), the
|
|
constructor is not used but the class is extensible
|
|
\item[JsonPointer, filter.TokenFilter] like above, but constructors are protected
|
|
\item[JsonpCharacterEscapes, util.DefaultPrettyPrinter\$NopIndenter,
|
|
Version] a singleton but with a public constructor that is never called
|
|
in the module code, may be called in tests
|
|
\item[io.JsonStringEncoder] like above, but the class is final
|
|
\item[util.InternCache, io.CharTypes\$AltEscapes]
|
|
actual singleton, thread-unsafe initialization
|
|
\item[io.ContentReference] like above, but constructor is protected
|
|
\end{description}
|
|
|
|
\subsection{Abstract Factory Pattern}
|
|
\textit{Pattern4J} detects only two instances of the abstract factory pattern:
|
|
|
|
\begin{description}
|
|
\item[TokenStreamFactory] which indeed is a factory for \textbf{JsonParser} and
|
|
\textbf{JsonGenerator} objects, although two overloaded factory methods
|
|
exist on this class (one for each class) catering for different combination of
|
|
arguments. A concrete implementation of this factory is included in the form
|
|
of the \textbf{JsonFactory} class, although other modules may add additional
|
|
implementations to cater for different encodings (like the
|
|
\textit{jackson-dataformat-xml} module for XML);
|
|
\item[TSFBuilder] which is also a factory for concrete implementations of
|
|
\textbf{TokenStreamFactory} to allow slight changes in the serialization and
|
|
deserialization rules (e.g. changing the quote character used in JSON keys
|
|
from \textit{"} to \textit{'}). Like \textbf{TokenStreamFactory}, this class
|
|
is only implemented by one class, namely \textbf{JsonFactoryBuilder}, whitin
|
|
the scope of this module. And as mentioned previously, this abstract factory
|
|
is also likely to be extended by concrete implementations in other
|
|
\textit{Jackson} modules.
|
|
\end{description}
|
|
|
|
\subsection{Builder Pattern}
|
|
|
|
The builder pattern does not seem to be analyzed by
|
|
\textit{Pattern4J}, as the analysis output does not mention the pattern, even
|
|
just to report that no instances of it have been found (as it is the case with
|
|
other patterns, e.g. the observer pattern). A manual search in the source code
|
|
produced the following results:
|
|
|
|
\begin{description}
|
|
\item[TSFBuilder] is also a builder other than an abstract factory. As mentioned
|
|
previously, this class allows to alter slightly the serialization and
|
|
deserialization rules used to build outputtting \textbf{JsonFactory}
|
|
objects. Each rule is represented by an object or enum instance implementing
|
|
the \textbf{util.JacksonFeature} interface. \textit{TSFBuilder} then
|
|
provides several overloaded methods to enable and disable features
|
|
represented by the interface. Enabled features are stored in several
|
|
bitmask \textit{protected int} fields, which are then directly accessed by
|
|
the constructor of the \textbf{TokenStreamFactory} concrete implementation
|
|
to build;
|
|
\marginpar[right text]{\color{white}\url{https://youtu.be/72b2nH-kdbU}}
|
|
\item[JsonFactoryBuilder] an concrete factory implementation of
|
|
\textbf{TSFBuilder} that builds \textbf{JsonFactory} instances;
|
|
\item[util.ByteArrayBuilder] provides facilities to build \textit{byte[]} objects
|
|
of varying length, akin to \textbf{StringBuilder} building \textbf{String}
|
|
objects. This is not a strict implementation of the builder pattern per se
|
|
(as Java arrays do not have a ``real'' constructor),
|
|
but it is nevertheless included since the features it exposes (namely
|
|
dynamic sizing while building) are decoupled by the underlying (fixed-size)
|
|
array representation.
|
|
\end{description}
|
|
|
|
\section{Creational Patterns}
|
|
\subsection{Adapter Pattern}
|
|
TBD
|
|
|
|
|
|
\subsection{Decorator Pattern}
|
|
Only in Pattern4j
|
|
|
|
\subsection{Bridge Pattern}
|
|
TBD
|
|
|
|
\subsection{Composite Pattern}
|
|
None found
|
|
|
|
\subsection{Facade Pattern}
|
|
TBD -- \textit{Pattern4J} does not detect this pattern
|
|
|
|
\subsection{Proxy Pattern}
|
|
None found
|
|
|
|
\section{Behavioral Patterns}
|
|
\subsection{Command Pattern}
|
|
None found
|
|
|
|
\subsection{Observer Pattern}
|
|
None found
|
|
|
|
|
|
\subsection{State Pattern}
|
|
Among the design patterns \textit{Pattern4J} detects, the state pattern is
|
|
detected in 5 classes. The state pattern is a variation of the strategy pattern
|
|
where the concrete strategy used by the matching context is determined by the
|
|
state of a finite state machine the context class implements. In other words,
|
|
the state pattern chooses the concrete strategy to use through the state of the
|
|
context.
|
|
|
|
By analyzing the \textit{Pattern4J} results and the code, we can say that all
|
|
the instances of the state pattern the tool finds are false positives. Namely:
|
|
|
|
\begin{description}
|
|
\item[util.DefaultPrettyPrinter \textit{\_inputDecorator} and
|
|
\textit{\_outputDecorator}] are fields flagged as states, thus flagging the
|
|
class as a state pattern instance. However, no ``state'' akin to a
|
|
finite-state machine is maintained by the class to determine which
|
|
implementation of these fields to invoke. What is detected are more likely
|
|
lightweight implementations of the strategy pattern, since these fields can
|
|
be mutated through matching getters and setters. Additionally, the
|
|
documentation of each of the matching \textit{...Decorator} field types
|
|
(namely interfaces) states that implementors are meant to be algorithms to
|
|
pre-process input before the formatting process (a feature labeled as
|
|
``decorator'' w.r.t.\ the library, not to be confused with the decorator
|
|
pattern);
|
|
\item[util.DefaultPrettyPrinter \_objectIndenter and \_arrayIndenter] are
|
|
false positives too, and are likely strategy patterns too for the reasons
|
|
described above.
|
|
\item[util.DefaultPrettyPrinter \_rootValueSeparator] is flagged as a state
|
|
field too, however the field is simply a boxed \textit{String-like}
|
|
immutable data structure (i.e.\ \textit{SerializableString}) that is
|
|
swapped during the pretty-printer parsing logic;
|
|
\item[json.WriterBasedJsonGenerator \_currentEscape] is a false positive for
|
|
the same reasons described above.
|
|
\end{description}
|
|
|
|
\subsection{Strategy Pattern}
|
|
\textit{Pattern4j} detects no instance of the strategy pattern in Jackson,
|
|
however the previous section regarding the state pattern referenced some false
|
|
positives that were indeed applications of this pattern. Due to the flexibility
|
|
of Jackson, there are many more instances of the strategy pattern to configure
|
|
and customize the serialization and deserialization pipeline in several stages.
|
|
|
|
\subsection{Template Method Pattern}
|
|
Due to the extendibility of Jackson, it is of no surprise that the template
|
|
method pattern is used extensively to create a class hierarchy that provides
|
|
rich interfaces while maintaining behavioural flexibility. \textit{Pattern4J}
|
|
correctly detects several instances of the pattern, namely
|
|
\textbf{JsonStreamContext}, \textbf{JsonGenerator}, \textbf{type.ResolvedType},
|
|
\textbf{JsonParser}, \textbf{base.ParserBase}, \textbf{base.GeneratorBase},
|
|
\textbf{base.ParserMinimalBase}. All these classes implement several concrete
|
|
\textit{public} methods throwgh the use of \textit{protected abstract} methods.
|
|
Although the concrete (i.e.\ the template) methods are usually not vary complex
|
|
(as the pattern example shown in class), they still follow the principles of the
|
|
template method pattern. We show as an example some template methods found in
|
|
\textbf{base.ParserBase}:
|
|
|
|
\begin{lstlisting}[caption=Template method \textit{void close()} and step
|
|
methods \textit{void \_closeInput()} and \textit{void \_releaseBuffers()} in
|
|
\textbf{base.ParserBase}., language=java]
|
|
@Override public void close() throws IOException {
|
|
if (!_closed) {
|
|
// 19-Jan-2018, tatu: as per [core#440] need to ensure no more data
|
|
// assumed available
|
|
_inputPtr = Math.max(_inputPtr, _inputEnd);
|
|
_closed = true;
|
|
try {
|
|
_closeInput();
|
|
} finally {
|
|
// as per [JACKSON-324], do in finally block
|
|
// Also, internal buffer(s) can now be released as well
|
|
_releaseBuffers();
|
|
}
|
|
}
|
|
}
|
|
|
|
protected abstract void _closeInput() throws IOException;
|
|
|
|
protected void _releaseBuffers() throws IOException {
|
|
/* implementation omitted */
|
|
}
|
|
\end{lstlisting}
|
|
|
|
Here the pattern is slightly modified by providing a default implementation of
|
|
\textit{void \_releaseBuffers()}. In this case, child classes occasionally
|
|
override the method with a body first calling \textit{super()} and then adding
|
|
additional buffer release code after.
|
|
|
|
\subsection{Visitor Pattern}
|
|
None found
|
|
|
|
\end{document}
|
|
|