Week 8 [Mon, Oct 7th] - Topics

Last week, you learned intermediate-level class diagram notation. But the quiz only focused on interpreting such diagrams. This week, we cover the aspect of drawing intermediate-level class diagrams to match code. Here are what you can do:
1. Do Part 1 of this week's quiz (which covers the same area).
2. Watch the worked examples in the following videos to learn the process of drawing intermediate-level class diagrams to match code.

Video Drawing class/object diagrams (intermediate) - Action, Task, History

Video Drawing class/object diagrams (intermediate) - Person, Inbox, Message

Video Drawing class/object diagrams (intermediate) - Person, Project, Task

Detailed Table of Contents



Guidance for the item(s) below:

This week, we learn a few design principles that you can try to apply in your project.

These principles build on top of the design fundamentals you learned earlier (i.e., abstraction, coupling, cohesion).

[W8.1] Design Principles

W8.1a

Principles → Separation of concerns principle

Video

Can explain separation of concerns principle

Separation of concerns principle (SoC): To achieve better modularity, separate the code into distinct sections, such that each section addresses a separate concern. -- Proposed by Edsger W. Dijkstra

A concern in this context is a set of information that affects the code of a computer program.

Examples for concerns:

  • A specific feature, such as the code related to the add employee feature
  • A specific aspect, such as the code related to persistence or security
  • A specific entity, such as the code related to the Employee entity

Applying reduces functional overlaps among code sections and also limits the ripple effect when changes are introduced to a specific part of the system.

If the code related to persistence is separated from the code related to security, a change to how the data are persisted will not need changes to how the security is implemented.

This principle can be applied at the class level, as well as at higher levels.

The n-tier architecture utilizes this principle. Each layer in the architecture has a well-defined functionality that has no functional overlap with each other.

This principle should lead to higher cohesion and lower coupling.


Exercises:

Correct statements about SoC



W8.1b

Principles → Single responsibility principle

Video

Can explain single responsibility principle

Single responsibility principle (SRP): A class should have one, and only one, reason to change. -- Robert C. Martin

If a class has only one responsibility, it needs to change only when there is a change to that responsibility.

Consider a TextUi class that does parsing of the user commands as well as interacting with the user. That class needs to change when the formatting of the UI changes as well as when the syntax of the user command changes. Hence, such a class does not follow the SRP.

Gather together the things that change for the same reasons. Separate those things that change for different reasons. ―- Agile Software Development, Principles, Patterns, and Practices by Robert C. Martin


Resources:

W8.1c : OPTIONAL

Principles → Liskov substitution principle


W8.1d : OPTIONAL

Principles → Open-closed principle


W8.1e : OPTIONAL

Principles → Law of Demeter


W8.1f : OPTIONAL

Principles → Interface segregation principle


W8.1g : OPTIONAL

Principles → Dependency inversion principle


W8.1h : OPTIONAL

Principles → SOLID principles


W8.1i : OPTIONAL

Principles → YAGNI principle


W8.1j : OPTIONAL

Principles → DRY principle


W8.1k : OPTIONAL

Principles → Brooks' law



[W8.2] Architecture : OPTIONAL

Video


Architecture: Overview

Video

W8.2a : OPTIONAL

Design → Architecture → Introduction → What


W8.2b : OPTIONAL

Design → Architecture → Architecture Diagrams → Reading


W8.2c : OPTIONAL

Design → Architecture → Architecture Diagrams → Drawing


W8.2d : OPTIONAL

Design → Introduction → Multi-level design



Architecture: Styles

Video

W8.2e : OPTIONAL

Design → Architecture → Styles → What


W8.2f : OPTIONAL

Design → Architecture → Styles → n-Tier Style → What


W8.2g : OPTIONAL

Design → Architecture → Styles → Client-Server Style → What


W8.2h : OPTIONAL

Design → Architecture → Styles → Event-Driven Style → What


W8.2i : OPTIONAL

Design → Architecture → Styles → Transaction Processing Style → What


