首页 > > 详细

CSC 216辅导、JAVA程序设计调试、JAVA辅导辅导留学生Prolog|调试C/C++编程

Home > Projects > CSC 216 Projects - Fall 2020 > Project 1, Part 2: Project Manager
CSC216: Project 1
Project 1, Part 2: Project Manager
Project 1, Part 2: Project Manager
Part 1 of this assignment laid out the requirements for the Project Manager application that you must create. Part 2 details the design that you must implement
and test. For this part, you must create a complete Java program consisting at multiple source code files and JUnit test cases. You must electronically submit your
files to NCSU GitHub by the due date.
Process Points 1 Deadline: Thursday, September 24, 2020 at 11:45PM
Process Points 2 Deadline: Thursday, October 1 , 2020 at 11:45PM
Part 2 Due Date: Thursday, October 8, 2020 at 11:45PM
Late Deadline: Saturday, October 10, 2020 at 11:45PM
Project 1 Part 2 MUST be completed individually.
Set Up Your Work Environment
Before you think about any code, prepare your work environment to be compatible with the teaching staff grading criteria. The teaching staff relies on NCSU
GitHub and Jenkins for grading your work. Follow these steps:
1. Create an Eclipse project named Project1: Right click in the package explorer, select New > Java Project. Name the project Project1. (The project naming is case
sensitive. Be sure that the project name begins with a capital P and ends with a 1. There are no spaces in the project name.) DO NOT CREATE module-info.java
FOR PROJECT1!!
2. If you have not already done so, clone your remote NCSU GitHub repository corresponding to this project. Note that each major project will have its own
repository.
Requirements
The requirements for this project are described in Project 1 Part 1. The Problem Overview describes the Project Manager FSM for user stories. The system is
further described in 15 different use cases:
i Use Case 1: Create Project
i Use Case 2: Load Projects and User Stories
i Use Case 3: Save Projects and User Stories
i Use Case 4: Quit Project Manager
i Use Case 5: Select Active Project
i Use Case 6: List User Stories
i Use Case 7: Add a User Story
i Use Case 8: Delete a User Story
i Use Case 9: Edit a User Story
i Use Case 10: Edit User Story in Submitted State
i Use Case 11: Edit User Story in Backlog State
i Use Case 12: Edit User Story in Working State
i Use Case 13: Edit User Story in Verifying State
i Use Case 14: Edit User Story in Completed State
i Use Case 15: Edit User Story in Rejected State
Design
Your program must implement the teaching staff design, which is described below. The design consists of 13 different classes (6 as inner classes), 1
enumerations, and 1 interface. We are providing the interface (UserStoryState - which should be an inner interface of the UserStory class) and the graphical user
interface front-end (ProjectManagerGUI).
edu.ncsu.csc216.project_manager.model Classes in the edu.ncsu.csc216.project_manager.model package form the model portion of the ProjectManager system.
edu.ncsu.csc216.project_manager.model.command. Sub-package of edu.ncsu.csc216.project_manager.model containing the object representation of a command
that a user would make in the Project Manager that might initiate a state change. This is an example of the Command Pattern.
i Command. Encapsulates the information about a user command that would lead to a transition in the user story FSM. Contains one inner enumerations.
i CommandValue. An enumeration contained in the Command class (i.e., an inner-enumeration). Represents one of the seven possible commands that a user
can make for the user story FSM. See the information about Enumerations in the implementation section - the code for the enumeration is provided there.
edu.ncsu.csc216.project_manager.model.user_story. Sub-package of edu.ncsu.csc216.project_manager.model containing the State Pattern implementation of the
user story FSM that is part of the larger Project Manager system.
i UserStory. Concrete class representing the State Pattern context. An UserStory keeps track of all user story information including the current state. The state is
updated when a Command encapsulating a transition is given to the UserStory. UserStory encapsulates the UserStoryState interface and six concrete *State
classes.
i UserStoryState. Interface that describes behavior of concrete *State classes for the Project Manager FSM. You cannot change this code in any way. All
concrete *State classes must implement UserStoryState. UserStoryState is an inner interface of the UserStory class. All of the *State classes that implement
UserStoryState are also inner classes of UserStory.
i SubmittedState: Concrete class that represents the submitted state of the Project Manager FSM.
i BacklogState: Concrete class that represents the backlog state of the Project Manager FSM.
i WorkingState: Concrete class that represents the working state of the Project Manager FSM.
i VerifyingState: Concrete class that represents the verifying state of the Project Manager FSM.
i CompletedState: Concrete class that represents the completed state of the Project Manager FSM.
i RejectedState: Concrete class that represents the rejected state of the Project Manager FSM.
edu.ncsu.csc216.project_manager.model.io. Sub-package of edu.ncsu.csc216.project_manager.model containing file processing classes.
i ProjectReader. Processes a file containing project and user story information and creates a List of Projects and their associated UserStorys.
i ProjectWriter. Writes the given list of Projects to the file name provided.
edu.ncsu.csc216.project_manager.model.manager. Sub-package of edu.ncsu.csc216.project_manager.model containing Projects (and their associated UserStorys
and the overarching ProjectManager functionality.
i Project. Concrete class that maintains its name and a list of UserStorys in the project.
i ProjectManager. Concrete class that maintains a list of Projects, the active or current project, and handles Commands from the GUI. ProjectManager
implements the Singleton Design Pattern.
edu.ncsu.csc216.project_manager.view
Classes in the edu.ncsu.csc216.project_manager.view package implement the view-controller of the ProjectManager program.
edu.ncsu.csc216.project_manager.view.ui. Sub-package of edu.ncsu.csc216.project_manager.view containing the view-controller elements of the Project Manager
Model-View-Controller pattern.
i ProjectManagerGUI. The graphical user interface for the project. This is the class that starts execution of the program. You cannot change this code in any way.
The ProjectManagerGUI interacts with the rest of the system through the ProjectManager singleton.
UML Class Diagrams
The UML class diagram for the design is shown in the figure below. The fields and methods represented by green circles (public) or yellow diamonds (protected)
represent the minimum set of visible state and behavior required to implement the project.
Figure 1: Project Manager UML class diagram
UML Class Diagram Notations
UML uses standard conventions for display of data, methods, and relationships. Many are illustrated in the UML class diagram above. Here are some things you
should note:
i - or a red square in front of a class member means private.
i + or a green circle in front of a class member means public.
i # or a yellow diamond in front of a class member means protected.
i Static members (data or methods) are underlined.
i Methods that are declared but not defined (abstract methods or those declared in interfaces) are in italics, unless they are in an interface.
i The names of abstract classes are in italics.
i Dotted arrows with triangular heads point to interfaces from the classes that implement them.
i Solid arrows with triangular heads go from concrete classes to their parents.
i Solid arrows with simple heads indicate has-a relationships (composition). The containing class is at the tail of the arrow and the class that is contained is at
the head. The arrow is decorated with the name and access of the member in the containing class. The arrow is also decorated with the “multiplicity” of the
relationship, where 0..1 means there is 1 instance of the member in the containing class. (See c on the arrow from Command to CommandValue.) A multiplicity
of 0..* means there are many, usually indicating a collection such as an array or collection class. (See stories on the arrow from Project to UserStory.)
i A circle containing an “X” or cross sits on a the border of a class that contains an inner (nested) class, with a line connecting it to the inner class. (See the class
BacklogState and its corresponding outer class UserStory. See also the enumerations.)
Our UML class diagram has some additional graphic notation:
i A red square (empty or solid) in front of a name means private. Solid squares are methods and empty squares are data members. (See UserStory.storyId.)
i A green circle (empty or solid) in front of a name means public. (See Project.addUserStory(...).)
i A yellow diamond (empty or solid) in front of a name means protected.
i SF in front of a name means static, final. (See UserStory.BACKLOG_NAME.)
i Methods embellished with C are constructors. (See UserStory.UserStory(...).) Private methods embellished with a C are constructors in private inner classes.
(See ProjectManager.ProjectManager().) Note that while all classes require a constructor, not all constructors require implementation. In some cases the default
constructor is sufficient (e.g., in the inner *State classes).
Implementation Process
Professional software development is more than building working software. The process of building software is important to build complex systems efficiently.
We expect you to follow good software engineering practices and processes as you create your software to help you become a better software developer and to
help with understanding your progress on the project. We have general software engineering practices we expect you to follow throughout the project, you will be
evaluated on some of these as per the grading rubric at the end of the project. Additionally, we have Process Points Milestones that will help you work on the
project. The Process Points 1 Milestone is a compiling skeleton and commented code. The Process Points 2 Milestone is a complete, but not fully tested system.
Deadlines are listed at the top of this page and on Moodle. There are no late deadlines for process points.
General Software Engineering Practices
i Commit with meaningful messages.
i Run your static analysis tools locally and make sure that all your Javadoc is correctly formatted. Make sure the tools are configured correctly (see configuration
instructions) and set up the tools to run with each build so you are alerted to style notifications shortly after creating them. Note that we will evaluate the
content of your comments (both for Process Points 1 and the final deliverable) after the final deadline. Your comments should describe the functionality of the
various structures in your code.
i Practice test-driven development. Start by writing your test cases. This will help you think about how a client would use your class (and will help you see how
that class might be used by other parts of your program). Then write the code to pass your tests.
Process Points 1 Milestone
Process Points 1 Milestone gets you started with the project and ensures that you meet the design and that you start commenting your code.
i Compile a skeleton. The class diagram provides a full skeleton of what the implemented Project Manager program should look like. Start by creating an Eclipse
project named Project1. Copy in provided code and create the skeletons of the classes you will implement, including the test classes. Ensure that the packages,
class names, and method signatures match the class diagram exactly! If a method has a return type, put in a place holder return statement (for example,
return 0; or return null;) so that your code will compile. Push to GitHub and make sure that your Jenkins job shows a yellow ball. A yellow ball on Jenkins
means that 1) your code compiles, 2) that the teaching staff tests compile against your code, which means that you have the correct code skeleton for the
design, and 3) you have a skeleton of your test code in the test/ folder.
i Comment your code. Javadoc your classes and methods. When writing Javadoc for methods, think about the inputs, outputs, preconditions, and post
conditions.
Process Points 2 Milestone
For Process Points 2 Milestone you are expected to have completely implemented the project with at least 60% statement/line coverage for all non-UI classes AND
no test-related PMD notifications. Reaching 60% statement/line coverage with no test-related PMD notifications for all non-UI classes will unlock the teaching staff
test cases. The feedback from the hidden teaching staff tests can be used to refine your implementation and tests.
Note that for full credit for the coverage portion of the project, you MUST have at least 80% statement/line coverage for all non-UI classes. The expectation with
providing teaching staff test feedback after reaching 60% statement/line coverage is that you will likely have teaching staff test failures and you can use the
feedback in the teaching staff tests to enhance your own tests. This will help you write high-quality tests for debugging while reducing some of the rework of
implementation and test given the teaching staff feedback (which is ultimately what you’ll be graded on).
The Process Points 2 Milestone is due a week before the final project deadline. This will provide time for you to debug your project and (hopefully) finish early!
To earn full credit for the process points deadline, you should have at least 60% coverage of all non-UI classes and no test-related PMD notifications before the
deadline. Then you will see the Teaching Staff tests listed in your TestResults with the leading TS*. The hints that go along with the test failures are written to
describe the scenario that is being tested. You should use these hints to write your own version of the tests for debugging. If you have questions about the hints,
please post to piazza and include the name of the teaching staff test file, the test method, and the line number to facilitate feedback. We also expect that you have
made a good faith efforts to try to recreate the test locally before asking additional questions.
Another consideration when working with teaching staff test feedback is the order that you should consider test failures. The implementation section describes
the suggested order of implementation for the classes. You should also resolve teaching staff test failures in the same order. For example, if the FSM in UserStory
isn’t working correctly, the tests in Project that execute changing the state on the FSM likely won’t work either. Fix the UserStory class first! That may resolve the
issues you’re seeing in other classes that depend on it.
Implementation
We suggest you work on Project 1 Part 2 one piece at a time. The details below provide the suggested implementation order and details about the
implementation.
Package edu.ncsu.csc216.project_manager.model.command.
The Command class creates objects that encapsulate user actions (or transitions) that cause the state of a UserStory to update. We recommend that you start with
the Command class because the UserStory class and the concrete States rely on a correctly working Command class.
Command should include an enumeration for the possible command values that can cause transitions in our FSM (CommandValue). Our textbook defines
enumeration as “a type that has only a small number of predefined constant values.” Since there are a discrete number of actions a user can take and a set
number of resolutions, an enumeration is quite appropriate to list those values.
Copy the code below into the Command class exactly as given. You can include the enumeration code with the fields of Command. Enumerations are pseudoobjects
(like arrays). Constructors are listed in the class diagram, but are not needed in the implementation. You should Javadoc this enumeration using classlevel-like
comments.
To access a value in the enumeration, use the classname, (Command), followed by the enumeration name (CommandValue) followed by the value (for example,
Command.CommandValue.ASSIGN). Enumerated types are essentially a name given to an integer value. Therefore, you can use primitive comparison operators
(== and !=) to compare enumerated type variables of the same enumerated type. Enumerated types can also be the type of a variable. For example, Command’s
command field is of type CommandValue. See pp. 1133-1134 in the Reges and Stepp textbook or Section 5.13 in the Zybook for more details on enumerated types.
A Command constructor has 2 parameters: CommandValue command, String commandInformation. The second value may not be needed for every
CommandValue. Unneeded values can be passed as null. Any The following conditions result in an IllegalArgumentException when constructing a Command
object:
i A Command with a null CommandValue parameter. A Command MUST have a CommandValue.
i A Command with a CommandValue of BACKLOG, ASSIGN, or REJECT with a null or empty string commandInformation. These commands require an
additional piece of information.
i A Command with a CommandValue of REVIEW, CONFIRM, REOPEN, or RESUBMIT and a non-null commandInformation. These commands do NOT require an
additional piece of information.
The remaining methods are standard getters for the fields.
Package edu.ncsu.csc216.project_manager.model.user_story
The user_story package holds the context (UserStory), abstract state (the interface UserStoryState), and the concrete states (all the *State classes) of the State
design pattern for the user story FSM as part of the Project Management system.
UserStory represents an user story managed by our system. An UserStory knows its storyId, state, title, user, action, value, priority, developerId, and
rejectionReason. Each UserStory has its own state, which is updated from Commands propagated to it from the UI.
The six concrete *State classes implement UserStoryState. UserStoryState should be an inner interface of UserStory. The *State classes should be inner classes
of UserStory. Every concrete UserStoryState must support two behaviors: 1) update when given a Command and 2) know its name.
UserStory
UserStory has the following constants, which are all public. This means that you can use them directly in other classes and tests. They MUST be public b/c the
teaching staff tests may rely on them!
i Constants for State Names:
i SUBMITTED_NAME: A constant string for the submitted state’s name with the value “Submitted”.
i BACKLOG_NAME: A constant string for the backlog state’s name with the value “Backlog”.
i WORKING_NAME: A constant string for the working state’s name with the value “Working”.
i VERIFYING_NAME: A constant string for the verifying state’s name with the value “Verifying”.
i COMPLETED_NAME: A constant string for the completed state’s name with the value “Completed”.
i REJECTED_NAME: A constant string for the rejected state’s name with the value “Rejected”.
i Constants for Priority:
i HIGH_PRIORITY: A constant string for the priority of “High”.
i MEDIUM_PRIORITY: A constant string for the priority of “Medium”.
i LOW_PRIORITY: A constant string for the priority of “Low”.
i Constants for Rejection Reason:
i DUPLICATE_REJECTION: A constant string for the rejection reason of “Duplicate”.
i INAPPROPRIATE_REJECTION: A constant string for the rejection reason of “Inappropriate”.
i INFEASIBLE_REJECTION: A constant string for the rejection reason of “Infeasible”.
UserStory has the following fields needed for an user story:
i storyId: Unique id for an user story.
i state: Current state for the user story of type UserStoryState.
i title: Title of the user story as provided by the user on creation.
i user: The user information for the statement “As a [user]”.
i action: The action information for the statement “I want to [action]”.
i value: The value information for the statement “so I can [value]”.
i priority: The user story’s priority. Can only take on the values of null (e.g., no priority set) or one of the priorities listed above.
i developerId: The user story’s assigned developer. Can only take on the values of null (e.g., no assigned developer) or a non-empty string.
i rejectionReason: The user story’s rejection reason. Can only take on the value of null (e.g., no rejection reason) or one of the rejection reason constants listed
above.
UserStory has a static field counter and two static methods, incrementCounter() and setCounter(). The static modifier on counter means that the field is shared
across all instances of UserStory. If one instance of UserStory changes the values of counter another instance of UserStory would see the changed value. The
benefit of this is that we can use the counter field for creating the storyId for each new instance of a UserStory! The idea is that when a new UserStory is created,
it takes the current value of the storyId and increments the counter via the incrementCounter() method. If a UserStory is created from info read in from a file (the
constructor with parameters for each value), then the id is already provided. But we can set up the id for the next user story to be the incoming id + 1. The
setCounter() method is there for clients of UserStory to set the counter value to a given number. During testing, you can use the setCounter() method to set the
UserStory to a known counter and ensure that the first UserStory is created with that known id and the second one is created with an id of counter + 1. You’ll also
use this method later with the Project class.
UserStory maintains one instance of every concrete *State class. One of these instances may be the current state of the UserStory at any given time. All of the
*State instances should be final; they are not changed once constructed.
i submittedState: Final instance of the SubmittedState inner class.
i backlogState: Final instance of the BacklogState inner class.
i workingState: Final instance of the WorkingState inner class.
i verifyingState: Final instance of the VerifyingState inner class.
i completedState: Final instance of the CompletedState inner class.
i rejectedState: Final instance of the RejectedState inner class.
A UserStory has two constructors:
i UserStory(String title, String user, String action, String value): Constructs a UserStory from the provided title, user, action, and value. If any of the parameters
are null or empty strings, then an IllegalArgumentException is thrown. The storyId field is set to the value stored in UserStory.counter. The counter is then
incremented using UserStory.incrementCounter(). A new UserStory starts in the submitted state. The priority, developerId, and rejectionReason are all null.
i UserStory(int id, String state, String title, String user, String action, String value, String priority, String developerId, String rejectionReason): The fields of the
UserStory are set to the parameter values after error checking. This constructor should be used in the ProjectReader class. You may find it useful to create
private setter methods to set the fields for UserStory. This constructor checks the constraints on UserStory objects listed in [UC2]. Additionally, if the incoming
id is greater than the current value in UserStory.counter, then the UserStory.counter should be updated to the id + 1 using the setCounter(id) method. Note that
if there is an issue with any of the parameters, an IllegalArgumentException should be thrown.
UserStory has getters and setters to handle working with the field information. All setters must be private and are optional, but strongly recommended. The
private setters are intended for use during object construction. The getters return information that would be appropriate for display in the GUI. The
setState(String) method receives a String value for the state. You will need to use the String to figure out which *State instance to assign to the state field for the
current state. You can also do error checking on if the state and other parameters are valid as per [UC2].
The update(Command) method drives the finite state machine by delegating to the current state’s updateState(Command) method. The update() method throws
an UnsupportedOperationException if the current state determines that the transition, as encapsulated by the Command, is not appropriate for the FSM. (Note:
The *State.updateState(Command) methods will actually create and throw the UnsupportedOperationException. The UserStory.update(Command) method will let
that exception pass through to its caller. But since the exception can be thrown out of UserStory.update(Command) you MUST document the method
accordingly.)
The toString() method returns the string representation of the UserStory that is printed during file save operations [UC3].
UserStory has six inner classes that each implement UserStoryState. The inner classes each represent the six states in the user story FSM. Each concrete *State
handles updating when given a Command. If the Command is not appropriate for the current state, then the concrete *State’s update() method throws an
UnsupportedOperationException. Otherwise, the state field of UserStory is updated as appropriate for the Command. Additional UserStory fields may be modified
based on the command and transition expectations. A concrete *State also knows its name. The use case associated with each concrete *State is below:
i Use Case 10: Edit User Story in Submitted State
i Use Case 11: Edit User Story in Backlog State
i Use Case 12: Edit User Story in Working State
i Use Case 13: Edit User Story in Verifying State
i Use Case 14: Edit User Story in Completed State
i Use Case 15: Edit User Story in Rejected State
Package edu.ncsu.csc216.project_manager.model.manager
The manager package contains the two classes that manage the Projects and their UserStorys. You’ll want to complete the Project class before the file I/O classes.
You’ll finish the ProjectManager class after the file I/O classes.
Project
A Project has a projectName and maintains a List of UserStorys.
When creating a new Project, set the project name and create a new empty List (you may use either an ArrayList or a LinkedList from the Java Collections
Framework as the constructed type). An IllegalArgumentException is thrown if the projectName is null or an empty string.
Project supports the following operations:
i setUserStoryId() which will set the counter for the UserStory instances to the value of the maximum id in the list of UserStorys for the project + 1.
i getProjectName() returns the project name.
i addUserStory(String title, String user, String action, String value) creates a new UserStory in the submitted state, adds it to the list in sorted order, and returns
the id. If a story already exists with the given id, an IllegalArgumentException will be thrown.
i addUserStory(UserStory story) adds the user story to the list in sorted order by id. The list will be maintained in sorted order, so you will be able to add a new
story in order. If a story already exists with the given id, an IllegalArgumentException will be thrown.
i getUserStories() returns the List of UserStorys.
i getUserStoryById(int id) returns the UserStory in the list with the given id. If there is no UserStory with that id, the method returns null.
i deleteUserStoryById(int id) removes the UserStory with the given id from the list.
i executeCommand(int id, Command c) will find the UserStory with the given id and update it by passing in the given Command.
The addUserStory(String title, String user, String action, String value) method has the same parameters as the
UserStory(String title, String user, String action, String value) constructor. Error checking on the parameters can be delegated to the UserStory constructor.
When working with methods that receive an id parameter, there is no need to error check or throw an exception if the id does not exist in the list. For
getUserStoryById, return null. For all other methods, do not change the internal state of the list.
Package edu.ncsu.csc216.project_manager.model.io
The io package holds the classes that handle file input and output. Since the methods are static, there are no explicit composition relationships modeled in the
class diagram. However, ProjectManager (and the teaching staff tests) will depend on these files working to test Project and ProjectManager in addition to testing
the ProjectReader and ProjectWriter classes themselves.
ProjectReader
ProjectReader has one public method readProjectFile that receives a String with the file name to read from. If the file cannot be loaded because it doesn’t exist, the
method will throw an IllegalArgumentException with the message “Unable to load file.” Any invalid user stories or projects (i.e., they cannot be constructed,
information is missing, or there is too much info for the item) are ignored.
The input file can contain multiple projects. Each project should have one or more user stories. To help with processing the information, we recommend the
following breakdown of work:
i Create a String object and read the whole file into the String object, line by line. You’ll need to add in \n characters at the end of each line since those are used
as delimiters when reading in line by line.
i To break the line into projects, each of which we will call a project token, use \\r?\\n?[#] as a delimiter. This will break apart the contents by end of line
characters \n and \r and a following # character that represents a project. The first line of the project token is the project name.
i After removing the project name from the project token, you can then use the \\r?\\n?[*] delimiter to break apart the string into user story tokens. The first line
of a user story token is the information about the user story except for the user, action, and value information. The first line is delimited by comma characters.
i A user story token can be broken into the three tokens for user, action, and value using the \\r?\\n?[-] delimiter.
i After breaking down everything, you can create objects (or throw exceptions if there’s a problem) and build up the UserStorys, add them to Projects, and add
the Projects to the list of Projects for return to the caller. Where possible, delegate error checking to the UserStory and Project methods that would be most
appropriate.
When working through this implementation, we recommend utilizing print statements to see what is happening in the file. First, try to break file contents into
projects. Then break projects into user stories. Finally, start creating user stories and projects from the smallest tokens. The String.trim() method will help remove
leading and trailing whitespace. The leading #, *, and - characters should be removed before adding any of the strings to objects. The String.substring() method
will be helpful for that.
ProjectWriter
ProjectWriter has one public method writeProjectToFile that receives a String with the file name to write to and a Project to write to file. ProjectWriter should use
UserStory’s toString() method to create the properly formatted output for a UserStory. If there are any errors or exceptions, an IllegalArgumentException is
thrown with the message “Unable to save file.”
[UC3] has been updated so that only the current project is written to the file instead of all the open projects.
Package edu.ncsu.csc216.project_manager.model.manager
ProjectManager
Separation of Project from ProjectManager means each class can have a very specific abstraction: Project represents a single project and its list of UserStorys and
ProjectManager controls

联系我们 - QQ: 99515681 微信:codinghelp
程序辅导网!