After studying this code and completing the corresponding exercises, you should be able to,
[LO-Encapsulation]
[LO-ImplementClass]
[LO-SRP]
[LO-Exceptions]
[LO-Inheritance]
[LO-ISP]
[LO-ClassLevel]
[LO-Composition]
[LO-AssociationClass]
[LO-JUnit]
[LO-TDD]
[LO-2KLoC]
[LO-Encapsulation]
CommandResult
class membersCommandResult
class is not encapsulated. i.e. it is visible outside the object. Hide it so that it can only be accessed using methods provided.[LO-ImplementClass]
Address
into more classesSide reading: Code smell: Primitive Obsession - A case against using primitives instead of small objects for simple tasks
a/BLOCK, STREET, UNIT, POSTAL_CODE
a/123, Clementi Ave 3, #12-34, 231534
Address
class as follows. Note: the filled diamond symbol ◆ means an Address
consists of Block
, Street
, etc.[LO-SRP]
TextUi
classThe exercise in the LO-ImplementClass
section is somewhat related to SRP as well. Here's a slightly more difficult exercise.
TextUi
class has more than one responsibility. Try to extract out the responsibility of Formatting text for display (e.g. adding decorations) in to a separate class named Formatter
.[LO-Exceptions]
[LO-Inheritance]
Note how the Command
class contains some code that is reused by some of its child classes. By defining *Command
classes as child classes of Command
, we have avoided having to duplicate those methods in multiple *Command
classes.
Contact
classPhone
, Email
and Address
classes into a parent class called Contact
.[LO-ISP]
Note how the Person
class implements the ReadOnlyPerson
interface so that clients who don't need write access to Person
objects can access Person
objects through the ReadOnlyPerson
interface instead.
Printable
interfaceAdd a Printable
interface as follows.
Override
the getPrintableString
in classes Name
, Phone
, Email
, and Address
so that each produces a printable string representation of the object. e.g. Name: John Smith
, Phone: 12349862
Add the following method in a suitable place of some other class. Note how the method depends on the Interface.
/** * Returns a concatenated version of the printable strings of each object. */ String getPrintableString(Printable... printables){
The above method can be used to get a printable string representing a bunch of person details. For example, you should be able to call that method like this:
//p is a Person object return getPrintableString(p.getPhone(), p.getEmail(), p.getAddress());
[LO-ClassLevel]
Note how some of the variables and methods are declared static
. That means they are class-level members rather than instance-level members.
e.g.
Main.VERSION
, Name.EXAMPLE
, Utils.isAnyNull(...)
Parser::parseCommand(...)
method (i.e. the parseCommand()
method of the Parser
class) to a class-level method. Note how this method can be either class-level or instance-level.setTags
method of the Person
class cannot be converted to a class-level method.int sequenceNumber
and a class-level variable int nextSequenceNumber
to the Person
class. Using these two variables, ensure that each Person
object has a unique sequence number that indicates the order in which Person
objects were created. e.g.Adam
is the first Person
object to be created. It is assigned sequence number 1.Ben
and Charlie
are created next, and assigned 2 and 3 respectively.Ben
is deleted.Daisy
is added next and is given sequence number 4.[LO-Composition]
Note the following examples of composition (filled diamond):
Whole | Parts |
---|---|
AddressBook | UniquePersonList UniqueTagList |
Person | Name Phone Email Address |
Contrast with these examples of aggregration (empty diamond):
Container | Contained |
---|---|
UniquePersonList | Person |
UuniqueTagList | Tag |
[LO-AssociationClass]
The current design does not have any association classes.
Tagging
Assume the following:
+ Jake Woo [friend] - Jake Woo [colleague] + Jean Wong [client]
To support (ii) above, implement an Association Class called Tagging
as given in the diagram below.
Each Tagging
object will represent an adding or deleting of a tag for a specific person that happened during that session.
Note that if the list of
Tagging
s is kept as a class-level variable theTagging
class, the diagram would be like this:
[LO-JUnit]
Note how there are many test classes in this code base that uses JUnit to implement automated unit tests e.g. test/java/seedu/addressbook/parser/ParserTest.java
class contains tests for the seedu.addressbook.parser.Parser
class.
Utils#isAnyNull(Object...)
methodtest/seedu/addressbook/common/UtilsTest.java
to test the seedu.addressbook.common.Utils#isAnyNull(Object...)
method.[LO-TDD]
It's recommended you do [LO-JUnit]
before attempting TDD.
Add the following method to the Name
class. Use the TDD technique to add the method. Commit after each step.
/** * Returns true of the other name is very similar to this name. * Two names are considered similar if ... */ public boolean isSimilar(Name other) { ... }
You may define 'similar' as you see fit. Make sure the definition covers scenarios where other name is null
, in a different case, in a different order, is a subset/superset, etc.
e.g. John K Smith
John K SMITh
John Smith
Smith, John K
Don't forget to refactor the method to improve its code quality at the end.
[LO-2KLoC]
Add a feature to AddressBook. Here are some suggestions.