W8.2j : OPTIONAL

Design → Architecture → Styles → Service-Oriented Style → What


W8.2k : OPTIONAL

Design → Architecture → Styles → Using styles


W8.2l : OPTIONAL

Design → Architecture → Styles → More styles



[W8.3] Design: High-Level View : OPTIONAL

Video

W8.3a : OPTIONAL

Design → Design Approaches → Top-down and bottom-up design


W8.3b : OPTIONAL

Design Approaches → Agile Design → Agile design



Guidance for the item(s) below:

As you add more and more Java classes to your project, keeping all those classes in the same directory becomes untenable. The solution is covered in the next topic.

[W8.4] Java: Packages

W8.4a

C++ to Java → Miscellaneous Topics → Packages

Video

Can use Java packages

You can organize your types (i.e., classes, interfaces, enumerations, etc.) into packages for easier management (among other benefits).

To create a package, you put a package statement at the very top of every source file in that package. The package statement must be the first line in the source file and there can be no more than one package statement in each source file. Furthermore, the package of a type should match the folder path of the source file. Similarly, the compiler will put the .class files in a folder structure that matches the package names.

The Formatter class below (in <source folder>/seedu/tojava/util/Formatter.java file) is in the package seedu.tojava.util. When it is compiled, the Formatter.class file will be in the location <compiler output folder>/seedu/tojava/util:

package seedu.tojava.util;

public class Formatter {
    public static final String PREFIX = ">>";

    public static String format(String s){
        return PREFIX + s;
    }
}

Package names are written in all lower case (not camelCase), using the dot as a separator. Packages in the Java language itself begin with java. or javax. Companies use their reversed Internet domain name to begin their package names.

For example, com.foobar.doohickey.util can be the name of a package created by a company with a domain name foobar.com

To use a public from outside its package, you must do one of the following:

  1. Use the to refer to the member
  2. Import the package or the specific package member

The Main class below has two import statements:

  • import seedu.tojava.util.StringParser: imports the class StringParser in the seedu.tojava.util package
  • import seedu.tojava.frontend.*: imports all the classes in the seedu.tojava.frontend package
package seedu.tojava;

import seedu.tojava.util.StringParser;
import seedu.tojava.frontend.*;

public class Main {

    public static void main(String[] args) {

        // Using the fully qualified name to access the Processor class
        String status = seedu.tojava.logic.Processor.getStatus();

        // Using the StringParser previously imported
        StringParser sp = new StringParser();

        // Using classes from the tojava.frontend package
        Ui ui = new Ui();
        Message m = new Message();

    }
}

Note how the class can still use the Processor without importing it first, by using its fully qualified name seedu.tojava.logic.Processor

Importing a package does not import its sub-packages, as packages do not behave as hierarchies despite appearances.

import seedu.tojava.frontend.* does not import the classes in the sub-package seedu.tojava.frontend.widget.

If you do not use a package statement, your type doesn't have a package -- a practice not recommended (except for small code examples) as it is not possible for a type in a package to import a type that is not in a package.

Optionally, a static import can be used to import static members of a type so that the imported members can be used without specifying the type name.

The class below uses static imports to import the constant PREFIX and the method format() from the seedu.tojava.util.Formatter class.

import static seedu.tojava.util.Formatter.PREFIX;
import static seedu.tojava.util.Formatter.format;

public class Main {

    public static void main(String[] args) {

        String formatted = format("Hello");
        boolean isFormatted = formatted.startsWith(PREFIX);
        System.out.println(formatted);
    }
}

Formatter class


Note how the class can use PREFIX and format() (instead of Formatter.PREFIX and Formatter.format()).

When using the commandline to compile/run Java, you should take the package into account.

If the seedu.tojava.Main class is defined in the file Main.java,

  • when compiling from the <source folder>, the command is:
    javac seedu/tojava/Main.java
  • when running it from the <compiler output folder>, the command is:
    java seedu.tojava.Main

