Course overview
What’s this course about?
- Program construction: Practice building mid-sized production-quality software using a high-level programming language (Java).
- Program design: A recurring theme in the course will be designing your software for stability in the face of changing requirements.
- Design patterns: We will talk about some design patterns. The goal is not to get you to memorise design patterns, but rather to gain an appreciation for the idea of design patterns as way to talk and think about program design. Unlike most books on “design patterns” we will try to think about patterns beyond the context of Object-oriented software.
“Production-quality” means that, in addition to functional correctness (your program does what we expect it to do), you will be expected to attend to the following aspects:
- Code style (e.g., using a linter) and writing code for readability and maintainability
- Testing
- Documentation (i.e., Javadoc comments)
Syllabus overview
Grading and assessments
- Projects — some will build on others — design your programs with this maintainability in mind!
- Labs — we’ll practice what we talk about in lecture — in the early-to-middle part of the quarter, these will be things like code review discussions, design documents — in the later weeks, these will be “labs” in the sense you’re used to (programming assignments) where you’ll practice new syntax/concepts that we’ve talked about
- Quizzes — these will be weekly timed quizzes taken during the lab session — you must be present to take these — these will include a mix of open-ended design questions, multiple-choice questions, and programming questions
- Participation — there’ll occasionally be in-class small-group activities done in class — you’ll get credit for turning them in
Notes about all programming assignments
- Code style — all programming assignments will be done using Java 19, using Checkstyle to enforce coding standards — we’ll use the Google style guide (Checkstyle configuration file provided in Canvas)
- Programming environment — you’re encouraged to work using IntelliJ IDEA — we’ll set it up with the Checkstyle plugin and walk through enabling test quality checks during the lab session
Academic honesty
- Labs are meant to be worked on individually, but you’re free to discuss and collaborate with your classmates. But be aware that the labs are meant for your practice — you’re shortchanging yourself if you don’t let yourself be challenged.
- Projects are individual endeavours. Normally, you can discuss high-level issues with your classmates, but note that this is a design course. By-and-large, you all know how to program already. The high-level issues are in large part what the projects are meant to test.
- Quizzes are completely individual endeavours. Any evidence of illicit collaboration will be taken extremely seriously.
Code style, programming practices
Effective Java, Sonarlint
Code critique
public static String delimit(String delimiter, String[] str) {
String result = "";
int i;
for (i = 0; i < str.length; i++) {
if (i != 0) {
result += delimiter;
}
result += str[i];
}
return result;
}
What do you think of this code? Is its purpose clear? Is the function maintainable?
EJ57: Minimise the scope of local variables.
The variable i
is now only available inside the for
loop.
public static String delimit(String delimiter, String[] str) {
String result = "";
if (str.length > 0) {
result += str[0];
}
for (int i = 1; i < str.length; i++) {
result += delimiter;
result += str[i];
}
return result;
}
In the example below, the iterator i
is not needed after the first while
loop. But its scope is
not limited to that area. This can subtle mistakes like the one below. Can you spot it?
public static void example(List<Object> c, List<Object> c2) {
Iterator<Object> i = c.iterator();
while (i.hasNext()) {
System.out.println(i.next());
}
// ... Some other code.
Iterator<Object> i2 = c2.iterator();
while (i.hasNext()) {
System.out.println(i2.next());
}
}
EJ63: Beware performance of String concatenation
+
is a convenient way to concatenate strings- but string are immutable, that means each time we “append” to the string, a
new
string is created. thenew
keyword is expensive to use. - use
StringBuilder
instead
public static String delimit(String delimiter, String[] str) {
StringBuilder result = new StringBuilder();
if (str.length > 0) {
result.append(str[0]);
}
for (int i = 1; i < str.length; i++) {
result.append(delimiter);
result.append(str[i]);
}
return result.toString();
}
EJ58: Prefer for-each loops to traditional for loops where possible.
- Using a for-each loop instead of a regular for loop removes the chances of making
off-by-one errors (e.g., ending the loop at
i <= str.length
instead ofi < str.length
) - You may sometimes need the index variable; in those cases a regular
for
loop is fine. Thedelimit
function is an example of such a case: we need thei
variable in order to tell the function to skip the first item in the list.
EJ59 Know and use the standard libraries.
- The Java platform has been developed over years
- Benefit from the experts where you can
- It’s also really well documented
public static String delimit(String delimiter, List<String> str) {
return String.join(delimiter, str);
}
public static String delimit(String delimiter, String[] str) {
return String.join(delimiter, str);
}