Skip to content

Commit

Permalink
Merge pull request #136 from Esilocke/1.5rcUGDG
Browse files Browse the repository at this point in the history
[v1.5rc][Docs] Portfolio page + Update DG
  • Loading branch information
Esilocke authored Nov 7, 2017
2 parents d475144 + 68574fb commit caa3d18
Show file tree
Hide file tree
Showing 3 changed files with 201 additions and 29 deletions.
56 changes: 27 additions & 29 deletions docs/DeveloperGuide.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -376,53 +376,50 @@ image::UndoRedoActivityDiagram.png[width="200"]
**Cons:** Requires dealing with commands that have already been undone: We must remember to skip these commands. Violates Single Responsibility Principle and Separation of Concerns as `HistoryManager` now needs to do two different things. +
// end::undoredo[]

// tag::task[]
=== Task Object

The Task object stores information related to a single deadline or task, in a manner similar to how Person information is stored. +
As such, it also shares the same types of commands as the Person object, namely the add, delete, list, select, and edit commands.
Instead of making a new Logic object for each new command, polymorphism is used to implement the "Task" version of each command.
As such, it also shares the same types of commands as the Person object, namely the `add`, `delete`, `find`, `select`, and `edit` commands.
Object inheritance is thus used to create the commands that are shared with those used to handle Person objects.

An example of using polymorphism to handle Person vs Task addition:
==== Task-related Command implementation

An example of using inheritance to handle Person vs Task addition:

