Name: addressbook-level1
Owner: Software Engineering Education - FOSS Resources
Description: A Java sample application for students. An AddressBook application written in procedural fashion.
Created: 2016-07-22 07:20:33.0
Updated: 2017-08-28 07:20:03.0
Pushed: 2018-02-09 06:58:44.0
Homepage: null
Size: 2519
Language: Java
GitHub Committers
User | Most Recent Commit | # Commits |
---|
Other Committers
User | Most Recent Commit | # Commits |
---|
Table of Contents
LO-IdeSetup
]LO-CodeNavigation
]LO-Debugging
]LO-AutomatedCliTesting
]LO-Collections
]LO-Enums
]LO-Varargs
]LO-CodingStandard
]LO-CodingBestPractices
]LO-Refactor
]LO-MethodAbstraction
]LO-SLAP
]LO-1KLoC
]This product is not meant for end-users and therefore there is no user-friendly installer. Please refer to the Setting up section to learn how to set up the project.
Using IntelliJ
Project Explorer
(usually located at the left side)Project Explorer
is not visible, press ALT+1 for Windows/Linux, CMD+1 for macOS to open the Project Explorer
tabsrc
folder and locate the AddressBook
fileRun AddressBook.main()
Console
(usually located at the bottom side)Console
Using Command Line
Build
-> Build Project
)Terminal
/Command Prompt
. Note: You can open a terminal inside Intellij too (View
-> Tool Windows
-> Terminal
)cd
into the project's out\production\addressbook-level1
directory. Note: That is the where Intellij puts its compiled class files.java seedu.addressbook.AddressBook
, then Enter to executehelp
Format: help
Help is also shown if you enter an incorrect command e.g.
abcd
add
Adds a person to the address book
Format: add NAME p/PHONE_NUMBER e/EMAIL
Words in
UPPER_CASE
are the parameters
Phone number and email can be in any order but the name must come first.
Examples:
add John Doe p/98765432 e/johnd@gmail.com
add Betsy Crowe e/bencrowe@gmail.com p/1234567
list
Shows a list of persons, as an indexed list, in the order they were added to the address book, oldest first.
Format: list
find
Finds persons that match given keywords
Format: find KEYWORD [MORE_KEYWORDS]
The search is case sensitive, the order of the keywords does not matter, only the name is searched, and persons matching at least one keyword will be returned (i.e.
OR
search).
Examples:
find John
Returns
John Doe
but notjohn
find Betsy Tim John
Returns Any person having names
Betsy
,Tim
, orJohn
delete
Format: delete INDEX
Deletes the person at the specified
INDEX
. The index refers to the index numbers shown in the most recent listing.
Examples:
list
delete 2
Deletes the 2nd person in the address book.
find Betsy
delete 1
Deletes the 1st person in the results of the
find
command.
clear
Clears all entries from the address book.
Format:clear
exit
Format: exit
Address book data are saved in the hard disk automatically after any command that changes the data. There is no need to save manually.
Address book data are saved in a file called addressbook.txt
in the project root folder.
You can change the location by specifying the file path as a program argument.
Example:
java seedu.addressbook.AddressBook mydata.txt
java seedu.addressbook.AddressBook myFolder/mydata.txt
The file path must contain a valid file name and a valid parent directory.
File name is valid if it has an extension and no reserved characters (OS-dependent).
Parent directory is valid if it exists.
Note for non-Windows users: if the file already exists, it must be a 'regular' file.When running the program inside IntelliJ, there is a way to set command line parameters before running the program.
Prerequisites
Importing the project into IntelliJ
File
> Close Project
to close the existing project dialog first)Configure
> Project Defaults
> Project Structure
New...
and select the directory where you installed JDK 8.OK
.Import Project
OK
Create project from existing sources
and click Next
Next
Next
Finish
AddressBook saves data in a plain text file, one line for each person, in the format NAME p/PHONE e/EMAIL
.
Here is an example:
Doe p/98765432 e/johnd@gmail.com
Doe p/12346758 e/jane@gmail.com
All person data are loaded to memory at start up and written to the file after any command that mutates data.
In-memory data are held in a ArrayList<String[]>
where each String[]
object represents a person.
Windows
test
folderruntests.bat
scriptactual.txt
and expected.txt
,
the test has passed.Mac/Unix/Linux
test
folderruntests.sh
scriptactual.txt
and expected.txt
,
the test has passed.Troubleshooting test failures
actual.txt
and expected.txt
?actual.txt
to the format used by your OS using some utility.Learning Outcomes are the things you should be able to do after studying this code and completing the corresponding exercises.
[LO-IdeSetup]
Part A:
Part B:
clone or download
link above and either,[LO-CodeNavigation]
The AddressBook.java
code is rather long, which makes it cumbersome to navigate by scrolling alone.
Navigating code using IDE shortcuts is a more efficient option.
For example, CTRL+B will navigate to the definition of the method/field at the cursor.
Learn basic IntelliJ code navigation features.
[LO-Debugging]
Learn basic IntelliJ debugging features.
Prerequisite: [LO-IdeSetup]
Demonstrate your debugging skills using the AddressBook code.
Here are some things you can do in your demonstration:
[LO-AutomatedCliTesting]
Learn how to automate testing of CLIs.
input.txt
. Run the tests. It should fail.expected.txt
to make the tests pass again.AddressBook.java
to modify the behavior slightly and modify tests to match.[LO-Collections]
Note how the AddressBook
class uses ArrayList<>
class (from the Java Collections
library) to store a list of String
or String[]
objects.
Learn how to use some Java Collections
classes, such as ArrayList
and HashMap
HashMap
Currently, a person's details are stored as a String[]
. Modify the code to use a HashMap<String, String>
instead.
A sample code snippet is given below.
ate static final String PERSON_PROPERTY_NAME = "name";
ate static final String PERSON_PROPERTY_EMAIL = "email";
Map<String,String> john = new HashMap<>();
.put(PERSON_PROPERTY_NAME, "John Doe");
.put(PERSON_PROPERTY_EMAIL, "john.doe@email.com");
c.
[LO-Enums]
HashMap
+ Enum
Similar to the exercise in the LO-Collections
section, but also bring in Java enum
feature.
ate enum PersonProperty {NAME, EMAIL, PHONE};
Map<PersonProperty,String> john = new HashMap<>();
.put(PersonProperty.NAME, "John Doe");
.put(PersonProperty.EMAIL, "john.doe@email.com");
c.
[LO-Varargs]
Note how the showToUser
method uses Java Varargs feature.
Modify the code to remove the use of the Varargs feature. Compare the code with and without the varargs feature.
[LO-CodingStandard]
The given code follows the coding standard for the most part.
This learning outcome is covered by the exercise in [LO-Refactor]
.
[LO-CodingBestPractices]
Most of the given code follows the best practices mentioned here.
This learning outcome is covered by the exercise in [LO-Refactor]
[LO-Refactor]
Resources:
Note: this exercise covers two other Learning Outcomes: [LO-CodingStandard]
, [LO-CodingBestPractices]
Extract variable isValidPerson
, Inline method isValidPerson()
[LO-MethodAbstraction]
Notice how most of the methods in AddressBook
are short and focused (does only one thing and does it well).
Case 1. Consider the following three lines in the main
method.
String userCommand = getUserInput();
echoUserCommand(userCommand);
String feedback = executeCommand(userCommand);
If we include the code of echoUserCommand(String)
method inside the getUserInput()
(resulting in the code given below), the behavior of AddressBook remains as before.
However, that is a not a good approach because now the getUserInput()
is doing two distinct things.
A well-abstracted method should do only one thing.
String userCommand = getUserInput(); //also echos the command back to the user
String feedback = executeCommand(userCommand);
Case 2. Consider the method removePrefixSign(String s, String sign)
.
While it is short, there are some problems with how it has been abstracted.
It contains the term sign
which is not a term used by the AddressBook vocabulary.
A method adds a new term to the vocabulary used to express the solution. Therefore, it is not good when a method name contains terms that are not strictly necessary to express the solution (e.g. there is another term already used to express the same thing) or not in tune with the solution (e.g. it does not go well with the other terms already used).
Its implementation is not doing exactly what is advertised by the method name and the header comment.
For example, the code does not remove only prefixes; it removes sign
from anywhere in the s
.
The method can be more general and more independent from the rest of the code. For example, the method below can do the same job, but is more general (works for any string, not just parameters) and is more independent from the rest of the code (not specific to AddressBook)
moves prefix from the given fullString if prefix occurs at the start of the string.
ate static String removePrefix(String fullString, String prefix) { ... }
If needed, a more AddressBook-specific method that works on parameter strings only can be defined. In that case, that method can make use of the more general method suggested above.
Refactor the method removePrefixSign
as suggested above.
[LO-SLAP]
Notice how most of the methods in AddressBook
are written at a single
level of abstraction (cf se-edu/se-book:SLAP)
Here is an example:
public static void main(String[] args) {
showWelcomeMessage();
processProgramArgs(args);
loadDataFromStorage();
while (true) {
userCommand = getUserInput();
echoUserCommand(userCommand);
String feedback = executeCommand(userCommand);
showResultToUser(feedback);
}
}
In the main
method, replace the processProgramArgs(args)
call with the actual code of that method.
The main
method no longer has SLAP. Notice how mixing low level code with high level code reduces
readability.
Sometimes, going in the wrong direction can be a good learning experience too. In this exercise, we explore how low code qualities can go.
[LO-1KLoC]
Enhance the AddressBook to prove that you can work in a codebase of 1KLoC.
Remember to change code in small steps, update/run tests after each change, and commit after each significant change.
Some suggested enhancements:
find
command case insensitive e.g. find john
should match John
sort
command that can list the persons in alphabetical orderedit
command that can edit properties of a specific personThe full list of contributors for se-edu can be found here.