Resources:


Guidance for the item(s) below:

As the size of your Java codebase grows, every class being able to access every member of every other class can be problematic. Hence, there should be a way to control the access to our Java classes and their members. The solution is given in the topic below.

[W8.5] Java: Access Modifiers

W8.5a

C++ to Java → Miscellaneous Topics → Access modifiers

Can explain access modifiers

Access level modifiers determine whether other classes can use a particular field or invoke a particular method.

There are two levels of access control:

  1. At the class level:

    • public: the class is visible to all classes everywhere
    • no modifier (the default, also known as package-private): it is visible only within its own package

  2. At the member level:

    • public or no modifier (package-private): same meaning as when used with top-level classes
    • private: the member can only be accessed in its own class
    • protected: the member can only be accessed within its own package (as with package-private) and, in addition, by a subclass of its class in another package

The following table shows the access to members permitted by each modifier.

Modifier
public
protected
no modifier
private

Access levels affect you in two ways:

  1. When you use classes that come from another source, such as the classes in the Java platform, access levels determine which members of those classes your own classes can use.
  2. When you write a class, you need to decide what access level every member variable and every method in your class should have.


Guidance for the item(s) below:

As you know, adding comments to the code is a good practice. Let's learn about a specific type of comments that you can use in Java code that can do even more than just explain the code.

[W8.6] Java: JavaDocs

W8.6a

Implementation → Documentation → Tools → JavaDoc → What

Video

Can explain JavaDoc

JavaDoc is a tool for generating API documentation in HTML format from comments in the source code. In addition, modern IDEs use JavaDoc comments to generate explanatory tooltips.

An example method header comment in JavaDoc format:

/**
 * Returns an Image object that can then be painted on the screen.
 * The url argument must specify an absolute {@link URL}. The name
 * argument is a specifier that is relative to the url argument.
 * <p>
 * This method always returns immediately, whether or not the
 * image exists. When this applet attempts to draw the image on
 * the screen, the data will be loaded. The graphics primitives
 * that draw the image will incrementally paint on the screen.
 *
 * @param url An absolute URL giving the base location of the image.
 * @param name The location of the image, relative to the url argument.
 * @return The Image at the specified URL.
 * @see Image
 */
public Image getImage(URL url, String name) {
    try {
        return getImage(new URL(url, name));
    } catch (MalformedURLException e) {
        return null;
    }
}

Generated HTML documentation:

Tooltip generated by IntelliJ IDE:


W8.6b

Implementation → Documentation → Tools → JavaDoc → How

Can write JavaDoc comments

In the absence of more extensive guidelines (e.g., given in a coding standard adopted by your project), you can follow the two examples below in your code.

A minimal JavaDoc comment example for methods:

/**
 * Returns lateral location of the specified position.
 * If the position is unset, NaN is returned.
 *
 * @param x X coordinate of position.
 * @param y Y coordinate of position.
 * @param zone Zone of position.
 * @return Lateral location.
 * @throws IllegalArgumentException If zone is <= 0.
 */
public double computeLocation(double x, double y, int zone)
    throws IllegalArgumentException {
    // ...
}

A minimal JavaDoc comment example for classes:

package ...

import ...

/**
 * Represents a location in a 2D space. A <code>Point</code> object corresponds to
 * a coordinate represented by two integers e.g., <code>3,6</code>
 */
public class Point {
    // ...
}

Resources:


Guidance for the item(s) below:

Let's learn about a few more Git techniques, starting with branching. Although these techniques are not really needed for the iP, we require you to use them in the iP so that you have more time to practice them before they are really needed in the tP.

[W8.7] RCS: Branching

W8.7a

Project Management → Revision Control → Branching

Video

Can explain branching

Branching is the process of evolving multiple versions of the software in parallel. For example, one team member can create a new branch and add an experimental feature to it while the rest of the team keeps working on another branch. Branches can be given names e.g. master, release, dev.