[source,java]
----
public class AddCommand extends Command {
public AddCommand(ReadOnlyPerson person) {
toAdd = new Person(person);
toHandle = HANDLE_TYPE_PERSON;
}
public class AddPersonCommand extends AddCommand {
}
public AddCommand(ReadOnlyTask task) {
toAdd = new Task(task);
toHandle = HANDLE_TYPE_TASK;
}
public class AddTaskCommand extends AddCommand {
}
----

The AddCommand will thus call a different constructor depending on the type of the argument supplied to it. To facilitate this, the respective Parser class must also be modified:

[source,java]
----
public AddCommand parse(String args) throws ParseException {
int objectType = checkType(args);
if (objectType == HANDLE_TYPE_PERSON) {
Person toAdd = createNewPerson(args);
return AddPersonCommand(toAdd);
} else if (objectType == HANDLE_TYPE_TASK) {
Task toAdd = createNewTask(args);
return AddTaskCommand(toAdd);
}
return new AddCommand(toAdd);
}
----

The AddCommandParser checks the args to see if this is a task, then creates the object to be added, and creates a new AddCommand to handle the result. +
The Parser in charge of the command will thus return either an AddPersonCommand, or an AddTaskCommand, depending on whether you specify to add a Task or not in the arguments.
+
The sequence diagram below shows how this is done:

image::AddTaskSeq.png[width="800"]

To support the addition of Task objects, the Storage component is modified to accept Task objects in a similar manner as to how Person objects are being stored.
==== Task Object Storage

[source, html]
[source, xml]
---
<persons>
<name>someone else</name>
Expand All @@ -438,28 +435,29 @@ To support the addition of Task objects, the Storage component is modified to ac
</tasks>
---

Tasks objects are stored in the same level of hierarchy as Person objects, and during startup, are read and entered into the UniqueTaskList, which handles all the tasks that are present in the address book.
Task objects are stored in a similar manner to Person objects, and share the same level of hierarchy as Person objects. During startup, tasks are read and entered into the UniqueTaskList, which handles all the tasks that are present in the address book.


==== Design Considerations

**Aspect:** Implementation of Task-related commands +
**Alternative 1 (current choice):** Use polymorphism to allow existing commands to implement the new commands +
**Pros:** Under this scheme, any command can be extended to allow addition of new commands of any type, without affecting the architecture significantly +
**Cons:** SRP may be violated as each Command class may now need to handle 2 different types of objects. +
**Alternative 2:** Create new classes for all new commands +
**Pros:** Simpler to implement. +
**Cons:** Code duplication occurs as the commands for Person and Tasks objects share the same structure.
**Alternative 1 (current choice):** Use inheritance to implement different commands for Task and Person objects +
**Pros:** Can be easily extended to allow handling of other types of objects, and preserves Separation of Concerns. +
**Cons:** Minor code duplication occurs as the commands for Person and Tasks objects share the same structure. +
**Alternative 2:** Use polymorphism to allow existing commands to implement task handling +
**Pros:** Code duplication is kept to a minimum as the Command will handle Task and Person objects in the same class. +
**Cons:** Single Responsibility Principle is violated as each Command class now needs to handle 2 different types of objects. +

---

**Aspect:** Storage of Task objects +
**Alternative 1 (current choice):** Store Tasks objects in a separate XML file +
**Pros:** Easier to manage as Person storage will not interfere with Task storage, and vice versa.
**Cons:** All existing save/load functions will require an additional method to handle Task storage.
**Alternative 2:** Store Task objects together in the default XML storage file +
**Pros** Only 1 storage file is needed. The storage manager thus only needs to refer to one storage +
**Cons** Any changes to the Person or Task will affect the storage of both the Person and Task objects. This will increase coupling between the Person and Task classes.
**Cons** Any changes to the Person or Task will affect the storage of both the Person and Task objects. This will increase coupling between the Person and Task classes. +
**Alternative 1 (current choice):** Store Tasks objects in a separate XML file +
**Pros:** Easier to manage as Person storage will not interfere with Task storage, and vice versa. +
**Cons:** All existing save/load functions will require an additional method to handle Task storage. +
// end::task[]

=== Sort Command

Expand Down
6 changes: 6 additions & 0 deletions docs/UserGuide.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,7 @@ Edits the priority of the 2nd task to be `5`.
Removes the priority and deadline of the second task.
// end::editprivacy[]

// tag::edittag[]
=== Renaming existing tags : `edittag` (Since v1.2)

You can use `edittag` to rename one existing tag. For example, you may wish to promote all existing "acquaintances" into "friends", or change all "CS2103" project mates to "CS2101" project mates instead. +
Expand All @@ -272,6 +273,7 @@ Examples:

* `edittag friends enemies` +
Changes the tag called `friends` to one called `enemies` instead. All existing contacts with a `friends` tag will now have an `enemies` tag instead.
// end::edittag[]

// tag::changeprivacy[]
=== Changing the Privacy of a person's details : `changeprivacy`(Since V1.3)
Expand Down Expand Up @@ -615,6 +617,7 @@ Opens Google Maps to provide directions on how to navigate from the address of t
****
// end::navigate[]

// tag::setstate[]
=== Mark task as complete : `setcomplete` (Since V1.5)

Have you finally completed a task in the address book? You can use `setcomplete` to mark the specified task as complete. +
Expand Down Expand Up @@ -656,7 +659,9 @@ Sets the 2nd task in the address book as incomplete.
* `find task update` +
`setincomplete 1` +
Sets the 1st task in the results of the `find task` command as incomplete.
// end::setstate[]

// tag::assignDismiss[]
=== Assign contacts to task : `assign` (Since V1.4)

You can use `assign` to assign contacts to an ongoing task. You may wish to use `assign` when collaborating with others for projects, for example. +
Expand Down Expand Up @@ -704,6 +709,7 @@ Dismisses 1st, 4th and 5th contacts in the address book from the 2nd task.
`find task update` +
`dismiss 2 from/1` +
Dismisses the 2nd person in the address book from the 1st task in the results of the `find task` command.
// end::assignDismiss[]

=== Listing entered commands : `history`

Expand Down
168 changes: 168 additions & 0 deletions docs/team/Esilocke.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
= Kelvin Lin - Project Portfolio
ifdef::env-github,env-browser[:outfilesuffix: .adoc]
:imagesDir: ../images
:stylesDir: ../stylesheets

== Project: AddressBook - Level 4
AddressBook - Level 4 is a desktop address book application used for teaching Software Engineering principles. The user interacts with it using a CLI, and it has a GUI created with JavaFX. It is written in Java, and has about 6 kLoC.

*Code contributed*: [https://github.com/CS2103AUG2017-W09-B2/main/blob/master/collated/main/Esilocke.md[Functional code]] [https://github.com/CS2103AUG2017-W09-B2/main/blob/master/collated/test/Esilocke.md[Test code]]

=== Enhancement Added: Edit Tag

==== External behavior

---
#Start of Extract [from: User Guide]#

include::../UserGuide.adoc[tag=edittag]

#End of Extract#

---

==== Justification

The user may find a need to change the name of a particular name. +
In the context of the target user, suppose that a user wishes to change the tag `CS2103Groupmates` to `friends`, after he has completed the module. +
The user would need to delete the tag from all users who are tagged with `CS2103Groupmates`, and add the tag `friends` to them one-by-one. `edittag` thus aims to make this process faster by allowing users to rename all instances of the tag from the address book.

==== Implementation

---
#Start of Extract [from: Developer Guide]#

include::../DeveloperGuide.adoc[tag=edittag]

#End of Extract#

---

=== Enhancement Added: Optional Data Input

==== External behavior

---

Optional Data Input allows tasks and persons to have only one compulsory field, the name. All other fields in a person or task can be left unspecified, allowing for a greater range of inputs.

---

==== Justification

We may not always have the opportunity to have contacts or tasks with complete information. +
Some contacts may not have an address, or email address, while some tasks may not have a deadline, or require a description. Without Optional Data Input, the user would need to come up with random placeholder values for each prefix, which would greatly hinder user experience as the user would need to type in unnecessary values to satisfy the command format. +
Allowing optional data input thus lifts the restriction of making every field compulsory, and thus allows users to fill in a wider range of input.

==== Implementation

---
#Start of Extract [from: Developer Guide]#

include::../DeveloperGuide.adoc[tag=optional]

#End of Extract#

---

=== Enhancement Added: Tasks Management

==== External behavior

---
#Start of Extract [from: User Guide]#

include::../UserGuide.adoc[tag=task]
include::../UserGuide.adoc[tag=setstate]
include::../UserGuide.adoc[tag=assignDismiss]

#End of Extract#

---

==== Justification

Our intended target audience are primarily NUS students, who are working on projects. In addition to managing their contact details, allowing users to manage their tasks would also greatly improve their user experience, as they would not need to keep track of their project deadlines separately.


==== Implementation

---
#Start of Extract [from: Developer Guide]#

include::../DeveloperGuide.adoc[tag=task]

#End of Extract#

=== Assign and Dismiss Commands

The `assign` and `dismiss` command allows you to assign contacts to and from your tasks, thus aiding coordination and collaboration. +
The Assignees class stores information related to who is assigned to a particular task through maintaining an internal ArrayList that keeps track of all the indexes of the people who are assigned to the task. +

The indexes stored in the Assignees class *refer to the index of the person in the UniquePersonList, not the visible index shown to the user in the UI*. This means that the indexes will not change even if the list shown in the UI changes, such as after a `find` operation. +
For example, given the below list of persons:

0. First person
1. Second person
2. Third person
3. Fourth person
4. Fifth person
5. Sixth person

After a `find` operation, the following list of persons is shown to the user: +

1. Second person
2. Fourth person
3. Fifth person

When you call `assign 1 2 to/1`, while the first and second persons in the visible list will be assigned to the first Task, in this case the "Second person" and "Fourth person", internally the assignee list contains the following values: +

[source, java]
assignedList = {1, 3}

The indexes 1 and 3 refer to the zero-based index of the "Second person" and "Fourth person" in the complete list.

==== Design Considerations

**Aspect:** Storage of assigned persons in the Assignee class +
**Alternative 1 (current choice):** Store the Indexes of the persons only +
**Pros:** The assigned persons will only need to be retrieved on a per-need basis, rather than residing in the Assignee class all the time, thus making storage simpler +
**Cons:** UniquePersonList will be coupled to Tasks, as Tasks will need to retrieve information from the UniquePersonList in order to . +
**Alternative 2:** Store the whole person in the Assignees class +
**Pros:** The Assignees class will not need to depend on the UniquePersonList as its internal list is independent from that of the UniquePersonList +
**Cons:** Repetition of information is incurred in the storage file, as the same person can appear multiple times if he is assigned to multiple tasks. This will increase the size of the storage file, and make read-write operations slow. +

---

=== Enhancement Proposed: Add automatic reminders for upcoming tasks

==== External behavior

---
#Start of Extract [from: User Guide]#

include::../UserGuide.adoc[tag=reminder]

#End of Extract#

---

==== Justification

When a user has many tasks, they might wish to see which tasks are due, or already past their deadlines. While the user could do this indirectly via sorting the tasks by their deadlines, having the application remind the user of the number of tasks upcoming would serve as an alternative.

==== Implementation

---
#Start of Extract [from: Developer Guide]#

include::../DeveloperGuide.adoc[tag=reminder]

#End of Extract#

---

=== Other contributions

* Conducted internal rigorous Acceptance testing (Link to Issues found)
* Conducted Acceptance Testing for other teams [https://github.com/CS2103AUG2017-F09-B1/main/issues/83[F09-B1]] [https://github.com/CS2103AUG2017-F09-B1/main/issues/82[F09-B1]]

0 comments on commit caa3d18

Please sign in to comment.