1
CS61B, Fall 2024 @ UC Berkeley
Industrial Applications!
Software Engineering II
Lecture 31
Background
Vanessa Teo (she/her)
Today’s lecture will be about the building a project from the ground up. The concepts we’ll discuss today can be used right now! They’ll also apply forever :)
General Q&A will be at the end.
Design
Lecture 31, CS61B, Fall 2024
Design
Managing Complexity
Documentation
Group Coordination
Q & A
Why Design?
“Instead of wasting time by designing my program, I can save time by starting to code now” - Person who will regret their decision soon™
Design is an important first stage in development:
Design Documents
Design documents do not need to follow a specific form, but they should give the reader easily accessible information about your project.
A design document should:
Design Documents in Industry
Often, design documents will be reviewed before work on the project even begins.
When onboarding to an existing project, the first question someone will ask is “where’s the design doc?”
Design docs are reviewed in performance reviews
Design in Project 3
Think about each class you want to create and how they will fit together
Consider what methods are required to meet each class’s functionality
The major algorithms you’ll need to think about are room and hallway generation
You are making something new!
Managing Complexity
Lecture 31, CS61B, Fall 2024
Design
Managing Complexity
Documentation
Group Coordination
Q&A
Who Cares?
Who Cares?
Technical Debt
There is pressure to achieve both quality and quantity.
This is inarguably a trade-off—prioritizing one will negatively affect the other.
This doesn’t just apply to code—it applies to life.
How do you deal with this? Strategic vs Tactical Programming
Tactical Programming
The focus is on getting something working quickly, leveraging workarounds.
Ex: Code that contains many nested if statements to handle many separate cases that is hard to explain.
Prototypes, proof-of-concepts leverage tactical programming. The goal is to show that something could theoretically work.
However:
Strategic Programming
A different form of programming that emphasizes long term strategy over quick fixes. The objective is to write code that works elegantly - at the cost of planning time.
Code should be:
If the strategy is insufficient, go back to the drawing board before continuing work.
This is your design document for Project 2B.
Importance
Bad Style
IMPORTANT NOTE!
Refactoring is changing your code to make things more organized without affecting functionality.
Before refactoring, always add and commit your code! This way, you can restore your old work if necessary.
Bad Code Example - What’s wrong with this?
static void print3DArray(String[][][] arrays) {
System.out.print("[");
for (int i = 0; i < arrays.length; i++) {
if (arrays[i] == null) {
continue;
}
System.out.print("[");
for (int j = 0; j < arrays[i].length; j++) {
if (arrays[i][j] == null) {
continue;
}
System.out.print("[");
for (int k = 0; k < arrays[i][j].length; k++) {
System.out.print(arrays[i][j][k]);
if (k < arrays[i][j].length - 1) {
System.out.print(", ");
}
}
System.out.print("]");
if (j < arrays[i].length - 1) {
System.out.print(", ");
}
}
System.out.print("]");
if (i < arrays.length - 1) {
System.out.print(", ");
}
}
System.out.print("]\n");
}
Bad Code Example - Test to verify correctness as you refactor
public static void main(String[] args) {
String[][][] arrays = new String[][][] {
new String[][] {
new String[] {"1", "2", "3"},
new String[] {"4", "5", "6"},
new String[] {"7", "8", "9"}
},
null,
new String[][] {
new String[] {"10", "11", "12"},
new String[] {"13", "14", "15"},
new String[] {"16", "17", "18"}
}
};
print3DArray(arrays);
}
Bad Code Example - Use the tools of the language
static void print3DArray(String[][][] arrays) {
System.out.print("[");
for (String[][] array : arrays) {
if (array == null) {
continue;
}
System.out.print("[");
for (String[] arr : array) {
if (arr == null) {
continue;
}
System.out.print("[");
for (String a : arr) {
System.out.print(a + ", ");
}
System.out.print("], ");
}
System.out.print("], ");
}
System.out.print("]\n");
}
Bad Code Example - Separate logic into simple methods
static void print3DArray(String[][][] arrays) {
System.out.print("[");
for (String[][] array : arrays) {
print2DArray(array);
System.out.print(", ");
}
System.out.print("]\n");
}
static void print2DArray(String[][] array) {
if (array != null) {
System.out.print("[");
for (String[] arr : array) {
print1DArray(arr);
System.out.print(", ");
}
System.out.print("]");
}
}
static void print1DArray(String[] arr) {
if (arr != null) {
System.out.print("[");
for (String a : arr) {
System.out.print(a + ", ");
}
System.out.print("]");
}
}
Bad Code Example - Code generically; don’t repeat yourself
static void print3DArray(String[][][] arrays) {
printCommaSeparated(arrays);
System.out.print("\n");
}
static void print2DArray(String[][] array) {
printCommaSeparated(array);
}
static void print1DArray(String[] arr) {
printCommaSeparated(arr);
}
static <T> void printCommaSeparated(T[] arr) {
if (arr != null) {
System.out.print("[");
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]);
if (i < arr.length - 1) {
System.out.print(", ");
}
}
System.out.print("]");
}
}
Bad Code Example - Don’t reinvent the wheel
static void print3DArray(String[][][] arrays) {
printCommaSeparated(arrays);
System.out.print("\n");
}
static void print2DArray(String[][] array) {
printCommaSeparated(array);
}
static void print1DArray(String[] arr) {
printCommaSeparated(arr);
}
static <T> void printCommaSeparated(T[] arr) {
if (arr != null) {
System.out.print(Arrays.toString(arr));
}
}
Better Code Example - Cheat Don’t reinvent the wheel, again
static <T> void printArray(T[] arr) {
System.out.print(Arrays.deepToString(arr));
}
Original vs Refactored
static void print3DArray(String[][][] arrays) {
System.out.print("[");
for (int i = 0; i < arrays.length; i++) {
if (arrays[i] == null) {
continue;
}
System.out.print("[");
for (int j = 0; j < arrays[i].length; j++) {
if (arrays[i][j] == null) {
continue;
}
System.out.print("[");
for (int k = 0; k < arrays[i][j].length; k++) {
System.out.print(arrays[i][j][k]);
if (k < arrays[i][j].length - 1) {
System.out.print(", ");
}
}
System.out.print("]");
if (j < arrays[i].length - 1) {
System.out.print(", ");
}
}
System.out.print("]");
if (i < arrays.length - 1) {
System.out.print(", ");
}
}
System.out.print("]\n");
}
static <T> void printArray(T[] arr) {
System.out.print(Arrays.deepToString(arr));
}
Bonus: Quake III - Fast Inverse Square Root (with original comments)
float q_rsqrt(float number)
{
long i;
float x2, y;
const float threehalfs = 1.5F;
x2 = number * 0.5F;
y = number;
i = * ( long * ) &y; // evil floating point bit level hacking
i = 0x5f3759df - ( i >> 1 ); // what the fuck?
y = * ( float * ) &i;
y = y * ( threehalfs - ( x2 * y * y ) ); // 1st iteration
// y = y * ( threehalfs - ( x2 * y * y ) ); // 2nd iteration, this can be removed
return y;
}
Good Style and Clean Code Guidelines
Writing Clean Code, Summary
Documentation
Lecture 31, CS61B, Fall 2024
Design
Managing Complexity
Documentation
Group Coordination
Q&A
Documentation Intro
Why Documentation?
"We don't have enough time”
"No-one would read it anyway”
"The code should be self-documenting”
Documentation Example
What can we improve about this documentation?
/**
* Changes location of the trees in the world
* We use java.util.Random.
*/
public boolean movePlayer(int x, int y) {...}
Documentation Example
/**
* Moves the player to a specified location within the game world.
* Validates the destination and checks for bounds.
*
* @param x The x-coordinate of the destination (horizontal position).
* @param y The y-coordinate of the destination (vertical position).
* @return 'true' if the move is successful, 'false' otherwise.
* @throws OutOfBoundsException if coordinates are outside the world.
* @usage To move the player to (5, 10), call movePlayer(5, 10).
*/
public boolean movePlayer(int x, int y) {...}
Writing Good Git Commits
There are well-established conventions:
Rules: https://cbea.ms/git-commit/
Example: Google Truth Library (We use for writing tests!)
Writing Good Git Commits
Good Commit Messages:
Some Bad Commit Messages
Overview
Poor documentation can impact productivity in three main areas:
Group Coordination
Lecture 31, CS61B, Fall 2024
Design
Managing Complexity
Documentation
Group Coordination
Q&A
Project 3: BYOW
Project 3 is a team project.
Two main reasons:
Ancillary reason: Also reduces programming workload per person, but the project is small enough that a single person can handle it.
Teamwork is Hard
In the real world, some tasks are much too large to be handled by a single person.
When faced with the same task, some teams succeed, where others may fail.
Last fall, ~9% of partnerships thought their partnership did not work well for them.
Strategies for Collaboration: Pair Programming
Pair programming is a technique where two programmers work on a single station
Benefits:
Tips:
You can do this remotely too!�IntelliJ: Code With Me
VS Code: Live Share
Agile Methodology
Agile is a flexible and iterative process to software development that emphasizes collaboration, feedback, and small, rapid releases.
Responds to change, ensures product alignment, and reduces risk.
Scrum Framework
An Agile framework that organizes work into structured “sprints.”
The Sprint Cycle
Scrum in Project 3
Let’s take a look at what this schedule may look like
Proj3A Sprint
Wednesday 11/13
Thursday 11/14
Friday 11/15
Saturday + Sunday 11/16 - 11/17
Monday 11/18
Total
~8 hours
Proj3B/C Sprint
Tuesday 11/19
Wednesday 11/20
Thursday 11/21
Friday 11/22
Saturday + Sunday 11/23 - 11/24
Monday 11/25
Tuesday 11/26
Total
~7 hours
Q&A
Lecture 31, CS61B, Fall 2024
Design
Managing Complexity
Documentation
Group Coordination
Q&A