联系方式

  • QQ:99515681
  • 邮箱:99515681@qq.com
  • 工作时间:8:00-23:00
  • 微信:codinghelp

您当前位置:首页 >> Java编程Java编程

日期:2020-10-08 11:45

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 the creation and modification of many Projects.

ProjectManager implements the Singleton design pattern. This means that only one instance of the ProjectManager can ever be created. The Singleton pattern

ensures that all parts of the ProjectManagerGUI are interacting with the same ProjectManager at all times. Note that the ProjectManagerGUI does not have a

global reference (or a field) to ProjectManager. Since ProjectManager is a Singleton, the GUI can access that single instance at any time with a call of

ProjectManager.getInstance() since getInstance() is a static method.

With a singleton, we have a static instance of the class, which is singleton in ProjectManager. This is created via a call to the static method getInstance(), which

returns an instance of ProjectManager. getInstance() will check if the singleton is null. If the singleton is null, then the getInstance() calls the private

ProjectManager() constructor to create the single instance. The singleton instance is always returned; the null check is there to make sure there always is one! If

we want to resetProjectManager(), we can set the singleton to null. Note that resetProjectManager() is protected to restrict where it can be called. It’s intended for

testing.

There are four methods that work with Projects:

i createNewProject(String projectName): Creates a new Project with the given name and adds it to the end of the projects list. The project is then loaded as the

currentProject by calling the loadProject(String projectName) method.

i loadProject(String projectName): Find the Project with the given name in the list, makes it the active or currentProject, and sets the user story id for that project

so that any new UserStorys added to the project are created with the next correct id.

i getProjectName(): Returns the project name for the currentProject. If the currentProject is null, then null is returned.

i getProjectList(): Returns a String array of project names in the order they are listed in the projects list. This is used by the GUI to populate the project drop

down.

ProjectManager works with the files that contain the saved Projects and their UserStorys. Therefore, ProjectManager works closely with the ProjectReader and

ProjectWriter classes in the following methods.

i loadProjectsFromFile(String fileName): Uses the ProjectReader to read the given fileName. The returned list of Projects are added to the projects field. The first

project in the list returned from ProjectReader is made the currentProject.

i saveCurrentProjectToFile(String fileName): If the currentProject is null or if there are no UserStorys in the currentProject an IllegalArgumentException should be

thrown. Otherwise, write the Project to the file using the ProjectWriter class.

ProjectManager also provides information to the GUI through methods like getUserStoriesAsArray() and getUserStoryById(). The getUserStoriesAsArray() method

returns a 2D Object array that is used to populate the UserStoryTableModel (inner class of the ProjectManagerGUI.UserStoryListPanel) with information. The 2D

Object array stores [rows][columns]. The array should have 1 row for every UserStory that you need to return. There should be 4 columns:

i Index 0. UserStory’s id number

i Index 1. UserStory’s state name

i Index 2. UserStory’s title

i Index 3. UserStory’s developer id (or an empty string if there is no current developer assigned)

The other methods in ProjectManager delegate to the Project.

Overall Flow of Control

The sequence diagram shown below models the flow of transition SubmittedA . The assumption is that an Project has already been created or loaded and

populated with at least one UserStory in the SubmittedState. The flow of control in the sequence diagram is similar for other functionality.

Figure 2: Project Manager Sequence Diagram SubmittedA transition

Testing

For Part 2 of this project, you must write unit and integration tests using JUnit AND report the results of running your system (black box) tests from Part 1.

Test Files

We have provided several test files that will be helpful when testing the Project Manager. The README.txt file provides an overview of the file and how it can be

used during testing.

White box testing

Your JUnit tests should follow the same package structure as the classes that they test. You need to create JUnit tests for all of the concrete classes that you

create (even inner classes). At a minimum, you must exercise every method in your solution at least once by your JUnit tests. Start by testing all methods that are

not simple getters, simple setters, or simple constructors for all of the classes that you must write and check that you are covering all methods. If you are not,

write tests to exercise unexecuted methods. You can test the common functionality of an abstract class through a concrete instance of its child.

When testing void methods, you will need to call other methods that do return something to verify that the call made to the void method had the intended effects.

For each method and constructor that throws exceptions, test to make sure that the method does what it is supposed to do and throws an exception when it

should.

Test Quality

During grading, your tests will be inspected for quality. Low quality tests may lead to a global deduction on the project or possibly an academic integrity violation

depending on the situation (e.g., writing junk code to achieve coverage - don’t do this - we look for this). Low quality tests have one or more of the following

characteristics (this is not an exhaustive list):

i Very few asserts (or none at all) in a test method, especially for the calls to the code under test - this is typically done to get high coverage without checking for

anything and is a terrible practice! Don’t do this!

i Test methods that don’t do anything meaningful.

i Exception tests lacking a fail() call in either the try or catch portions of the exception block. One of the paths should fail.

i Test classes that are lacking tests for complex methods in the class under test. You don’t have to have test methods for every getter and setter, but you should

have test methods for the complex functionality.

Coverage

To unlock the teaching staff test cases, 60% statement/line coverage is required for all non-UI classes.

For full credit on the coverage portion of your grade, you must exercise at least 80% of the statements/lines in your non-UI classes. The exception is ProjectWriter,

where statement/line coverage of over 65% will be sufficient due to how the method will likely be implemented. Jenkins will be set up to look at these thresholds

