With companies starting to hire for graduate roles and internships, now is the ideal time to start looking for your job. UC Women in Tech Society is hosting a workshop which will help you with every part of the hiring process.
There will also be the chance to meet with recent grads and find out what the job-seeking experience is like from someone who was in your shoes a year or two ago.
You are welcome to come whether you are a WiTSoc member or not. Please respond to our Facebook event so we know how much pizza to get for everyone: https://fb.me/e/1gE8ihxdK
Copyright By PowCoder代写 加微信 powcoder
Software Engineering I SENG201
Lecture 16 – Design and coding practices March 28, 2022
Previous lecture
1. Introduction
2. Throwing and catching exceptions
3. Types of exceptions
4. Writing your own exception
1. Relationships between classes in UML
2. Basic good design and coding practices
1. Relationships between classes in UML
2. Basic good design and coding practices
Motivation
“Program complexity grows until it exceeds the capability of the [engineer] who must maintain it.”
– 7th Law of Computer Programming1
1http://www.cs.oberlin.edu/~jwalker/humor/lawsOfComputerPrograming.html
Relationships between classes
Class relationships in UML
• Dependency – Uses
• Inheritance (and interfaces/abstract classes) – Is-a-kindof
• Association – Has-a
• Aggregation and composition – Is-part-of
– Whole-part
Association
relationship
Containment without whole-part relationship
Dependency versus association
• Dependency: “use” of another type, e.g.,
– ThePlayerusessomeDicewhenplayingagame
– class Player { public void rollDice(Dice someDice); }
• Association: “ownership” of another type, e.g.,
– The Player has some Dice
– class Player { private Dice myDice; … }
Aggregation (form of association)
Department
Is-part-of
relationship
Lifetime of “part” does not depend on lifetime of aggregate
Objects assembled together to more complex object
Often not visible in code if aggregation or association
Multiplicities
Fast slide
• How many objects of a model element (e.g., class) at each end
• Example: a player should have one or more pets
Player 1 1..* Pet
• Options (examples)
Description
One-to-one
Student ─ Home
One-to-one (optional on left side)
DoB ─ Student
Many-to-many (optional on both sides)
Student ─ Book
Many-to-many (optional of left side)
Student ─ Book
One-to-many
Student ─ Language
Association versus aggregation
• Plain association indicates relationship between peers
– Neither class more important than the other
• Aggregation models “is-part-of” relationship
– One class is larger thing which has constituent parts – Nolinkinglifetimesofwholeandparts
– Parts can be added, modified, removed
Composition (form of aggregation)
Whole-part
relationship
Lifetime of “part” depends on lifetime of “whole”
Composition
• Stronger form of aggregation
– Strongownershipandcoincidentlifetime
– Part (Topping) can only be in one composite (Pizza)
– When pizza is gone, so are the toppings
Pizza 0..* Topping
Invoice Address
1. Relationships between classes in UML
2. Basic good design and coding practices
Motivation
“Any fool can write code that a computer can understand.
Good programmers write code that humans can understand.”
– (OO and agile software development guru)
Initial thought
https://twitter.com/housecor/status/400479246713229312 (Disclaimer: This is not an excuse to not comment code)
https://tech.palatinategroup.com/a-common-misconception-we-have-as-developers-is-that-the-consequences-of-bad-code-are-localised-to-7599c7031b69
What developers want from a job
Hacker News readers between September 5th and October 5th, 2017 (https://hackernoon.com/what-does-hacker-news-care-about-e364fb87431c)
Software development in practice
“Brownfield” rather than “greenfield”
– No “clean sheet” but existing systems, legacy software
When “coding” – a quick reality check
Code comprehension
Problem solving
Writing new code
How to achieve maintainable code?
• Create design and code that humans can comprehend
– Guidelinesinspiredbycognitivepsychologyandmentalprocesses,e.g.,
• Attention and memory
• Language use
• Problem solving
• Creativity and thinking • Assumption
– Smaller and less complex “units” typically easer to understand, test, reuse
• Typical “unit” in OO: method
• Typical “module” in OO: class
Disclaimer
• We introduce some basic guidelines – Many more to come, e.g., in SENG301
• Writing good code often require changing existing code – “Refactoring”
• Need to practice
– Discuss your code and design with tutors
Basic guidelines
• Guideline 1: Write short units of code
• Guideline 2: Write simple units of code
• Guideline 3: Write code once
• Guideline 4: Separate concerns into modules
• Guideline 5: Keep unit interfaces small
• Guideline 6: Write “clean code”
Study guidelines in your own time + apply them in project and labs
Guidelines 1 – write short units of code
• Try to limit length of code units to ~15 lines of code – Split long units into multiple smaller units
• Trade-off: short code is not always better – Unit should still do something meaningful
Fast slide
Example – write short units of code (1)
public void printOwing() {
Enumeration e = orders.elements(); double outstanding = 0.0;
// print banner
System.out.println (“**************************”);
System.out.println (“***** Customer Owes ******”);
System.out.println (“**************************”);
// calculate outstanding
while (e.hasMoreElements()) {
Order each = (Order) e.nextElement();
outstanding += each.getAmount();
//print details
System.out.println (“name: ” + name);
System.out.println (“amount ” + outstanding);
Example – write short units of code (2)
public void printOwing() {
Enumeration e = orders.elements(); double outstanding = 0.0;
printBanner();
// calculate outstanding
while (e.hasMoreElements()) {
Order each = (Order) e.nextElement();
outstanding += each.getAmount(); }
//print details
System.out.println (“name: ” + name);
System.out.println (“amount ” + outstanding);
public void printBanner()
// print banner
System.out.println (“**************************”);
System.out.println (“***** Customer Owes ******”);
System.out.println (“**************************”);
• Code easier to maintain
• Increased cohesion
• Code requires less documentation
• printBanner() can be used anywhere
Guideline 2 – write simple units of code
Fast slide
• Fewer branch points makes units easier to modify and test
– Limit the number of branch points per unit to ~4
– Split complex units into simpler ones, avoid complex units
Example – write simple units of code (1)
• Two consecutive if-statements
– Branch and execution path coverage (four possible “flows”)
Example – write simple units of code (2)
• calculateDepth
• Binary search tree root node
• An integer we try to find in the tree
– Determines
• Whether integer occurs in the tree; if so, returns depth of integer in tree
• Otherwise, print error
Example – write simple units of code (3)
public static int calculateDepth(BinaryTreeNode
int depth = 0;
if (t.getValue() == n) {
return depth;
if (n < t.getValue()) {
BinaryTreeNode
System.out.println(“Value not found in tree!”);
return 1 + calculateDepth(left, n);
BinaryTreeNode
System.out.println(“Value not found in tree!”);
return 1 + calculateDepth(right, n);
Example – write simple units of code (4)
t.getValue() == n
n < t.getValue()
return depth
right == null
left == null
return ...
return ...
Example – write simple units of code (5)
public static int calculateDepth(BinaryTreeNode
int depth = 0;
if (t.getValue() == n) return depth;
if (n < t.getValue() && t.getLeft() != null)
return 1 + calculateDepth(t.getLeft(), n);
if (n > t.getValue() && t.getRight() != null)
return 1 + calculateDepth(t.getRight(), n);
throw new TreeException(“Value not found in tree!”);
• Got rid of the nested conditional
– Identified distinct cases
– Inserted return statements for these distinct cases
Example – write simple units of code (6)
t.getValue() == n
return depth
n < t.getValue() && t.getLeft() != null
return ...
n > t.getValue() && t.getRight() != null
return …
throw exception
Guideline 3 – write code once
• Bugs need to be fixed at multiple places
– Inefficient and error-prone
– Do not copy code
– Reuse:callexistingmethods
– Enablereuse:writereusable,genericcode
• Related guideline: don’t reinvent the wheel
– Reuse existing solutions to recurring problems
– Reusability – enable others to reuse
Fast slide
Example – write code once (1)
Remember from before
public void printOwing() {
Enumeration e = orders.elements(); double outstanding = 0.0;
printBanner();
// calculate outstanding
while (e.hasMoreElements()) {
Order each = (Order) e.nextElement();
outstanding += each.getAmount(); }
//print details
System.out.println (“name: ” + name);
System.out.println (“amount ” + outstanding);
public void printBanner()
// print banner
System.out.println (“**************************”);
System.out.println (“***** Customer Owes ******”);
System.out.println (“**************************”);
Example – write code once (2)
public void printOwing() {
Enumeration e = orders.elements(); double outstanding = 0.0;
printBanner(“Customer Owes”);
// calculate outstanding
while (e.hasMoreElements()) {
Order each = (Order) e.nextElement();
outstanding += each.getAmount(); }
//print details
System.out.println (“name: ” + name);
System.out.println (“amount ” + outstanding);
public void printBanner(String bannerText)
// print banner
System.out.println (“**************************”);
System.out.println (“***** “ + bannerText + “ ******”);
System.out.println (“**************************”);
Further thoughts on write code once
Fast slide
• Idea also applies to higher level design (e.g., class diagrams) – DRY:Don’tRepeatYourself
• Get rid of redundant code, keep it at single place – Singe Responsibility principle
• Each component of system should have one single responsibility – KISS:KeepItSimpleStupid
• Keep system as simple as possible – Simplicity – YAGNI:YouAin’tGonnaNeedIt
• Create functionality only when necessary
Guideline 4 – separate concerns in modules
• Changes in loosely coupled codebase easier to execute
– Avoid large modules to achieve loose coupling
– Assign responsibilities to separate modules
– Hide implementation details behind interfaces
• Related guidelines: Separation of concerns + modularity – Dividesoftwareintoparts(components,modules)
– Build each part once
Fast slide
Example – separate concerns in modules (1)
• Organ donation
– Identifyreal-worldentitiesinvolved
• Recipients
• Transplants
• Clinicians
• Hospitals
• Medical records
• Appointments
• Medications
Example – separate concerns in modules (2)
• Choose entity and create class
name dateOfBirth nationality bloodType previousDiseases currentAddress gender
weight levelOfEducation martialStatus
name dateOfBirth nationality bloodType previousDiseases currentAddress gender
weight levelOfEducation martialStatus
dateOfBirth? currentAddress? gender?
healthRecord (class)? backgroundData (class)?
Guideline 5 – keep unit interfaces small
Fast slide
• Try to limit the number of parameters per unit to at most 4 – Extract many parameters into objects
Example – keep unit interfaces small
public void printPersonalData(String firstName, String lastName, int age, String city) {
System.out.println(“First name: ” + firstName); System.out.println(“Last name: ” + lastName); System.out.println(“Age: ” + age); System.out.printon(“City: ” + city);
getFirstName() getLastName() getAge() getCity()
public void printPersonalData(Person person) {
System.out.println(“First name: ” + person.getFirstName());
System.out.println(“Last name: ” + person.getLastName());
System.out.println(“Age: ” + person.getAge());
System.out.printon(“City: ” + person.getCity());
Guideline 6 – write “clean code”
Fast slide
• Do not leave code “smells” behind
– Remove unused “text”, statements, etc. from code
– E.g., bad comments, code in comments, dead code, long identifiers
1. Relationships between classes in UML
2. Basic good design and coding practices
Cartoon of the day
Key lesson: Good design and code quality increase maintainability and make fixing bugs less painful.
程序代写 CS代考 加微信: powcoder QQ: 1823890830 Email: powcoder@163.com