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