A branch can be merged into another branch. Merging sometimes results in a new commit (called the merge commit) being created, to represent the cumulative changes done in the receiving branch as a result of the merge.

Branching and merging

Merge conflicts happen when you try to merge two branches that had changed the same part of the code and the RCS cannot decide which changes to keep. In those cases, you have to ‘resolve’ the conflicts manually.


W8.7b

Tools → Git and GitHub → branch: Doing multiple parallel changes

Video

Can use Git branching

Git supports branching, which allows you to do multiple parallel changes to the content of a repository.

First, let us learn how the repo looks like as you perform branching operations.

A Git branch is simply a named label pointing to a commit which moves forward automatically as you add more commits to that branch. The HEAD label indicates which branch you are on.

Git creates a branch named master (or main) by default. When you add a commit, it goes into the branch you are currently on, and the branch label (together with the HEAD label) moves to the new commit.

Given below is an illustration of how branch labels move as branches evolve. Refer to the text below it for explanations of each stage.

  1. There is only one branch (i.e., master) and there is only one commit on it. The HEAD label is pointing to the master branch (as we are currently on that branch).

    To learn a bit more about how labels such as master and HEAD work, you can refer to this article.

  2. A new commit has been added. The master and the HEAD labels have moved to the new commit.

  3. A new branch fix1 has been added. The repo has switched to the new branch too (hence, the HEAD label is attached to the fix1 branch).

  4. A new commit (c) has been added. The current branch label fix1 moves to the new commit, together with the HEAD label.

  5. The repo has switched back to the master branch. Hence, the HEAD has moved back to master branch's .
    At this point, the repo's working directory reflects the code at commit b (not c).

  1. A new commit (d) has been added. The master and the HEAD labels have moved to that commit.
  2. The repo has switched back to the fix1 branch and added a new commit (e) to it.
  3. The repo has switched to the master branch and the fix1 branch has been merged into the master branch, creating a merge commit f. The repo is currently on the master branch.

Now that you have some idea how the repo will look like when branches are being used, let's follow the steps below to learn how to perform branching operations using Git. You can use any repo you have on your computer (e.g. a clone of the samplerepo-things) for this.

Note that how the revision graph appears (colors, positioning, orientation etc.) in your Git GUI varies based on the GUI you use, and might not match the exact diagrams given above.

0. Observe that you are normally in the branch called master.


$ git status

on branch master

1. Start a branch named feature1 and switch to the new branch.

Click on the Branch button on the main menu. In the next dialog, enter the branch name and click Create Branch.

Note how the feature1 is indicated as the current branch (reason: Sourcetree automatically switches to the new branch when you create a new branch).


You can use the branch command to create a new branch and the checkout command to switch to a specific branch.

$ git branch feature1
$ git checkout feature1

One-step shortcut to create a branch and switch to it at the same time:

$ git checkout –b feature1

The new switch command

Git recently introduced a switch command that you can use instead of the checkout command given above.

To create a new branch and switch to it:

$ git branch feature1
$ git switch feature1

One-step shortcut:

$ git switch –c feature1

2. Create some commits in the new branch. Just commit as per normal. Commits you add while on a certain branch will become part of that branch.
Note how the master label and the HEAD label moves to the new commit (The HEAD label of the local repo is represented as in Sourcetree, as illustrated in the screenshot below).

3. Switch to the master branch. Note how the changes you did in the feature1 branch are no longer in the working directory.

Double-click the master branch.

Revisiting master vs origin/master

In the screenshot above, you see a master label and a origin/master label for the same commit. The former identifies the of the local master branch while the latter identifies the tip of the master branch at the remote repo named origin. The fact that both labels point to the same commit means the local master branch and its remote counterpart are with each other. Similarly, origin/HEAD label appearing against the same commit indicates that of the remote repo is pointing to this commit as well.


$ git checkout master

4. Add a commit to the master branch. Let’s imagine it’s a bug fix.
To keep things simple for the time being, this commit should not involve the same content that you changed in the feature1 branch. To be on the safe side, you can change an entirely different file in this commit.

