Detailed Table of Contents
Abstraction
Coupling
[W7.3b] Design → Design Fundamentals → Coupling → What
[W7.3c] Design → Design Fundamentals → Coupling → How
[W7.3d] Design → Design Fundamentals → Coupling → Types of coupling : OPTIONAL
Cohesion
[W7.6a] Project Management → Project Planning → Milestones
[W7.6b] Project Management → Project Planning → Buffers
[W7.6c] Project Management → Project Planning → Issue trackers
[W7.6d] Project Management → Project Planning → Work breakdown structure
[W7.6e] Project Management → Project Planning → Gantt charts
[W7.6f] Project Management → Project Planning → PERT charts : OPTIONAL
[W7.6g] Project Management → Teamwork → Team structures
[W7.7a] Project Management → Revision Control → Forking flow
[W7.7b] Tools → Git and GitHub → Forking workflow
[W7.7c] Project Management → Revision Control → DRCS vs CRCS
[W7.7d] Project Management → Revision Control → Feature branch flow : OPTIONAL
[W7.7e] Project Management → Revision Control → Centralized flow : OPTIONAL
Guidance for the item(s) below:
Previously, you learned a number of techniques for specifying requirements. There's one more left, which we'll cover this week.
Can explain use cases
Use case: A description of a set of sequences of actions, including variants, that a system performs to yield an observable result of value to an actor.[ 📖 : uml-user-guideThe Unified Modeling Language User Guide, 2e, G Booch, J Rumbaugh, and I Jacobson ]
Actor: An actor (in a use case) is a role played by a user. An actor can be a human or another system. Actors are not part of the system; they reside outside the system.
A use case describes an interaction between the user and the system for a specific functionality of the system.
Example 1: 'transfer money' use case for an online banking system
System: Online Banking System (OBS) Use case: UC23 - Transfer Money Actor: User MSS: 1. User chooses to transfer money. 2. OBS requests for details of the transfer. 3. User enters the requested details. 4. OBS requests for confirmation. 5. User confirms. 6. OBS transfers the money and displays the new account balance. Use case ends.
Extensions: 3a. OBS detects an error in the entered data. 3a1. OBS requests for the correct data. 3a2. User enters new data. Steps 3a1-3a2 are repeated until the data entered are correct. Use case resumes from step 4. 3b. User requests to effect the transfer in a future date. 3b1. OBS requests for confirmation. 3b2. User confirms future transfer. Use case ends. *a. At any time, User chooses to cancel the transfer. *a1. OBS requests to confirm the cancellation. *a2. User confirms the cancellation. Use case ends.
Example 2: 'upload file' use case of an LMS
UML includes a diagram type called use case diagrams that can illustrate use cases of a system visually, providing a visual ‘table of contents’ of the use cases of a system.
In the example on the right, note how use cases are shown as ovals and user roles relevant to each use case are shown as stick figures connected to the corresponding ovals.
Unified Modeling Language (UML) is a graphical notation to describe various aspects of a software system. UML is the brainchild of three software modeling specialists James Rumbaugh, Grady Booch and Ivar Jacobson (also known as the Three Amigos). Each of them had developed their own notation for modeling software systems before joining forces to create a unified modeling language (hence, the term ‘Unified’ in UML). UML is currently the de facto modeling notation used in the software industry.
Use cases capture the functional requirements of a system.
Can use use cases to list functional requirements of a simple system
A use case is an interaction between a system and its actors.
Actors in Use Cases
Actor: An actor (in a use case) is a role played by a user. An actor can be a human or another system. Actors are not part of the system; they reside outside the system.
Some example actors for a Learning Management System:
A use case can involve multiple actors.
An actor can be involved in many use cases.
A single person/system can play many roles.
Many persons/systems can play a single role.
Use cases can be specified at various levels of detail.
Consider the three use cases given below. Clearly, (a) is at a higher level than (b) and (b) is at a higher level than (c).
While modeling user-system interactions,
Exercises
Use case diagram for a ticket vending machine
Consider a simple movie ticket vending machine application. Every week, the theatre staff will enter the weekly schedule as well as ticket price for each show. A customer sees the schedule and the ticket price displayed at the machine. There is a slot to insert money, a keypad to enter a code for a movie, a code for the show time, and the number of tickets. A display shows the customer's balance inside the machine. A customer may choose to cancel a transaction before pressing the “buy” button. Printed tickets can be collected from a slot at the bottom of the machine. The machine also displays messages such as "Please enter more money”, “Request fewer tickets" or "SOLD OUT!”. Finally, a "Return Change" button allows the customer to get back his unspent money.
Draw a use case diagram for the above requirements.
Note that most of the details in the description are better given as part of the use case description rather than as low-level use cases in the diagram.
Use case diagram for QA system
A software house wishes to automate its Quality Assurance division.
The system is to be used by Testers, Programmers and System Administrators. Only an administrator can create new users and assign tasks to programmers. Any tester can create a bug report, as well as set the status of a bug report as ‘closed’. Only a programmer can set the state of a bug report to ‘fixed’, but a programmer cannot set the status of a bug report to ‘closed’. Each tester is assigned just one task at a time. A task involves testing of a particular component for a particular customer. Tester must document the bugs they find. Each bug is given a unique identifier. Other information recorded about the bug is component id, severity, date and time reported, programmer who is assigned to fix it, date fixed, date retested and date closed. The system keeps track of which bugs are assigned to which programmer at any given time. It should be able to generate reports on the number of bugs found, fixed and closed e.g. number of bugs per component and per customer; number of bugs found by a particular tester; number of bugs awaiting to be fixed; number of bugs awaiting to be retested; number of bugs awaiting to be assigned to programmers etc.
Develop a use case diagram to capture their requirements given below.
Explanation: The given description contains information not relevant to use case modeling. Furthermore, the description is not enough to complete the use case diagram. All these are realities of real projects. However, the process of trying to create this use case diagram prompts us to investigate issues such as:
Requirements → Specifying Requirements → Use Cases → Introduction Requirements → Specifying Requirements → Use Cases → Identifying
Can specify details of a use case in a structured format
Writing use case steps
The main body of the use case is a sequence of steps that describes the interaction between the system and the actors. Each step is given as a simple statement describing who does what.
An example of the main body of a use case.
A use case describes only the externally visible behavior, not internal details, of a system i.e. should minimize details that are not part of the interaction between the user and the system.
This example use case step refers to behaviors not externally visible.
A step gives the intention of the actor (not the mechanics). That means UI details are usually omitted. The idea is to leave as much flexibility to the UI designer as possible. That is, the use case specification should be as general as possible (less specific) about the UI.
The first example below is not a good use case step because it contains UI-specific details. The second one is better because it omits UI-specific details.
Bad : User right-clicks the text box and chooses ‘clear’
Good : User clears the input
A use case description can show loops too.
An example of how you can show a loop:
Software System: SquareGame
Use case: Each use case can be given a unique identification for easier cross reference. UC02 - Play a Game
Actors: Player (multiple players)
Use case ends.
The Main Success Scenario (MSS) describes the most straightforward interaction for a given use case, which assumes that nothing goes wrong. This is also called the Basic Course of Action or the Main Flow of Events of a use case.
Note how the MSS in the example below assumes that all entered details are correct and ignores problems such as timeouts, network outages etc. For example, the MSS does not tell us what happens if the user enters incorrect data.
System: Online Banking System (OBS)
Use case: UC23 - Transfer Money
Actor: User
MSS:
Use case ends.
Extensions are "add-on"s to the MSS that describe exceptional/alternative flow of events. They describe variations of the scenario that can happen if certain things are not as expected by the MSS. Extensions appear below the MSS.
This example adds some extensions to the use case in the previous example.
System: Online Banking System (OBS) Use case: UC23 - Transfer Money Actor: User MSS: 1. User chooses to transfer money. 2. OBS requests for details of the transfer. 3. User enters the requested details. 4. OBS requests for confirmation. 5. User confirms. 6. OBS transfers the money and displays the new account balance. Use case ends.
Extensions: 3a. OBS detects an error in the entered data. 3a1. OBS requests for the correct data. 3a2. User enters new data. Steps 3a1-3a2 are repeated until the data entered are correct. Use case resumes from step 4. 3b. User requests to effect the transfer in a future date. 3b1. OBS requests for confirmation. 3b2. User confirms future transfer. Use case ends. *a. At any time, User chooses to cancel the transfer. *a1. OBS requests to confirm the cancellation. *a2. User confirms the cancellation. Use case ends. *b. At any time, 120 seconds lapse without any input from the User. *b1. OBS cancels the transfer. *b2. OBS informs the User of the cancellation. Use case ends.
Note that the numbering style is not a universal rule but a widely used convention. Based on that convention,
3a.
and 3b.
can happen just after step 3
of the MSS.*a.
can happen at any step (hence, the *
).When separating extensions from the MSS, keep in mind that the MSS should be self-contained. That is, the MSS should give us a complete usage scenario.
Also note that it is not useful to mention events such as power failures or system crashes as extensions because the system cannot function beyond such catastrophic failures.
In use case diagrams you can use the <<extend>>
arrows to show extensions. Note the direction of the arrow is from the extension to the use case it extends and the arrow uses a dashed line.
A use case can include another use case. Underlined text is commonly used to show an inclusion of a use case.
This use case includes two other use cases, one in step 1 and one in step 2.
Inclusions are useful,
You use a dotted arrow and an <<include>>
annotation to show use case inclusions in a use case diagram. Note how the arrow direction is different from the <<extend>>
arrows.
Preconditions specify the specific state you expect the system to be in before the use case starts.
Software System: Online Banking System
Use case: UC23 - Transfer Money
Actor: User
Preconditions: User is logged in
MSS:
Guarantees specify what the use case promises to give us at the end of its operation.
Software System: Online Banking System
Use case: UC23 - Transfer Money
Actor: User
Preconditions: User is logged in.
Guarantees:
MSS:
Exercises
EZ-Link top-up use case
Complete the following use case (MSS, extensions, etc.). Note that you should not blindly follow how the existing A type of a cash card topup machineEZ-Link machine operates because it will prevent you from designing a better system. You should consider all possible extensions without complicating the use case too much.
Notes:
Note: UC02 can be written along similar lines.
LearnSys – reply to post use case
Complete the following use case (MSS, extensions, etc.).
Parts of a use case description
Which of these cannot appear as part of a use case description?
(f)
Explanation: Performance requirements are non-functional requirements. They are not captured in use cases.
What’s wrong with this use case?
Identify problems with this use case description.
None.
Explanation: Catastrophic failures such as ‘system crash’ need not be included in a use case. A use case is not supposed to contain UI details. Post conditions are optional. It is not a problem to have multiple exit points for a use case.
Can optimize the use of use cases
You can use actor generalization in use case diagrams using a symbol similar to that of UML notation for inheritance.
In this example, actor Blogger
can do all the use cases the actor Guest
can do, as a result of the actor generalization relationship given in the diagram.
Do not over-complicate use case diagrams by trying to include everything possible. A use case diagram is a brief summary of the use cases that is used as a starting point. Details of the use cases can be given in the use case descriptions.
Some include ‘System’ as an actor to indicate that something is done by the system itself without being initiated by a user or an external system.
The diagram below can be used to indicate that the system generates daily reports at midnight.
However, others argue that only use cases providing value to an external user/system should be shown in the use case diagram. For example, they argue that view daily report
should be the use case and generate daily report
is not to be shown in the use case diagram because it is simply something the system has to do to support the view daily report
use case.
You are recommended to follow the latter view (i.e. not to use System as a user). Limit use cases for modeling behaviors that involve an external actor.
UML is not very specific about the text contents of a use case. Hence, there are many styles for writing use cases. For example, the steps can be written as a continuous paragraph.
Use cases should be easy to read. Note that there is no strict rule about writing all details of all steps or a need to use all the elements of a use case.
There are some advantages of documenting system requirements as use cases:
One of the main disadvantages of use cases is that they are not good for capturing requirements that do not involve a user interacting with the system. Hence, they should not be used as the sole means to specify requirements.
Exercises
Advantages of use cases
What are the advantages of using use cases (the textual form) for requirements modelling?
(a) (b) (c) (d)
Statements about use cases
Which of these are correct?
(a)(b)(d)
Explanation: It is not correct to say one format is better than the other. It depends on the context.
Follow up notes for the item(s) above:
Now that you know all the different ways of specifying requirements, here is an example that shows how all techniques of specifying requirements can work together:
Guidance for the item(s) below:
In the tP, you start with a code base that already has a certain design. What if there is no such design for you to starth with? The next few topics look at how one can come up with such a design yourself.
Can explain what is software design
Design is the creative process of transforming the problem into a solution; the solution is also called design. -- 📖 Software Engineering Theory and Practice, Shari Lawrence; Atlee, Joanne M. Pfleeger
Software design has two main aspects:
Follow up notes for the item(s) above:
Now that you know there are two kinds of 'design', also note that this module focuses more on the internal design rather than the external design.
Design → Design Approaches → Multi-Level Design → What
Can explain top-down and bottom-up design
Multi-level design can be done in a top-down manner, bottom-up manner, or as a mix.
Exercises
Which is better?
Top-down design is better than bottom-up design.
False
Explanation: Not necessarily. It depends on the situation. Bottom-up design may be preferable when there are a lot of existing components we want to reuse.
Can explain agile design
Agile design can be contrasted with full upfront design in the following way:
Agile designs are emergent, they’re not defined up front. Your overall system design will emerge over time, evolving to fulfill new requirements and take advantage of new technologies as appropriate. Although you will often do some initial architectural modeling at the very beginning of a project, this will be just enough to get your team going. This approach does not produce a fully documented set of models in place before you may begin coding. -- adapted from agilemodeling.com
Exercises
Statement about agile design
The agile design camp expects the design to change over the product’s lifetime.
True
Explanation: Yes, that is why they do not believe in spending too much time creating a detailed and full design at the very beginning. However, the architecture is expected to remain relatively stable even in the agile design approach.
Guidance for the item(s) below:
As you do projects, you'll have to make design decisions e.g., decide between multiple design alternatives. Let us learn three fundamental design concepts that you can use in those decisions.
It is extremely important for you to know these three because they are like the DNA of every higher-level design concept.
Can explain abstraction
Abstraction is a technique for dealing with complexity. It works by establishing a level of complexity we are interested in, and suppressing the more complex details below that level.
The guiding principle of abstraction is that only details that are relevant to the current perspective or the task at hand need to be considered. As most programs are written to solve complex problems involving large amounts of intricate details, it is impossible to deal with all these details at the same time. That is where abstraction can help.
Data abstraction: abstracting away the lower level data items and thinking in terms of bigger entities
Within a certain software component, you might deal with a user data type, while ignoring the details contained in the user data item such as name, and date of birth. These details have been ‘abstracted away’ as they do not affect the task of that software component.
Control abstraction: abstracting away details of the actual control flow to focus on tasks at a higher level
print(“Hello”)
is an abstraction of the actual output mechanism within the computer.
Abstraction can be applied repeatedly to obtain progressively higher levels of abstraction.
An example of different levels of data abstraction: a File
is a data item that is at a higher level than an array and an array is at a higher level than a bit.
An example of different levels of control abstraction: execute(Game)
is at a higher level than print(Char)
which is at a higher level than an Assembly language instruction MOV
.
Abstraction is a general concept that is not limited to just data or control abstractions.
Some more general examples of abstraction:
Can explain coupling
Coupling is a measure of the degree of dependence between components, classes, methods, etc. Low coupling indicates that a component is less dependent on other components. High coupling (aka tight coupling or strong coupling) is discouraged due to the following disadvantages:
In the example below, design A
appears to have more coupling between the components than design B
.
Exercises
Coupling levels of alternative designs
Discuss the coupling levels of alternative designs x and y.
Overall coupling levels in x and y seem to be similar (neither has more dependencies than the other). (Note that the number of dependency links is not a definitive measure of the level of coupling. Some links may be stronger than the others.). However, in x, A
is highly-coupled to the rest of the system while B
, C
, D
, and E
are standalone (do not depend on anything else). In y, no component is as highly-coupled as A
of x. However, only D
and E
are standalone.
Regressions and coupling
Explain the link (if any) between regressions and coupling.
When the system is highly-coupled, the risk of regressions is higher too e.g. when component A
is modified, all components ‘coupled’ to component A
risk ‘unintended behavioral changes’.
Coupling and testability
Discuss the relationship between coupling and a measure of how easily a given component can be testedtestability.
Coupling decreases testability because if the Software Under TestSUT is coupled to many other components, it becomes difficult to test the SUT in isolation of its dependencies.
Statements about coupling
Choose the correct statements.
(a)(b)(c)(d)(e)
Explanation: High coupling means either more components are required to be integrated at once in a big-bang fashion (increasing the risk of things going wrong) or more drivers and stubs are required when integrating incrementally.
Design → Design Fundamentals → Coupling → What
Can reduce coupling
X is coupled to Y if a change to Y can potentially require a change in X.
If the Foo
class calls the method Bar#read()
, Foo
is coupled to Bar
because a change to Bar
can potentially (but not always) require a change in the Foo
class e.g. if the signature of Bar#read()
is changed, Foo
needs to change as well, but a change to the Bar#write()
method may not require a change in the Foo
class because Foo
does not call Bar#write()
.
code for the above example
class Foo {
...
new Bar().read();
...
}
class Bar {
void read() {
...
}
void write() {
...
}
}
Some examples of coupling: A
is coupled to B
if,
A
has access to the internal structure of B
(this results in a very high level of coupling)A
and B
depend on the same global variableA
calls B
A
receives an object of B
as a parameter or a return valueA
inherits from B
A
and B
are required to follow the same data format or communication protocolExercises
Which indicate coupling?
Which of these indicate coupling between components A and B?
(a)(b)(c)(d)(e)(f)
Explanation: Being written by the same developer does not imply coupling.
Design → Design Fundamentals → Coupling → What
Can identify types of coupling
Some examples of different coupling types:
Can explain cohesion
Cohesion is a measure of how strongly-related and focused the various responsibilities of a component are. A highly-cohesive component keeps related functionalities together while keeping out all other unrelated things.
Higher cohesion is better. Disadvantages of low cohesion (aka weak cohesion):
Design → Design Fundamentals → Cohesion →
What
Can increase cohesion
Cohesion can be present in many forms. Some examples:
Student
component handles everything related to students.GameArchive
component handles everything related to the storage and retrieval of game sessions.Suppose a Payroll application contains a class that deals with writing data to the database. If the class includes some code to show an error dialog to the user if the database is unreachable, that class is not cohesive because it seems to be interacting with the user as well as the database.
Exercises
Which class is more cohesive?
Compare the cohesion of the following two versions of the EmailMessage
class. Which one is more cohesive and why?
// version-1
class EmailMessage {
private String sendTo;
private String subject;
private String message;
public EmailMessage(String sendTo, String subject, String message) {
this.sendTo = sendTo;
this.subject = subject;
this.message = message;
}
public void sendMessage() {
// sends message using sendTo, subject and message
}
}
// version-2
class EmailMessage {
private String sendTo;
private String subject;
private String message;
private String username;
public EmailMessage(String sendTo, String subject, String message) {
this.sendTo = sendTo;
this.subject = subject;
this.message = message;
}
public void sendMessage() {
// sends message using sendTo, subject and message
}
public void login(String username, String password) {
this.username = username;
// code to login
}
}
Version 2 is less cohesive.
Explanation: Version 2 is handling functionality related to login, which is not directly related to the concept of ‘email message’ that the class is supposed to represent. On a related note, you can improve the cohesion of both versions by removing the sendMessage functionality. Although sending messages is related to emails, this class is supposed to represent an email message, not an email server.
Guidance for the item(s) below:
In case you are the type who want to become a 'power user' of IDEs (it's not a bad idea, given the IDE is like the primary tool of a software engineer), given below are some more things you can do with IDEs.
Guidance for the item(s) below:
As you start adding new code to the tP, let's also become aware of various approaches in integrating new code to a product.
Implementation → Integration → Introduction → What
Can explain how integration approaches vary based on timing and frequency
In terms of timing and frequency, there are two general approaches to integration: late and one-time, early and frequent.
Late and one-time: wait till all components are completed and integrate all finished components near the end of the project.
This approach is not recommended because integration often causes many component incompatibilities (due to previous miscommunications and misunderstandings) to surface which can lead to delivery delays i.e. Late integration → incompatibilities found → major rework required → cannot meet the delivery date.
Early and frequent: integrate early and evolve each part in parallel, in small steps, re-integrating frequently.
A it has all the high-level components needed for the first version in their minimal form, compiles, and runs but may not produce any useful output yetwalking skeleton can be written first. This can be done by one developer, possibly the one in charge of integration. After that, all developers can flesh out the skeleton in parallel, adding one feature at a time. After each feature is done, simply integrate the new code into the main system.
Here is an animation that compares the two approaches:
Can explain how integration approaches vary based on amount merged at a time
Big-bang integration: integrate all components at the same time.
Big-bang is not recommended because it will uncover too many problems at the same time which could make debugging and bug-fixing more complex than when problems are uncovered incrementally.
Incremental integration: integrate a few components at a time. This approach is better than big-bang integration because it surfaces integration problems in a more manageable way.
Here is an animation that compares the two approaches:
Exercises
Big-bang integration in school projects
Give two arguments in support and two arguments against the following statement.
Because there is no external client, it is OK to use big bang integration for a school project.
Arguments for:
Arguments against:
Implementation → Integration → Approaches → Big-Bang Vs Incremental
Can explain how integration approaches vary based on the order of integration
Based on the order in which components are integrated, incremental integration can be done in three ways.
Top-down integration: higher-level components are integrated before bringing in the lower-level components. One advantage of this approach is that higher-level problems can be discovered early. One disadvantage is that this requires the use of stubs in place of lower level components until the real lower-level components are integrated into the system. Otherwise, higher-level components cannot function as they depend on lower level ones.
Stub: A stub has the same interface as the component it replaces, but its implementation is so simple that it is unlikely to have any bugs. It mimics the responses of the component, but only for a limited set of predetermined inputs. That is, it does not know how to respond to any other inputs. Typically, these mimicked responses are hard-coded in the stub rather than computed or retrieved from elsewhere, e.g. from a database.
Bottom-up integration: the reverse of top-down integration. Note that when integrating lower level components, additional code written to provide inputs to a component via an APIdrivers may be needed to test the integrated components because the UI may not be integrated yet, just like how top-down integration needs stubs.
Sandwich integration: a mix of the top-down and bottom-up approaches. The idea is to do both top-down and bottom-up so as to 'meet' in the middle.
Here is an animation that compares the three approaches:
Exercises
Suggest an integration strategy
Suggest an integration strategy for the system represented by the following diagram. You need not follow a strict top-down, bottom-up, sandwich, or big bang approach. Dashed arrows represent dependencies between classes.
Also take into account the following facts in your test strategy:
HospitalUI
will be developed early, so as to get customer feedback early.HospitalFacade
shields the UI from the complexities of the application layer. It simply redirects the method calls received to the appropriate classes below.IO_Helper
is to be reused from an earlier project, with minor modifications.OutPatient
component has been outsourced, and its delivery is not expected until the 2nd half of the project.There can be many acceptable answers to this question. But any good strategy should consider at least some of the following:
HospitalUI
will be developed early, it’s OK to integrate it early, using stubs, rather than wait for the rest of the system to finish. (i.e. a top-down integration is suitable for HospitalUI
)HospitalFacade
is unlikely to have a lot of business logic, it may not be worth to write stubs to test it (i.e. a bottom-up integration is better for HospitalFacade
).IO_Helper
is to be reused from an earlier project, you can finish it early. This is especially suitable since there are many classes that use it. Therefore IO_Helper
can be integrated with the dependent classes in bottom-up fashion.OutPatient
class may be delayed, you may have to integrate PatientMgr
using a stub.TypeA
, TypeB
, and TypeC
seem to be tightly coupled. It may be a good idea to test them together.Given below is one possible integration test strategy. The relative positioning of items is used to indicate a rough timeline.
Integration order
Consider the architecture given below. Describe the order in which components will be integrated with one another if the following integration strategies were adopted.
a) top-down
b) bottom-up
c) sandwich
Note that dashed arrows show dependencies (e.g. A depends on B, C and D, and is therefore higher-level than B, C and D).
a) Diagram:
b) Diagram:
c) Diagram:
Guidance for the item(s) below:
Coordinating a team project is not easy. Given below are some very basic tools and techniques that are often used in planning, scheduling, and tracking projects.
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 |
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.
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):
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
|
2 man day
|
A |
C |
Implementation
|
4.5 man day
|
|
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?
Which one these project tasks is not well-defined?
(c)
Explanation: ‘More testing’ is not well-defined. How much is ‘more’? ‘Test the delete functionality’ is a better-defined task.
Can explain Gantt charts
A Gantt chart is a 2-D bar-chart, drawn as time vs tasks (represented by horizontal bars).
A sample Gantt chart:
In a Gantt chart, a solid bar represents the main task, which is generally composed of a number of subtasks, shown as grey bars. The diamond shape indicates an important deadline/deliverable/milestone.
Can explain PERT charts
A PERT (Program Evaluation Review Technique) chart uses a graphical technique to show the order/sequence of tasks. It is based on the simple idea of drawing a directed graph in which:
An example PERT chart for a simple software project
md
= man days
A PERT chart can help determine the following important information:
Final Testing
cannot begin until all coding of individual subsystems have been completed.High level design
is completed.Critical path is the path in which any delay can directly affect the project duration. It is important to ensure tasks on the critical path are completed on time.
Can explain common team structures
Given below are three commonly used team structures in software development. Irrespective of the team structure, it is a good practice to assign roles and responsibilities to different team members so that someone is clearly in charge of each aspect of the project. In comparison, the ‘everybody is responsible for everything’ approach can result in more chaos and hence slower progress.
Egoless team
In this structure, every team member is equal in terms of responsibility and accountability. When any decision is required, consensus must be reached. This team structure is also known as a democratic team structure. This team structure usually finds a good solution to a relatively hard problem as all team members contribute ideas.
However, the democratic nature of the team structure bears a higher risk of falling apart due to the absence of an authority figure to manage the team and resolve conflicts.
Chief programmer team
Frederick Brooks proposed that software engineers learn from the medical surgical team in an operating room. In such a team, there is always a chief surgeon, assisted by experts in other areas. Similarly, in a chief programmer team structure, there is a single authoritative figure, the chief programmer. Major decisions, e.g. system architecture, are made solely by him/her and obeyed by all other team members. The chief programmer directs and coordinates the effort of other team members. When necessary, the chief will be assisted by domain specialists e.g. business specialists, database experts, network technology experts, etc. This allows individual group members to concentrate solely on the areas in which they have sound knowledge and expertise.
The success of such a team structure relies heavily on the chief programmer. Not only must he/she be a superb technical hand, he/she also needs good managerial skills. Under a suitably qualified leader, such a team structure is known to produce successful work.
Strict hierarchy team
At the opposite extreme of an egoless team, a strict hierarchy team has a strictly defined organization among the team members, reminiscent of the military or a bureaucratic government. Each team member only works on his/her assigned tasks and reports to a single “boss”.
In a large, resource-intensive, complex project, this could be a good team structure to reduce communication overhead.
Exercises
Which team structure is the most suitable for a school project?
Which team structure is the most suitable for a school project?
(a)
Explanation: Given that students are all peers and beginners, the egoless team structure seems most suitable for a school project. However, since school projects are low-stakes, short-lived, and small, even the other two team structures can be used for them.
Guidance for the item(s) below:
Continuing on the same theme, given below are more practices used in managing projects, particularly related to the revision control aspect.
Can explain forking workflow
In the forking workflow, the 'official' version of the software is kept in a remote repo designated as the 'main repo'. All team members fork the main repo and create pull requests from their fork to the main repo.
To illustrate how the workflow goes, let’s assume Jean wants to fix a bug in the code. Here are the steps:
master
branch -- if Jean does that, she will not be able to have more than one PR open at any time because any changes to the master
branch will be reflected in all open PRs.Resources
Revision Control → Forking Workflow
Can follow Forking Workflow
You can follow the steps in the simulation of a forking workflow given below to learn how to follow such a workflow.
This activity is best done as a team.
Step 1. One member: set up the team org and the team repo.
Create a GitHub organization for your team. The org name is up to you. We'll refer to this organization as team org from now on.
Add a team called developers
to your team org.
Add team members to the developers
team.
Fork se-edu/samplerepo-workflow-practice to your team org. We'll refer to this as the team repo.
Add the forked repo to the developers
team. Give write access.
Step 2. Each team member: create PRs via own fork.
Fork that repo from your team org to your own GitHub account.
Create a branch named add-{your name}-info
(e.g. add-johnTan-info
) in the local repo.
Add a file yourName.md
into the members
directory (e.g., members/jonhTan.md
) containing some info about you into that branch.
Push that branch to your fork.
Create a PR from that branch to the master
branch of the team repo.
Step 3. For each PR: review, update, and merge.
[A team member (not the PR author)] Review the PR by adding comments (can be just dummy comments).
[PR author] Update the PR by pushing more commits to it, to simulate updating the PR based on review comments.
[Another team member] Approve and merge the PR using the GitHub interface.
[All members] Sync your local repo (and your fork) with upstream repo. In this case, your upstream repo is the repo in your team org.
Step 4. Create conflicting PRs.
[One member]: Update README: In the master
branch, remove John Doe and Jane Doe from the README.md
, commit, and push to the main repo.
[Each team member] Create a PR to add yourself under the Team Members
section in the README.md
. Use a new branch for the PR e.g., add-johnTan-name
.
Step 5. Merge conflicting PRs one at a time. Before merging a PR, you’ll have to resolve conflicts.
[Optional] A member can inform the PR author (by posting a comment) that there is a conflict in the PR.
[PR author] Resolve the conflict locally:
master
branch from the repo in your team org.master
branch to your PR branch.[Another member or the PR author]: Merge the de-conflicted PR: When GitHub does not indicate a conflict anymore, you can go ahead and merge the PR.
Can explain DRCS vs CRCS
RCS can be done in two ways: the centralized way and the distributed way.
Centralized RCS (CRCS for short) uses a central remote repo that is shared by the team. Team members download (‘pull’) and upload (‘push’) changes between their own local repositories and the central repository. Older RCS tools such as CVS and SVN support only this model. Note that these older RCS do not support the notion of a local repo either. Instead, they force users to do all the versioning with the remote repo.
The centralized RCS approach without any local repos (e.g., CVS, SVN)
Distributed RCS (DRCS for short, also known as Decentralized RCS) allows multiple remote repos and pulling and pushing can be done among them in arbitrary ways. The workflow can vary differently from team to team. For example, every team member can have his/her own remote repository in addition to their own local repository, as shown in the diagram below. Git and Mercurial are some prominent RCS tools that support the distributed approach.
The decentralized RCS approach
Revision Control → Forking Workflow
Can explain feature branch flow
Feature branch workflow is similar to forking workflow except there are no forks. Everyone is pushing/pulling from the same remote repo. The phrase feature branch is used because each new feature (or bug fix, or any other modification) is done in a separate branch and merged to the master
branch when ready.
Resources
Revision Control → Feature Branch Workflow
Can explain centralized flow
The centralized workflow is similar to the feature branch workflow except all changes are done in the master
branch.
Resources