Minor change
[u/philim/db2osl_thesis.git] / program_code.tex
1 \section{Code style}
2 \label{code}
3 TODO: Conventions, ex.: iterators
4 As the final system hopefully will have a long living cycle TODO
5 and will be used and refined by many people, high code quality was an important aim.
6 Beyond architectural issues this also involves cleanness on the lower level,
7 like the design of classes and the implementation of methods.
8 Common software development principles were followed TODO and
9 the unfamiliar reader was constantly taken into account
10 to yield clean, usable and readable code.
11
12 \subsection{Comments}
13 \label{comments}
14 Comments were used at places ambiguities or misinterpretations could arise,
15 yet care was taken to face such problems at their roots and solve them
16 wherever possible instead of just eliminating the ambiguity with comments.
17
18 Consider the following method in \file{CLIDatabaseInteraction.java}:
19 \codepar{public static void promptAbortRetrieveDBSchemaAndWait\\
20         \ind(final FutureTask<DBSchema> retriever) throws SQLException}
21
22 It could have been called \code{promptAbortRetrieveDBSchema} only, with the
23 waiting mentioned in a comment.
24 However, the waiting is such an important part of its behavior, that this
25 wouldn't have been enough, so the waiting was included in the function name.
26 Since the method is called at one place only, the lengthening of the method
27 name by 7 characters or about 26 \% is really not a problem.
28
29 More generally, ``speaking code'' was used wherever possible,
30 as described in section \fullref{speaking},
31 which rendered many uses of comments unnecessary.
32 In fact, the number of (plain, e.g. non-\name{Javadoc}) comments was
33 consciously minimized, to enforce speaking code and avoid redundancy.
34 This technique is known TODO.
35
36 An exception of course from this is the highlighting of subdivisions.
37 In class and method implementations, comments like
38 \codepar{//********************** Constructors **********************\textbackslash\textbackslash}
39
40 were deliberately used to ease navigation inside source files for unfamiliar
41 readers, but also to enhance readability: independent parts of method
42 implementations, for example, were optically separated this way.
43 Another alternative would have been to use separate methods for this code
44 pieces, as was done in other cases, and thereby sticking strictly to the so-called
45 ``Composed Method Pattern'' \cite{composed}.
46 However, sticking to this pattern too rigidly would have introduced additional
47 artifacts with either long or non-speaking names,
48 would have interrupted the reading flow and also would have increased complexity,
49 because these methods would have been callable at least from everywhere
50 in the source file.
51
52 Wherever possible, the appropriate \name{Javadoc} comments were used in favor of
53 plain comments, for example to specify parameters, return types, exceptions
54 and links to other parts of the documentation.
55
56 \subsection{Speaking code}
57 \label{speaking}
58 As mentioned in section \fullref{comments}, the use of ``speaking code'' as
59 introduced TODO
60 renders many uses of comments unnecessary.
61 In particular, the following aspects are commonly considered when referring to
62 the term ``speaking code'' TODO:
63
64 \begin{itemize}
65         \item Variable names
66         \item Control flow
67 \end{itemize}
68
69 \subsubsection{Variable names}
70 A very important part of speaking code 
71
72 \subsection{Robustness against incorrect use}
73 Care was taken to produce code that is robust to incorrect use, making it
74 suitable for the expected environment of sporadic updates by unfamiliar and
75 potentially even unpracticed programmers who very likely have their emphasis
76 on the concepts of bootstrapping rather than details of the present code.
77
78 In fact, carefully avoiding the introduction of technical artifacts to mind,
79 preventing programmers from focusing on the actual program logic,
80 is an important principle of writing clean code \cite{str4}.
81
82 In modern programming languages, of course the main instruments for achieving
83 this are the type system and exceptions.
84 In particular, static type information should be used to reflect data
85 abstraction and the ``kind'' of data, an object reflects,
86 while dynamic type information should only be used implicitly,
87 through dynamically dispatching method invocations \cite{str4}.
88 Exceptions on the other hand should be used at any place related to errors
89 and error handling, separating error handling noticeably from other code and
90 enforcing the treatment of errors, preventing the programmer from using
91 corrupted information in many cases.
92
93 An example of both mechanism, static type information and exceptions, acting
94 in combination, while cleanly fitting into the context of dynamic dispatching,
95 are the following methods from \file{Column.java}:
96 \codepar{public Boolean isNonNull()\\public Boolean isUnique()}
97
98 There return type is the \name{Java} class \code{Boolean}, not the plain type
99 \code{boolean}, because the information they return is not always known.
100 In an early stage of the program, they returned \code{boolean} and were
101 accompanied by two methods
102 \code{public boolean knownIsNonNull()} and \code{public boolean knownIsUnique()},
103 telling the caller whether the respective information was known and thus the
104 value returned by \code{isNonNull()} or \code{isUnique()}, respectively,
105 was reliable.
106
107 They were then changed to return the \name{Java} class \code{Boolean} and to return
108 null pointers in case the respective information is not known.
109 This eliminated any possibility of using unreliable data in favor of generating
110 exceptions instead, in this case a \code{NullPointerException}, which is thrown
111 automatically by the \name{Java Runtime Environment} if the programmer forgets the
112 null check and tries to get a definite value from one of these methods
113 when the correct value currently is not known.
114
115 Comparing two unknown values -- thus, two null pointers --
116 also yields the desired result, \code{true}, since the change,
117 even when the programmer forgets that he deals with objects.
118 However, when comparing two return values of one of the methods in general
119 -- as opposed to comparing one such return value against a constant --,
120 errors could occur if the programmer mistakenly writes \code{col1.isUnique() == col2.isUnique()}
121 instead of \code{col1.isUnique().booleanValue() == col2.isUnique().booleanValue()}.
122 In this case, since the two \code{Boolean} objects are compared for identity \cite{java},
123 the former comparison can return \code{false}, even when the two boolean values are in fact
124 the same.
125 However, since this case was considered much less common than cases in which the other
126 solution could make programmers making mistakes produce undetected errors, it was preferred.
127
128 TODO: more (?), summary
129
130 \subsection{Classes}
131 \label{code_classes}
132 Following the object-oriented programming paradigm, classes were heavily used
133 to abstract from implementation details and to yield intuitively usable objects with
134 a set of useful operations \cite{obj}.
135
136 \subsubsection{Identification of classes}
137 To identify potential classes, entities from the problem domain were -- if reasonable --
138 directly represented as \name{Java} classes.
139 The approach of choosing ``the program that most directly models the aspects of the
140 real world that we are interested in'' to yield clean code,
141 as described and recommended by Stroustrup \cite{str3}, proved to be extremely useful
142 and effective.
143 As a consequence, the code declares classes like \code{Column}, \code{ColumnSet},
144 \code{ForeignKey}, \code{Table}, \code{TableSchema} and \code{SQLType}.
145 As described in section \fullref{speaking}, class names were chosen to be concise
146 but nevertheless expressive TODO.
147 \name{Java} packages were used to help attain this aim,
148 which is why the previously mentioned class names are unambiguous
149 (for details about package use, see section \fullref{code_packages}, for the description
150 of the packages themselves and their structuring, see section \fullref{coarse}).
151
152 Care was taken not to introduce unnecessary classes, thereby complicating
153 code structure and increasing the number of source files and program entities.
154 Especially artificial classes, having little or no reference to real-world
155 objects, could most often be avoided.
156 On the other hand of course, it usually is not the cleanest solution
157 to avoid such artificial classes entirely.
158
159 Section \fullref{hierarchies} describes how the classes of \myprog{} are organized
160 into class hierarchies.
161
162 \subsubsection{Const correctness}
163 \label{const}
164 Specifying in the code which objects may be altered and which shall remain constant,
165 thus allowing for additional static checks preventing undesired modifications,
166 is commonly referred to as ``const correctness'' TODO.
167
168 Unfortunately, \name{Java} lacks a keyword like \name{C++}'s \code{const},
169 making it harder to achieve const correctness \cite{final}.
170 It only specifies the similar keyword \code{final}, which is much less expressive and
171 doesn't allow for a similarly effective error prevention \cite{final}.
172 In particular, because \code{final} is not part of an object's type information,
173 it is not possible to declare methods that return read-only objects TODO --
174 placing a \code{final} before the method's return type would declare the
175 method \code{final}. Similarly, there is no way to express that a method must not change
176 the state of its object parameters. A method like \code{public f(final Object obj)}
177 is only liable to not assigning a new value to its parameter object \code{obj} \cite{java}
178 (which, if allowed, wouldn't affect the caller anyway \cite{java}).
179 Methods changing its state, however, are allowed to be called on \code{obj} without
180 restrictions \cite{java}.
181
182 Several possibilities were considered to address this problem:
183 \begin{itemize}
184         \item Not implementing const correctness, but stating the access rules in
185         comments only
186         \item Giving the methods which modify object states special names
187         like\\\code{setName\textendash\textendash USE\_WITH\_CARE}
188         \item Delegating changes of objects to special ``editor'' objects to be
189         obtained when an object shall be altered TODO
190         \item Deriving classes offering the modifying methods from the read-only
191         classes
192 \end{itemize}
193
194 Not implementing const correctness at all of course would have been the simplest
195 possibility, producing the shortest and most readable code, but since
196 incautious manipulation of objects would possibly have introduced subtle,
197 hard-to-spot errors which in many cases would have occurred under additional
198 conditions only and at other places, for example when inserting a \code{Column}
199 into a \code{ColumnSet}, this method was not seriously considered.
200
201 Using intentionally angular, conspicuous names also was not considered seriously,
202 since it would have cluttered the code for the only sake of hopefully warning
203 programmers of possible errors -- and not attempting to avoid them technically.
204
205 So the introduction of new classes was considered the most effective and cleanest
206 solution, either in the form of ``editor'' classes or derived classes offering the
207 modifying methods directly. Again -- as in the identification of classes --,
208 the most direct solution was considered the best, so the latter form of introducing
209 additional classes was chosen and classes like \code{ReadableColumn},
210 \code{ReadableColumnSet} et cetera were introduced which offer only the read-only
211 functionality and usually occur in interfaces.
212 Their counterparts including modifying methods also were derived from them and the
213 implications of modifications were explained in their documentation, while the
214 issue and the approach as such were also mentioned in the documentation of the
215 \code{Readable...} classes.
216 The \code{Readable...} classes can be converted to their fully-functional
217 counterparts via downcasting (only), thereby giving a strong hint to
218 programmers that the resulting objects are to be used with care.
219
220 \subsubsection{Java interfaces}
221 \label{code_interfaces}
222 In \name{Java} programming, it is quiet common and often recommended, that every
223 class has at least one \code{interface} it \code{implements},
224 specifying the operations the class provides. TODO
225 If no obvious \code{interface} exists for a class or the desired
226 interface name is already given to some other entity,
227 the interface is often given names like \code{ITableSchema}
228 or \code{TableSchemaInterface}.
229
230 However, for a special purpose program with a relatively fixed set of classes
231 mostly representing real-world artifacts from the problem domain,
232 this approach was considered overly cluttering, introducing artificial
233 code entities for no benefit.
234 In particular, as explained in section TODO, all program classes either are
235 standing alone TODO or belong to a class hierarchy derived from at least one
236 interface.
237 So, except from the standalone classes, an interface existed anyway, either
238 ``naturally'' (as in the case of \code{Key}, for example) or because of
239 the chosen way to implement const correctness.
240 In some cases, these were interfaces declared in the program code, while
241 in some cases, \name{Java} interfaces like \code{Set} were implemented
242 (an obvious choice, of course, for \code{ColumnSet}).
243 Introducing artificial interfaces for the standalone classes was considered
244 unnecessary at least, if not messy.
245
246 \subsection{Packages}
247 \label{code_packages}
248 As mentioned in section \fullref{code_classes}, class names were chosen to be
249 concise but nevertheless expressive.
250 This only was possible through the use of \name{Java} \code{package}s,
251 which also helped structure the program.
252
253 For the current, relatively limited, extent of the program which currently
254 comprises $45$ (\code{public}) classes, a flat package structure was
255 considered ideal, because it is simple and doesn't stash source files deep
256 in subdirectories (in \name{Java}, the directory structure of the source tree
257 is required to reflect the package structure TODO).
258 Because also every class belongs to a package,
259 each source file is to be found exactly one directory below the root
260 program source directory, which in many cases eases their handling.
261
262 The following $11$ packages exist in the program
263 (their purpose and more details about the package structure are
264 described in section \fullref{coarse}):
265 \begin{multicols}{3}\begin{itemize}
266         \item \code{boostrapping}
267         \item \code{cli}
268         \item \code{database}
269         \item \code{helpers}
270         \item \code{log}
271         \item \code{main}
272         \item \code{osl}
273         \item \code{output}
274         \item \code{settings}
275         \item \code{specification}
276         \item \code{test}
277 \end{itemize}\end{multicols}
278
279 Each package is documented in the source code also, particularly in a file
280 \file{package-info.java} residing in the respective package directory.
281 This is a common scheme supported by the \name{Eclipse} IDE as well as the
282 documentation generation systems \name{javadoc} and \name{doxygen} TODO
283 (all of which were used in the creation of the program,
284 as described in section TODO).