at a global level; however, you should look at the coverage on a per-class level as reported in the console output to ensure you’re meeting the listed thresholds for

grading.

You will likely cover the simple getters, setters, and constructors as part of testing more complex functionality in your system.

We recommend that you try to achieve 100% condition coverage (where every conditional predicate is executed on both the true and false paths for all valid paths

in a method) in most parts of the program.

Testing the State Pattern

Since the concrete *State classes are private inner classes, you will not be able to test them directly. Instead, you will need to update a particular UserStory with a

Command that will cause a change of state (or not) and then check the UserStory’s state and other fields to ensure the values were updated correctly.

If you want to test the id of a UserStory, make sure that you reset the counter to zero at the start of each test BEFORE creating a new UserStory.

Remember that when testing an FSM, you want to test each transition out of each state. That means you must first get to the state (by issuing Commands) and

then test the transition out (by issuing another Command). Then you need to check that the state of the UserStory is correct.

An example test scenario for testing transition VerifyingA would be the following:

1. Create a new UserStory with a title, user, action, and value.

2. Check that newly created UserStory is in Submitted state.

3. Issue an ACCEPT Command with a priority.

4. Check that UserStory is in the Backlog state and has correct priority.

5. Issue a ASSIGN Command with a developer id.

6. Check that UserStory is in the Working state and had correct developer id.

7. Issue a REVIEW Command.

8. Check that story is in Verifying state.

9. Issue a CONFIRM Command.

10. Check that story is in Complete state

You should create similar tests for all the other transitions and then consider different patterns of transition.

Testing the Singleton

The ProjectManager is a singleton class, which means there is only one instance, and once that instance is created, that’s the instance that is used. So if one test

adds Projects to a list, then those Projects will be there for the next test. To make each test atomic so that it can run in isolation (because run order is NOT

guaranteed), you can use the ProjectManager.resetProjectManager() which should set the singleton to null. This will lead to the construction of a new singleton on

the next call to getInstance(). The ProjectManager() constructor will create an empty projects list and a null currentProject.

Black box testing and submission

Use the provided black box test plan template to describe your tests. Each test must be repeatable and specific; all input and expected results values must be

concrete. All inputs required to complete the test must be specified either in the document or the associated test file must be submitted. Remember to provide

instructions for how a tester would set up, start, and run the application for testing (What class from your design contains the main method that starts your

program? What are the command line arguments, if any? What do the input files contain?). The instructions should be described at a level where anyone using

Eclipse could run your tests.

If you are planning for your tests to read from or write to files, you need to provide details about what the files so that the teaching staff could recreate them or

find them quickly in your project. Similar to Part 1 submissions, the test files may be one of the provided test files.

Follow these steps to complete submission of your black box tests:

1. Run your black box tests on your code and report the results in the Actual Results column of your BBTP document.

2. Save the document as a pdf named BBTP_P1P2.pdf.

3. Create a folder named project_docs at the top level in your project and copy the pdf to that folder.

4. Push the folder and contents to your GitHub repository.

Deployment

For this class, deployment means submitting your work for grading. Submitting means pushing your project to NCSU GitHub.

Before considering your work complete, make sure:

1. Your program satisfies the style guidelines.

2. Your program behaves as specified in this document. You should test your code thoroughly. Be sure to know what messages should be displayed for each

major scenario.

3. Your program satisfies the gradesheet. You can estimate your grade from your Jenkins feedback.

4. You generate javadoc documentation on the most recent versions of your project files.

5. In addition to pushing src/ and test/, you should also push any updated project_docs, doc, and test-files folders to GitHub.

Project 1, Part 1: Project Manager

Note

You are expected to complete the project individually. All work must be strictly your own.

Important

The project you push to NCSU GitHub must contain unmodified versions of the files that we provide for you unless stated otherwise by the

instructor.

Access Modifiers

Note: You can modify the names of private variables, parameters, and methods. However, you MUST have the non-private data and methods

(names, return types, parameter types and order) exactly as shown for the teaching staff tests to run. YOU MAY NOT ADD ANY ADDITIONAL

PUBLIC OR PROTECTED CLASSES, METHODS, OR STATES.

Meaningful Commit Messages

The quality of your commit messages for the entire project history will be evaluated for meaning and professionalism as part of the process

points.

Compiling Skeleton & Fully Commented Classes

Fully commented classes and methods on at least a skeleton program are due at least two weeks before the final project deadline to earn the

associated process points. See the deadline for Process Points 1 at the top of this document.

public public enum enum CommandValue CommandValue { BACKLOG, ASSIGN, REVIEW, CONFIRM, REOPEN, REJECT, RESUBMIT }

?JAVA

@Before

public public void setUp() throws throws Exception Exception {

//Reset the counter at the beginning of every test.

UserStory UserStory.setCounter(0);

}

?JAVA

Deadline

The electronic submission deadline is precise. Do not be late. You should count on last minute failures (your failures, ISP failures, or NCSU

failures). Push early and push often!

Project 1, Part 1: Project Manager

Published with GitHub Pages

NC State Home COVID-19 UPDATES RESOURCES search ncsu.edu search


版权所有:留学生编程辅导网 2020 All Rights Reserved 联系方式:QQ:99515681 微信:codinghelp 电子信箱:99515681@qq.com
免责声明:本站部分内容从网络整理而来,只供参考!如有版权问题可联系本站删除。 站长地图

python代写
微信客服:codinghelp