Advanced Programming in Java CM3: the Software Development Process
Advanced Programming in Java
CM3: the Software Development Process
Arthur Bit-Monnot
INSA 4IR
Arthur Bit-Monnot | INSA 4IR 1 / 36
Advanced Programming in Java CM3: the Software Development Process | Software Life Cycle
Section 1
Software Life Cycle
Arthur Bit-Monnot | INSA 4IR 2 / 36
Advanced Programming in Java CM3: the Software Development Process | Software Life Cycle
Phases of Software Development (outdated)
1 Requirements Gathering
Identify and document the software’s purpose, features, and constraints.
2 Planning
Create a project plan, including timelines, resources, and budget.
3 Design
Define the software architecture, user interfaces, and data structures.
4 Implementation
Write code, develop features, and integrate components.
5 Testing
Verify that the software meets the specified requirements and is free from defects.
6 Deployment
Release the software to users or production environments.
7 Maintenance
Continuously update, enhance, and fix issues in the software.
Arthur Bit-Monnot | INSA 4IR 3 / 36
Advanced Programming in Java CM3: the Software Development Process | Software Life Cycle
Software Development
Previous slide: a bit dated
software was monolithic, produced by single company
Selling a given version
Releasing a new version every few years
Adapted from existing industrial dev process
Changing factors:
complexity increase (open source as enabler)
ease of delivery: paper ⇒ CD-ROM ⇒ Network
Arthur Bit-Monnot | INSA 4IR 4 / 36
Advanced Programming in Java CM3: the Software Development Process | Software Life Cycle
Software development: the Agile Era
Nowadays. . .
. . . software development is much more iterative
(xkcd/1428)
Arthur Bit-Monnot | INSA 4IR 5 / 36
Advanced Programming in Java CM3: the Software Development Process | Software Life Cycle
Software development: the Agile Era
Nowadays. . .
. . . software development is much more iterative
Specificities of software industry:
Cost of replacing a defective piece in your product:
Google vs Volkswagen
(xkcd/1428)
Arthur Bit-Monnot | INSA 4IR 5 / 36
Advanced Programming in Java CM3: the Software Development Process | Software Life Cycle
Ensuring quality in Increasingly Complex Software
decouple concerns into independent modules
large scale: micro-services
medium: libraries
small packages/class/function
agree on services provided by each module
Arthur Bit-Monnot | INSA 4IR 6 / 36
Advanced Programming in Java CM3: the Software Development Process | Software Life Cycle
Guidelines
1 Identify the responsibility of each module (class/package/library)
non overlapping concerns
2 Document the module’s contract
type system (everything that is public)
textual documentation (limitations, perf guarantees, . . . )
3 Hide implementation details
private / protected methods and classes
Arthur Bit-Monnot | INSA 4IR 7 / 36
Advanced Programming in Java CM3: the Software Development Process | Software Life Cycle
Your code provides a Service
Would your threading code keep working if the JVM providers were to:
Change the name of the Thread class?
Arthur Bit-Monnot | INSA 4IR 8 / 36
Advanced Programming in Java CM3: the Software Development Process | Software Life Cycle
Your code provides a Service
Would your threading code keep working if the JVM providers were to:
Change the name of the Thread class? → No
Remove a (public) method?
Arthur Bit-Monnot | INSA 4IR 8 / 36
Advanced Programming in Java CM3: the Software Development Process | Software Life Cycle
Your code provides a Service
Would your threading code keep working if the JVM providers were to:
Change the name of the Thread class? → No
Remove a (public) method? → No
Add a method
Arthur Bit-Monnot | INSA 4IR 8 / 36
Advanced Programming in Java CM3: the Software Development Process | Software Life Cycle
Your code provides a Service
Would your threading code keep working if the JVM providers were to:
Change the name of the Thread class? → No
Remove a (public) method? → No
Add a method → Yes
Change the return type of a method
Arthur Bit-Monnot | INSA 4IR 8 / 36
Advanced Programming in Java CM3: the Software Development Process | Software Life Cycle
Your code provides a Service
Would your threading code keep working if the JVM providers were to:
Change the name of the Thread class? → No
Remove a (public) method? → No
Add a method → Yes
Change the return type of a method → No (or to something more specific)
Change a method’s parameter name
Arthur Bit-Monnot | INSA 4IR 8 / 36
Advanced Programming in Java CM3: the Software Development Process | Software Life Cycle
Your code provides a Service
Would your threading code keep working if the JVM providers were to:
Change the name of the Thread class? → No
Remove a (public) method? → No
Add a method → Yes
Change the return type of a method → No (or to something more specific)
Change a method’s parameter name → Yes (but not in all languages)
Change the parameter type
Arthur Bit-Monnot | INSA 4IR 8 / 36
Advanced Programming in Java CM3: the Software Development Process | Software Life Cycle
Your code provides a Service
Would your threading code keep working if the JVM providers were to:
Change the name of the Thread class? → No
Remove a (public) method? → No
Add a method → Yes
Change the return type of a method → No (or to something more specific)
Change a method’s parameter name → Yes (but not in all languages)
Change the parameter type → No (or to something more general)
Change the name of the main thread?
Arthur Bit-Monnot | INSA 4IR 8 / 36
Advanced Programming in Java CM3: the Software Development Process | Software Life Cycle
Your code provides a Service
Would your threading code keep working if the JVM providers were to:
Change the name of the Thread class? → No
Remove a (public) method? → No
Add a method → Yes
Change the return type of a method → No (or to something more specific)
Change a method’s parameter name → Yes (but not in all languages)
Change the parameter type → No (or to something more general)
Change the name of the main thread? → It should (but does it?)
Change the implementation of setName() to avoid memory allocation?
Arthur Bit-Monnot | INSA 4IR 8 / 36
Advanced Programming in Java CM3: the Software Development Process | Software Life Cycle
Your code provides a Service
Would your threading code keep working if the JVM providers were to:
Change the name of the Thread class? → No
Remove a (public) method? → No
Add a method → Yes
Change the return type of a method → No (or to something more specific)
Change a method’s parameter name → Yes (but not in all languages)
Change the parameter type → No (or to something more general)
Change the name of the main thread? → It should (but does it?)
Change the implementation of setName() to avoid memory allocation? → Yes
Arthur Bit-Monnot | INSA 4IR 8 / 36
Advanced Programming in Java CM3: the Software Development Process | Software Life Cycle
/**
* Causes the currently executing thread to sleep ( temporarily cease
* execution) for the specified number of milliseconds plus the specified
* number of nanoseconds, subject to the precision and accuracy of system
* timers and schedulers. The thread does not lose ownership of any
* monitors.
*
* @param millis
* the length of time to sleep in milliseconds
* @param nanos
* {@code 0-999999} additional nanoseconds to sleep
* @throws IllegalArgumentException
* if the value of {@code millis} is negative, or the value of
* {@code nanos} is not in the range {@code 0-999999}
* ...
*/
public static void sleep(long millis, int nanos) throws InterruptedException {
}
Arthur Bit-Monnot | INSA 4IR 9 / 36
Advanced Programming in Java CM3: the Software Development Process | Software Life Cycle
Setting boundaries
Everything that is visible (i.e. public):
will be relied upon by your users
cannot be changed without breaking someone else’s code
Everything that is hidden:
can be freely changed in the future
only your code is affected
Arthur Bit-Monnot | INSA 4IR 10 / 36
Advanced Programming in Java CM3: the Software Development Process | Software Life Cycle
Setting boundaries
Everything that is visible (i.e. public):
will be relied upon by your users
cannot be changed without breaking someone else’s code
Everything that is hidden:
can be freely changed in the future
only your code is affected
Some things are visible but not contractual:
e.g. java’s default thread is called main
should not be relied upon
(xkcd/1172)
Arthur Bit-Monnot | INSA 4IR 10 / 36
Advanced Programming in Java CM3: the Software Development Process | Software Life Cycle
Setting boundaries: Java visibility modifiers
Java visibility modifiers:
private: inside the class
default: inside the package
protected: inside the package and subclasses
public: everywhere (your contract)
Boundaries should be set for each class and package
Arthur Bit-Monnot | INSA 4IR 11 / 36
Advanced Programming in Java CM3: the Software Development Process | Reliable Code: Error Handling
Section 2
Reliable Code: Error Handling
Arthur Bit-Monnot | INSA 4IR 12 / 36
Advanced Programming in Java CM3: the Software Development Process | Reliable Code: Error Handling
Reliable Code: Error Handling
Path filePath = [Link]("/tmp/secret");
String content = [Link](filePath);
[Link](content);
Arthur Bit-Monnot | INSA 4IR 13 / 36
Advanced Programming in Java CM3: the Software Development Process | Reliable Code: Error Handling
Reliable Code: Error Handling
Path filePath = [Link]("/tmp/secret");
String content = [Link](filePath);
[Link](content);
Arthur Bit-Monnot | INSA 4IR 13 / 36
Advanced Programming in Java CM3: the Software Development Process | Reliable Code: Error Handling
Student’ solution to error handling
Path filePath = [Link]("/tmp/secret");
String content = null;
try {
content = [Link](filePath);
} catch (IOException e) {
}
[Link](content);
AKA: “Make the Compiler Shut Up” approach
Arthur Bit-Monnot | INSA 4IR 14 / 36
Advanced Programming in Java CM3: the Software Development Process | Reliable Code: Error Handling
The Cases of Error Handling
1 We can recover from the error locally (local handling)
2 The error may be handled by someone else (the caller) with more context information
(error propagation)
3 There is no possibility of recovering from the error (crash)
Arthur Bit-Monnot | INSA 4IR 15 / 36
Advanced Programming in Java CM3: the Software Development Process | Reliable Code: Error Handling
Error Handling: Error propagation
public static String readFile(String filename)
throws UnreadableFile
{
Path filePath = [Link](filename);
try {
return [Link](filePath);
} catch (IOException e) {
// propagate error upwards
throw new UnreadableFile(filename, e);
}
}
Arthur Bit-Monnot | INSA 4IR 16 / 36
Advanced Programming in Java CM3: the Software Development Process | Reliable Code: Error Handling
Error Handling: Error propagation
// Error raised when the system is unable
// to read a file
public static String readFile(String filename) class UnreadableFile extends Exception {
throws UnreadableFile // File that couldn't be access
{ private final String filename;
Path filePath = [Link](filename); // Error thrown by the JVM when attempt
try { private final IOException cause;
return [Link](filePath);
} catch (IOException e) { UnreadableFile(String filename,
// propagate error upwards IOException cause) {
throw new UnreadableFile(filename, e); [Link] = filename;
} [Link] = cause;
} }
...
Arthur Bit-Monnot | INSA 4IR 16 / 36
Advanced Programming in Java CM3: the Software Development Process | Reliable Code: Error Handling
Error Handling: Local Recovery
Config loadConfig() {
String config = readFile("~/.conf");
return new Config(config);
}
Arthur Bit-Monnot | INSA 4IR 17 / 36
Advanced Programming in Java CM3: the Software Development Process | Reliable Code: Error Handling
Error Handling: Local Recovery
static final String DEFAULT_CONFIG = "address=localhost; port=80";
static Config loadConfig() {
String config = null;
try {
config = readFile("~/.conf");
} catch (UnreadableFile e) {
//
[Link]("Could not read config file "+[Link] +
"\n Caused by "+ [Link]);
[Link]("Loading default configuration");
config = DEFAULT_CONFIG;
}
return new Config(config);
}
Arthur Bit-Monnot | INSA 4IR 18 / 36
Advanced Programming in Java CM3: the Software Development Process | Reliable Code: Error Handling
Error Handling: Unrecoverable Error
public static void main(String[] args) {
Config config = loadConfig();
startHttpServer(config);
...
}
Arthur Bit-Monnot | INSA 4IR 19 / 36
Advanced Programming in Java CM3: the Software Development Process | Reliable Code: Error Handling
Error Handling: Unrecoverable Error
public static void main(String[] args) {
Config config = loadConfig();
try {
startHttpServer(config);
} catch (Exception e) {
// log error
[Link]();
[Link]("Could not start HTTP Server");
// Terminate program with error code
[Link](1);
}
}
Arthur Bit-Monnot | INSA 4IR 20 / 36
Advanced Programming in Java CM3: the Software Development Process | Reliable Code: Error Handling
Error Handling: Guidelines
How should I handle the error?
1 Recover locally (retry, default, ignore, . . . )
2 Delegate responsibility to caller (rethrow)
3 Take the responsibility of terminating ([Link](), throw new
RuntimeException())
Who should I communicate the error to?
1 Developer / Technical User (logging, stack traces)
2 End User (standard output, dialog)
Arthur Bit-Monnot | INSA 4IR 21 / 36
Advanced Programming in Java CM3: the Software Development Process | Reliable Code: Tests
Section 3
Reliable Code: Tests
Arthur Bit-Monnot | INSA 4IR 22 / 36
Advanced Programming in Java CM3: the Software Development Process | Reliable Code: Tests
Reliable Code: Tests
Tests ensure that:
the code is correct
fullfills its contract
Main approach in students population: Limitations:
try the most obvious case in the main not exhaustive
function not durable
Arthur Bit-Monnot | INSA 4IR 23 / 36
Advanced Programming in Java CM3: the Software Development Process | Reliable Code: Tests
Software Testing
Software testing is the process of building a test suite that:
ensures that the code fulfills its contract
can be automatically run
will stay throughout the code’s lifecycle
Relies on software testing libraries
> JUnit in Java (most popular option)
Arthur Bit-Monnot | INSA 4IR 24 / 36
Advanced Programming in Java CM3: the Software Development Process | Reliable Code: Tests
The Bare Minimum: Gradual Testing
You already write tests, don’t throw them away!
// PROHIBITED: make your test
@Test
// automatable and durable
public void testAdd() {
public static void main(String[] args) {
int result = add(4, 5);
int result = add(4, 5);
assert result == 9;
[Link](result);
}
}
Rule of thumb:
always write testing code in a dedicated method that you will keep
change your manual inspections (prints) with automatic ones (asserts)
Arthur Bit-Monnot | INSA 4IR 25 / 36
Advanced Programming in Java CM3: the Software Development Process | Reliable Code: Tests
What is Test Driven Development (TDD) ?
Test-Driven Development is a software development process that emphasizes writing tests
before writing the actual code.
TDD Workflow Steps
1 Write a failing test for a small unit of functionality.
2 Write the minimum amount of code to make the test pass.
3 Refactor the code for simplicity and maintainability.
4 Repeat the process for the next unit of functionality.
Arthur Bit-Monnot | INSA 4IR 26 / 36
Advanced Programming in Java CM3: the Software Development Process | Reliable Code: Tests
Benefits of Tests / TDD
Improved Code Quality: helps catch and fix defects early in the development process.
Sustainable Development: It promotes smaller, manageable iterations (TDD).
Documentation: Tests serve as living documentation for your code.
Confidence: Developers have confidence in the code’s correctness in the long run.
Arthur Bit-Monnot | INSA 4IR 27 / 36
Advanced Programming in Java CM3: the Software Development Process | Reliable Code: Tests
Conclusion
Reliable Software. . .
clearly states its promises (public API / Contract)
has slack to evolve (hidden implementation details)
correctly handles corner cases (error handling)
can always be shown to fulfill its contract through tests
Arthur Bit-Monnot | INSA 4IR 28 / 36
Advanced Programming in Java CM3: the Software Development Process | Code Quality
Section 4
Code Quality
Arthur Bit-Monnot | INSA 4IR 29 / 36
Advanced Programming in Java CM3: the Software Development Process | Code Quality
Correct vs Good Software
Process of producing correct software (repeated):
1 understand requirements
2 solve problem
3 validate correctness (test)
Arthur Bit-Monnot | INSA 4IR 30 / 36
Advanced Programming in Java CM3: the Software Development Process | Code Quality
Correct vs Good Software
Process of producing correct software (repeated):
1 understand requirements
2 solve problem
3 validate correctness (test)
Iterative process in order to:
refine understanding of requirements (better understanding of edge cases)
find a solution path (algorithms, API)
Output:
better understanding
working implementation
Arthur Bit-Monnot | INSA 4IR 30 / 36
Advanced Programming in Java CM3: the Software Development Process | Code Quality
Code: Benefits & Costs
Correct code provides immediate benefits:
the value of the feature it implements
Arthur Bit-Monnot | INSA 4IR 31 / 36
Advanced Programming in Java CM3: the Software Development Process | Code Quality
Code: Benefits & Costs
Correct code provides immediate benefits:
the value of the feature it implements
Good software :
is correct (bare minimum to ask)
Arthur Bit-Monnot | INSA 4IR 31 / 36
Advanced Programming in Java CM3: the Software Development Process | Code Quality
Code: Benefits & Costs
Correct code provides immediate benefits:
the value of the feature it implements
What are these costs ?
developer time
Good software : How to reduce them?
is correct (bare minimum to ask) improve ease of understanding
minimize the costs of the added code
ensure that the benefits are durable
Arthur Bit-Monnot | INSA 4IR 31 / 36
Advanced Programming in Java CM3: the Software Development Process | Code Quality
Software costs mostly related to readability
Ease of understanding:
what it does?
why it does it?
how to use it?
Way forward:
make your code as clear and simple as possible
Benefits:
easier to correct, improve, evolve, replace
otherwise: technical debt and will be removed at the next refactor
easier to use (maximize readability of consumer’s code)
Arthur Bit-Monnot | INSA 4IR 32 / 36
Advanced Programming in Java CM3: the Software Development Process | Code Quality
Example
void voteChanged(Vote oldVote, Vote newVote) {
var score = getScore();
if (newVote != oldVote) {
if (newVote == Up) {
score += (oldVote == Down ? 2 : 1);
} else if (newVote == Down) {
score -= (oldVote == Up ? 2 : 1);
} else if (newVote == None) {
score += (oldVote == Up ? -1 : 1);
}
}
setScore(score);
};
Source: Adapted from “The Art of Readable Code”
Arthur Bit-Monnot | INSA 4IR 33 / 36
Advanced Programming in Java CM3: the Software Development Process | Code Quality
Example (refactored)
void updateScore(Vote oldVote, Vote newVote) {
var score = getScore();
score -= voteValue(oldVote);
score += voteValue(newVote);
setScore(score);
}
int voteValue(Vote vote) {
return switch (vote) {
case Down -> -1;
case None -> 0;
case Up -> 1;
}
}
Arthur Bit-Monnot | INSA 4IR 34 / 36
Advanced Programming in Java CM3: the Software Development Process | Code Quality
Development process
produce a correct draft
1 understand requirements
2 solve problem
3 validate correctness (test)
4 repeat
improve and finalize
1 simplify (refactor) and improve (readability)
2 review (self)
3 repeat
submit (pull request)
1 peer review?
2 accept (merge, publish)
Arthur Bit-Monnot | INSA 4IR 35 / 36
Advanced Programming in Java CM3: the Software Development Process | Code Quality
Guidelines for Readable Code
Reference: The Art of Readable Code (linked on course website)
fairly comprehensive book on how to locally improve readability
(faster to read than it seems)
Arthur Bit-Monnot | INSA 4IR 36 / 36
Advanced Programming in Java CM3: the Software Development Process | Code Quality
Guidelines for Readable Code
Reference: The Art of Readable Code (linked on course website)
fairly comprehensive book on how to locally improve readability
(faster to read than it seems)
If it is not possible to make the code readable, it usually hint for a larger architectural problem
(i.e. requiring a large refactor).
Arthur Bit-Monnot | INSA 4IR 36 / 36