5. Switch back to the feature1 branch (similar to step 3).

6. Merge the master branch to the feature1 branch, giving an end-result like the following. Also note how Git has created a merge commit.

Right-click on the master branch and choose merge master into the current branch. Click OK in the next dialog.


$ git merge master

The objective of that merge was to sync the feature1 branch with the master branch. Observe how the changes you did in the master branch (i.e. the imaginary bug fix) is now available even when you are in the feature1 branch.

To undo a merge,

  1. Ensure you are in the .
  2. Do a hard reset (similar to how you delete a commit) of that branch to the commit that would be the tip of that branch had you not done the offending merge.

In the example below, you merged master to feature1.

If you want to undo that merge,

  1. Ensure you are in the feature1 branch (because that's the branch that received the merge).
  2. Reset the feature1 branch to the commit highlighted (in yellow) in the screenshot above (because that was the tip of the feature1 branch before you merged the master branch to it.

Instead of merging master to feature1, an alternative is to rebase the feature1 branch. However, rebasing is an advanced feature that requires modifying past commits. If you modify past commits that have been pushed to a remote repository, you'll have to force-push the modified commit to the remote repo in order to update the commits in it.

7. Add another commit to the feature1 branch.

8. Switch to the master branch and add one more commit.

9. Merge feature1 to the master branch, giving and end-result like this:

Right-click on the feature1 branch and choose Merge....


$ git merge feature1

10. Create a new branch called add-countries, switch to it, and add some commits to it (similar to steps 1-2 above). You should have something like this now:

Avoid this rookie mistake!

Always remember to switch back to the master branch before creating a new branch. If not, your new branch will be created on top of the current branch.

11. Go back to the master branch and merge the add-countries branch onto the master branch (similar to steps 8-9 above). While you might expect to see something like the following,

... you are likely to see something like this instead:

That is because Git does a fast forward merge if possible. Seeing that the master branch has not changed since you started the add-countries branch, Git has decided it is simpler to just put the commits of the add-countries branch in front of the master branch, without going into the trouble of creating an extra merge commit.

It is possible to force Git to create a merge commit even if fast forwarding is possible.

Windows: Tick the box shown below when you merge a branch:

Mac:

  1. Go to Sourcetree Settings.
  2. Navigate to the Git section.
  3. Tick the box Do not fast-forward when merging, always create commit.

Use the --no-ff switch (short for no fast forward):

$ git merge --no-ff add-countries


W8.7c

Tools → Git and GitHub → Dealing with merge conflicts

Video

Can use Git to resolve merge conflicts

Merge conflicts happen when you try to combine two incompatible versions (e.g., merging a branch to another but each branch changed the same part of the code in a different way).

Here are the steps to simulate a merge conflict and use it to learn how to resolve merge conflicts.

0. Create an empty repo or clone an existing repo, to be used for this activity.

1. Start a branch named fix1 in the repo. Create a commit that adds a line with some text to one of the files.

2. Switch back to master branch. Create a commit with a conflicting change i.e. it adds a line with some different text in the exact location the previous line was added.

3. Try to merge the fix1 branch onto the master branch. Git will pause mid-way during the merge and report a merge conflict. If you open the conflicted file, you will see something like this:

COLORS
------
blue
<<<<<< HEAD
black
=======
green
>>>>>> fix1
red
white

4. Observe how the conflicted part is marked between a line starting with <<<<<< and a line starting with >>>>>>, separated by another line starting with =======.

Highlighted below is the conflicting part that is coming from the master branch:

blue
<<<<<< HEAD
black
=======
green
>>>>>> fix1
red

This is the conflicting part that is coming from the fix1 branch:

blue
<<<<<< HEAD
black
=======
green
>>>>>> fix1
red

5. Resolve the conflict by editing the file. Let us assume you want to keep both lines in the merged version. You can modify the file to be like this:

COLORS
------
blue
black
green
red
white

6. Stage the changes, and commit. You have now successfully resolved the merge conflict.


W8.7d

Tools → Git and GitHub → Working with remote branches

Can work with remote branches

Git branches in a local repo can be linked to a branch in a remote repo so the local branch can 'track' the corresponding remote branch, and revision history contained in the local and the remote branch pair can be synchronized as desired.

[A] Pushing a new branch to a remote repo

Let's see how you can push a branch that you created in your local repo to the remote repo. Note that this branch does not exist in the remote repo yet.

Given below is how to push a branch named add-intro to your own fork named samplerepo-pr-practice.

We assume that your local repo already has the remote added to it with the name origin. If that is not the case, you should first configure your local repo to be able to communicate with the target remote repo.

  1. Click on Push button, which opens up the Push dialog.
  2. Choose the remote that you wish to push the branch (assuming you've added that repo to your Sourcetree already).
  3. Select the branch(es) you want to push -- in this case, add-intro.
    Ensure the Track? checkbox is ticked for the selected branch(es).
  4. Click Push.


$ git push -u origin add-intro

The -u (or --set-upstream) flag tells Git that you wish the local branch to 'track' the remote branch that will be created as a result of this push.

See git-scm.com/docs/git-push for details of the push command.


[B] Pulling a remote branch for the first time

Here, let's see how to fetch a new branch (i.e., it does not exist in your local repo yet) from a remote repo.

1. Check the list of remote branches by expanding the REMOTES menu on the left edge of Sourcetree. If the branch you expected to find is missing, you can click the Fetch button (in the top toolbar) to refresh the information shown under remotes.

2. Double-click the branch name (e.g., tweak-requirements branch in the myfork remote), which should open the checkout dialog shown below.

3. Go with the default settings (shown above) should be fine. Once you click OK, the branch will appear in your local repo. Furthermore, that repo will switch to that branch, and the local branch will the remote branch as well.


1. Fetch details from the remote. e.g., if the remote is named myfork

$ git fetch myfork

2. List the branches to see the name of the branch you want to pull.

$ git branch -a

master
remotes/myfork/master
remotes/myfork/branch1

-a flag tells Git to list both local and remote branches.

3. Create a matching local branch and switch to it.

$ git switch -c branch1 myfork/branch1

Switched to a new branch 'branch1'
branch 'branch1' set up to track 'myfork/branch1'.

-c flag tells Git to create a new local branch.


[C] Syncing branches

In this section we assume that you have a local branch that is already tracking a remote branch (e.g., as a result of doing [A] or [B] above).

[C1] To push new changes in the local branch to the corresponding remote branch:

Similar to how you pushed a new branch (in [A]):


Similar to [A] above, but omit the -u flag. e.g.,

$ git push origin add-intro

If you push but the remote branch has new commits that you don't have locally, Git will abort the push and will ask you to pull first.

[C2] To pull new changes from a remote branch to the corresponding local branch:

1. Switch to the branch you want to update by double-clicking the branch name. e.g.,

2. Pull the updated in the remote branch to the local branch by right-clicking on the branch name (in the same place as above), and choosing Pull <remote>/<branch> (tracked) e.g., Pull myfork/add-intro (tracked).


1. Switch to the branch you want to update using git checkout <branch> e.g.,

$ git checkout branch1

2. Pull the updated in the remote branch to the local branch, using git pull <remote> <branch> e.g.,

$ git pull origin branch1

If you pull but your local branch has new commits the remote branch doesn't have, Git will automatically perform a merge between the local branch and the remote branch.



Guidance for the item(s) below:

Given below are some very basic tools and techniques that are often used in planning, scheduling, and tracking projects.

[W8.8] Project Mgt: Scheduling and Tracking

Video

W8.8a

Project Management → Project Planning → Milestones

Can explain milestones

A milestone is the end of a stage which indicates significant progress. You should take into account dependencies and priorities when deciding on the features to be delivered at a certain milestone.

Each intermediate product release is a milestone.

In some projects, it is not practical to have a very detailed plan for the whole project due to the uncertainty and unavailability of required information. In such cases, you can use a high-level plan for the whole project and a detailed plan for the next few milestones.

Milestones for the Minesweeper project, iteration 1

Day Milestones
Day 1 Architecture skeleton completed
Day 3 ‘new game’ feature implemented
Day 4 ‘new game’ feature tested

W8.8b

Project Management → Project Planning → Buffers

Can explain buffers

A buffer is time set aside to absorb any unforeseen delays. It is very important to include buffers in a software project schedule because effort/time estimations for software development are notoriously hard. However, do not inflate task estimates to create hidden buffers; have explicit buffers instead. Reason: With explicit buffers, it is easier to detect incorrect effort estimates which can serve as feedback to improve future effort estimates.


W8.8c

Project Management → Project Planning → Issue trackers

Can explain issue trackers

Keeping track of project tasks (who is doing what, which tasks are ongoing, which tasks are done etc.) is an essential part of project management. In small projects, it may be possible to keep track of tasks using simple tools such as online spreadsheets or general-purpose/light-weight task tracking tools such as Trello. Bigger projects need more sophisticated task tracking tools.

Issue trackers (sometimes called bug trackers) are commonly used to track task assignment and progress. Most online project management software such as GitHub, SourceForge, and BitBucket come with an integrated issue tracker.

A screenshot from the Jira Issue tracker software (Jira is part of the BitBucket project management tool suite):


W8.8d

Project Management → Project Planning → Work breakdown structure

Can explain work breakdown structures

A Work Breakdown Structure (WBS) depicts information about tasks and their details in terms of subtasks. When managing projects, it is useful to divide the total work into smaller, well-defined units. Relatively complex tasks can be further split into subtasks. In complex projects, a WBS can also include prerequisite tasks and effort estimates for each task.

The high level tasks for a single iteration of a small project could look like the following:

Task ID Task Estimated Effort Prerequisite Task
A Analysis 1 man day -
B Design 2 man day A
C Implementation 4.5 man day B
D Testing 1 man day C
E Planning for next version 1 man day D

The effort is traditionally measured in man hour/day/month i.e. work that can be done by one person in one hour/day/month. The Task ID is a label for easy reference to a task. Simple labeling is suitable for a small project, while a more informative labeling system can be adopted for bigger projects.

An example WBS for a game development project.

Task ID Task Estimated Effort Prerequisite Task
A High level design 1 man day -
B Detail design
  1. User Interface
  2. Game Logic
  3. Persistency Support
2 man day
  • 0.5 man day
  • 1 man day
  • 0.5 man day
A
C Implementation
  1. User Interface
  2. Game Logic
  3. Persistency Support
4.5 man day
  • 1.5 man day
  • 2 man day
  • 1 man day
  • B.1
  • B.2
  • B.3
D System Testing 1 man day C
E Planning for next version 1 man day D

All tasks should be well-defined. In particular, it should be clear as to when the task will be considered done.

Some examples of ill-defined tasks and their better-defined counterparts:

Bad Better
more coding implement component X
do research on UI testing find a suitable tool for testing the UI

Exercises:

Which one is not a well-defined task?



W8.8e : OPTIONAL

Project Management → Project Planning → Gantt charts


W8.8f : OPTIONAL

Project Management → Project Planning → PERT charts



Last week, you learned intermediate-level class diagram notation. But the quiz only focused on interpreting such diagrams. This week, we cover the aspect of drawing intermediate-level class diagrams to match code. Here are what you can do:
1. Do Part 1 of this week's quiz (which covers the same area).
2. Watch the worked examples in the following videos to learn the process of drawing intermediate-level class diagrams to match code.

Video Drawing class/object diagrams (intermediate) - Action, Task, History

Video Drawing class/object diagrams (intermediate) - Person, Inbox, Message

Video Drawing class/object diagrams (intermediate) - Person, Project, Task