COSC1284 Programming Techniques Semester 2 Assignment 2

Assignment Objective

This assignment requires you to implement a “Library Management System (LMS)”.

(Note that the requirements and constraints described below are intentionally simplistic/artificial, being designed to provide a suitably sized assignment, and assess your understanding of various aspects of (good) object oriented programming. )

Specifically, the emphasis of this assessment is on adhering to a specification rather than developing a complete commercial grade library management product with realistic business rules.

The method signatures have been provided and must be implemented exactly as below. This will allow appropriate interfaces to be added to the program at a later stage and ensure that any test classes written to test your application will work correctly.

What you need to do

Your task is to write a simple “Library Management System (LMS)” as specified in this document.

Your design will consist of a collection of interacting classes/interfaces to store information about:

  1. The library and its collection
  2. The holdings contained in the library collection
  3. The members who can borrow/return available holdings

The system will need to be modelled as a number of object oriented classes/interfaces. The main classes involved in the system, and their behaviours, are detailed below.

  1. Your first task should be to download the startup project from Blackboard.
  2. Import it into Eclipse.
  3. Rename it to: [your_student_number]_A2

Any questions regarding this assignment or any of the requirements discussed in the specification should be directed to the assignment 2 forum in blackboard.

Part A – Write the class hierarchies indicated below to satisfy the functional requirements (5 marks)

For this part of the assignment you must design and implement the class heirarchies for both the holdings and the members.

You must also write a class that contains sample code for testing your class heirarchies are working correctly.

It is important the you complete this part of the assignment before moving onto Parts B & C.

You should not start implementing the menu system until you have completed and fully tested your classes.

The functional requirements for the two class heirarchies are specified below.

Holding - Functional Requirements

The system needs to cater for two distinct types of Holdings: Books and Videos. You should create an Abstract class called ‘Holding’ and two sub-classes called ‘Book’, and ‘Video’. Additional types of holding may be added later with each type of holding having a unique calculation of late fees.

Each holding has a:

  • A unique seven-digit alpha-numeric code prefixed with ‘b’ for a book and ‘v’ for a video (e.g. b000010 or v000010);
  • title (e.g. “Introduction to Java Programming”) which must be at least one character in length and cannot be set to null;
  • predefined loan fee ($ value);
  • maximum loan period (defined in terms of the number of days);
  • late penalty fee ($ value) calculated on a per late day basis.
  • an attribute which indicates if the holding has been made ‘inactive’ i.e. temporarily removed from the system.
  • A holding may be made ‘inactive’ essentially preventing the item from being borrowed. The conditions that make a holding inactive are:
  • If a holding is in an invalid state such as having an invalid ID or title, it should be marked as ‘inactive’.
  • If a holding is damaged, then the administrator of the system can mark the item as ‘inactive’ until the item can be repaired and placed back on the shelves.
  • A holding should not be allowed to have its status changed to inactive, if it is currently on loan.

Books:

  • Books have a fixed standard loan fee of $10, and a fixed maximum loan period of 28 days.
  • Books: late fee = number of late days x fixed daily rate of $2. e.g. if a given book was returned 3 days late, the late fee will be $6 (3 days x $2).

Videos:

  • Videos have a variable loan fee of either $4 or $6.50 (determined at the time the item is created in the system, and a fixed maximum loan period of 7 days.
  • Videos: late fee = number of late days x 50% of the standard loan fee. e.g. if a given video with a standard loan fee of $6.50 was returned 3 days late, the late fee will be $9.75 (3 days x 50% of $6.50).
  • Videos should also have an attribute indicating the running time of the movie.

The specifications for the holding classesare specified below.

Attributes

You should use appropriate variables and constants. You will need to decide where in the hierarchy these attributes belong, what are the most appropriate data types and scope for these attributes.

Getters and or Setters should not be written arbitrarily for all variables. Only write a getter and/or setter if you use it within your program.

NOTE: The DateTime class provided has multiple constructors to create a date based on the current date, a date specified by day, month, and year, and a date based on the number of days from the current date.

These constructors enable the creation of a specific date without having to change the system clock or having to wait for the specified number of days before fines are incurred.

DateTime todaysDate = new DateTime();

DateTime nextWeeksDate = new DateTime(7);

DateTime specificDate = new DateTime(14, 4, 2016);

This method will return the number of days between two dates.

todaysDate.diffDays(nextWeeksDate);

To get a date formatted in the Australian date format you can call the following method:

todaysDate.getFormattedDate();

Constructors

The constructor for the holding class must take the following arguments ‘holdingId’ and ‘title’.

public Holding(String holdingId, String title)

public Book(String holdingId, String title, int numPages)

public Video(String holdingId, String title, double loanFee, double runningTime)

Methods

The classes should have appropriate getters, setters and other methods to represent the functions as specified in the functional requirements section.

The method signatures have been provided and must be implemented exactly as below. This will allow appropriate interfaces to be added to the program at a later stage and ensure that any test classes written to test your application will work correctly.

You also need to consider which of the methods below should be abstract methods and modify your implementation accordingly.

Additional methods may be used if required but attention must be paid to ensure proper use of scope, return types and parameters. You should also ensure that you are not duplicating the functions already present as detailed below.

public double calculateLateFee(DateTime dateReturned)

The method can be used to calculate the late fee as part of the returning process, but it can also be used by the user of the system to find out what the late fee will be if returned on the specified date. The specific calculation will depend on the type of holding please see the functional requirements above. Note: the calcuation must be performed at the time this method is called (i.e polymorphically), you should not modify the value of the underlying attributes at the time of contructing the object to meet this requirement. Also note that it must return a double, so if no late fee will be applied, it should return zero.

public boolean borrowHolding()

A holding can only be borrowed if:

  • it is currently active in the system
  • it is not already on loan

If an item is borrowed, then it must have it’s borrowDate set to the current date

public boolean returnHolding(DateTime dateReturned)

A holding can only be returned if:

  • it is currently active in the system
  • it is already on loan
  • the return date is on or after the date on which the item was borrowed

If an item is returned, then it must have it’s borrowDate set to null

public String print()

The print method should return a string that represents the current state of the object in a user friendly format designed for display on the console. This method should not ‘do’ the actual printing, but give the data back to the calling method. The Menu will be responsible for printing it to the console.

Example String Output:

Book

Not on loan: ID:

Title:

Number of Pages: Loan Fee:

Max Loan Period:

On Loan:

System Status:

b000001

The Lion King

248

10.0 28

No

Active

On loan: ID:

Title:

Number of Pages: Loan Fee:

Max Loan Period:

On Loan:

Date of Loan:

b000001

The Lion King

248

10.0 28

Yes

23/08/2016

System Status:

Active

Video

Not on loan:

ID:

Title:

Running Time:

Loan Fee:

Max Loan Period:

On Loan:

System Status:

v000001

Intro to Java

1.37

6.5

7 No

Active

On loan:

ID:

Title:

Running Time:

Loan Fee:

Max Loan Period:

On Loan:

Date of Loan:

v000001

Intro to Java

1.37

6.5

7

Yes

23/08/2016

System Status:

Active

public String toString()

The Holding classes should override the toString() method to provide a pre-determined string representation of the holding. The format for the holding representation separates each attribute via the use of a colon ‘:’. This method will be used later when implementing your file reading and writing operations.

Book id:title:number_of_pages:loan_date:standard_loan_fee:max_loan_period:active

Video

id:title:runningTime:loan_date:standard_loan_fee:max_loan_period:active

e.g. b000001:Intro to Java Programming:248:12/09/2016:10:28:active v000001:Intro to Java Programming:1.37:null:4:7:active

public boolean activate()

public boolean deactivate()

Member - Functional Requirements

The system needs to cater for two distinct types of Members: Standard and Premium. These members can borrow and return holdings. You should create an Abstract class called ‘Member’ and two sub-classes called ‘StandardMember’, and ‘PremiumMember’.

The member has:

  • a unique seven-digit alpha-numeric code prefixed with ‘s’ for a standard member and ‘p’ for a premium member (e.g. s000010 or p000010);
  • full name (e.g. “John Smith”) which must be at least one character in length
  • maximum borrowing credit ($ value) which is predefined according to the specific membership type
  • Each member should have their credit set to the maximum available credit limit for that type of member when the member is created.
  • collection of currently borrowed holdings
  • Standard members have a fixed maximum borrowing credit of $30
  • Premium members have a fixed maximum borrowing credit of $45.
  • The holding’s standard loan fee should be deducted from member’s borrowing credit at the time he/she borrows a holding.
  • The member must have sufficient credit available to borrow a given holding.
  • The holding return procedure differs based on a specific member type:
  • Standard members are not allowed to return a (late) book if their current balance will become negative after paying the late penalty fee. In such cases, the current credit of a member should first be restored to the initial maximum value.
  • Premium members can return a holding even if this will result in a negative current balance. However, they won’t be able to borrow any new holdings until their current credit is restored to a positive value.

The requirements for the member classesare specified below.

Attributes

You are should use appropriate variables and constants. You will need to decide where in the hierarchy these attributes belong, what are the most appropriate data types and scope for these attributes.

Constructors

The constructor for the Member class must take the following arguments ‘memberId’, ‘fullName’ and

‘credit’.

public Member(String memberID, String fullName, int credit)

public StandardMember(String standardMemberId, String standardMemberName)

public PremiumMember(String premimumMemberId, String premiumMemberName)

Methods

The classes should have appropriate getters, setters and other methods to represent the functions as specified in the functional requirements section.

The method signatures have been provided and must be implemented exactly as below. This will allow appropriate interfaces to be added to the program at a later stage and ensure that any test classes written to test your application will work correctly.

You also need to consider which of the methods below should be abstract methods and modify your implementation accordingly.

Additional methods may be used if required but attention must be paid to ensure proper use of scope, return types and parameters. You should also ensure that you are not duplicating the functions already present as detailed below.

public boolean borrowHolding(Holding holding)

A member can only be borrow a holding if:

  • They are currently active in the system
  • They have enough credit to pay the initial loan fee

public boolean returnHolding(Holding holding, DateTime returnDate)

The conditions for returning a holding are different depending on the type of member, please see the functional requirements section above.

public boolean resetCredit()

This is just a convienience method that will set the member’s credit back to its maximumValue.

public boolean deactivate()

This allows you to set a flag that inidicates that the member should be made inactive in the system. This flag is used when implementing some of the business rules.

public boolean activate()

This allows you to set a flag that inidicates that the member should be made active again in the system.

public String print()

This method should return a string that can be printed by the ‘client’ (your menu system) that represents the current state of the member including the holdings they currently have onloan. This should be displayed in a ‘human friendly’ format such as the example below.

Member

ID: s000001

Title: Simba

Remaining Credit: 30.0

One Item on Loan:

ID: s000001

Title: Simba

Remaining Credit: 20.0 Current holdings on loan:

b000001

Two or more items on loan:

ID: s000001

Title: Simba

Remaining Credit: 13.5 Current holdings on loan:

b000001:v000001

public String toString()

The member class and its sub-classes should override the toString() method to provide a pre-determined string representation of the member. The format for the member representation separates each attribute via the use of a colon ‘:’.

The basic output of this method may be modified (i.e. add additional attributes) to facilitate maintaining state when writing and reading to text files.

member_id:full_name:remaining_credit e.g. p00001:Joe Bloggs:25

Part B – Write a menu driven program to demonstrate and test the classes you have implemented in the previous section. (5 marks)

You are required to implement a simple application which tests the functionality of the Holding and Member class hierarchies you have just developed. This application should demonstrate the processes of creating, manipulating and displaying the details of a collection of Holding and Member objects according to the requirements set out below.

IMPORTANT: A ‘façade’ class has been provided in your startup project. Your menu system must only have a reference to this class and should only make calls to this class. The Menu system should not directly access the main classes in your system such as the class heirarchies that you created in Part A of the assignment.

The ‘façade’ should have a reference to a Library class that is responsible for managing the collections of members and holdings. Note: The diagram below is a basic representation, you will have several classes in your system, not shown in the diagram, this is intended to get you started.

COSC1284 Programming Techniques Semester 2 Assignment 2 Image 1

Write a menu driven program to perform the operations outlined below.

The Menu should handle all the input/output. It then gives the information to the façade that passes it to the Library. Any response is passed from the Library, back to the façade that gives it to the menu for display.

You may modify your menu as you see fit by adding / removing menu items, provided that the system allows you to perform all of the functions below. If you choose to modify the menu system you should make sure that it is user friendly and intutitive and does not unnecessarily prompt the user for input.

COSC1284 Programming Techniques Semester 2 Assignment 2 Image 2
  • Declare two arrays named holdings and members that can store the references for up to 15 objects each. This should be done in your Library class.
  • Create the 8 Holding objects and 4 Member objects shown at the bottom of this section to automatically populate the library when the program starts so there is sample data for testing.
  • Additionally, allow the user of the program to add additional holdings and members at runtime. If the maximum number (15) of holdings or members is exceeded, a message should be displayed indicating that the operation cannot be performed.
  • Store references to these objects in their respective arrays (remember this should be done in your ‘Library’ class
  • Allow a user to perform both borrowing and return operations on any of the Holding objects stored in the array. Based on the returned value of these methods give appropriate feedback on the success or failure of operation.

For example when a book is borrowed you should display something like:

Your current balance is now: 20.0

You successfully borrowed:

ID: b000001

Title: The Lion King

Number of Pages: 248

Loan Fee: 10.0

Max Loan Period: 28

On Loan: Yes

Date of Loan: 24/08/2016

System Status: Active

Press any key to return to the menu

For example when a video is returned display any fine incurred.

You incurred a late penalty of :9.75 You current balance is now: 3.75

You successfully returned:

ID: v000001

Title: The Lion King

Running Time: 1.37

Loan Fee: 6.5

Max Loan Period: 7

On Loan: No

System Status: Active

Press any key to return to the menu

  • Display the current state of the objects stored in each of the arrays.
  • Allow the user to search for an object by providing an ‘ID’ at runtime and print only that object. If

the ‘ID’ supplied does not exist in the collection, the user should be informed and re-prompted to enter a valid ‘ID’. They should also be able to type ‘exit’ or ‘e’ to cancel the operation if they choose.

  • Allow user to borrow and return books repeatedly through the use of a loop. The loop should be repeated, as long as a user responds positively to the prompt, “Any more transactions?”
  • Add an Interface to your program called ‘SystemOperations’. This should contain two methods:

public boolean activate();

public boolean deactivate();

You should then have both your class hierarchies implement this interface. Write a single method in your main program (for each of the methods in your interface) that you can call which is able to take objects from either hierarchy as a parameter.

You will need to add this function to your menu.

Holding Sample Data (for pre-loading your system):

ID:

Title:

Number of Pages: Loan Fee:

Max Loan Period:

On Loan:

System Status:

ID:

Title:

Number of Pages: Loan Fee:

Max Loan Period:

On Loan:

System Status:

ID:

Title:

Number of Pages: Loan Fee:

Max Loan Period:

On Loan:

System Status:

ID:

Title:

Number of Pages: Loan Fee:

Max Loan Period:

On Loan:

System Status:

b000001

Intro to Java

200

10.0

28

Yes Active

b000002

Learning UML

124

10.0

28

No

Active

b000003

Design Patterns

345

10.0

28

No

Active

b000004

Advanced Java

287

10.0

28

No

Active

ID: v000001

Running Time: 1.37

Title: Java 1

Loan Fee: 4

Max Loan Period: 7

On Loan: No

System Status: Active

ID: v000002

Title: Java 2

Running Time: 1.28

Loan Fee:6.50

Max Loan Period: 7

On Loan: No

System Status: Active

ID: v000003

Title: UML 1

Running Time: 1.47

Loan Fee: 6.50

Max Loan Period: 7

On Loan: No

System Status: Active

ID: v000004

Title: UML 2

Running Time: 1.12

Loan Fee: 4 Max Loan Period: 7

On Loan: No

System Status: Active

Member Sample Data (for pre-loading your system):

ID:

Title:

Remaining Credit:

ID:

Title:

Remaining Credit:

s000001 Joe Bloggs 30

p000001 Fred Bloggs

45

ID:

Title:

Remaining Credit:

ID:

Title:

Remaining Credit:

s000002 Jane Smith 30

p00002 Fred Smith

45

Part C – Add File reading and writing functions to your program. (5 marks)

Finally, extend the application writing all objects (both book and member objects) to the files holdings.txt and members.txt.

You will need to add exception handling mechanism as part of your File operations.

When saving your data you should save to two files for each of the holdings and members:

holdings.txt holdings_backup.txt members.txt members_backup.txt

These files should be saved into your project directory using a relative path so it will work on any system when being assessed. Do not hard code the path to a directory on your own hard drive.

Part of your exception handling must include:

If the main data file is not found, it should automatically revert to using the backup file, so that this is handled without the user being aware.

When saving you always need to save to both files. The system will look first for the main file when loading the data, then and only if this file is not found it will restore from the backup file. Upon exiting the system again both files should be saved to the hard drive.

The data saved to the files should enable the full restoration of the state of the object at the time that it was written to the file was written. To restore the link between the which members have which holdings onloan, you can choose to augment the files above or choose to write out a separate file that maps these two together.

Updated (12/09) : for

clarification on persistence

***Important*** and restoration requirement.

You are not permitted to use serialisation for the implementation of the file reading and writing.

You must write your own classes for writing these objects to file on exit, and restoring them on program start up.

Submission Requirements

Your solution must use Java 1.7 or above and be compatible with the environment supplied in the computer laboratories.

You can use your own computers to develop your assignment, but you must make sure that your assignment can be compiled and run on the computers in the RMIT laboratories.

Assessment

The assignment is designed to test multiple competencies required for successful software development. The assessment evaluates all skills required not just the code itself. You will be assessed on your ability to comply with requirements as set out in this document.

The assessment will include competencies in:

  1. Business Requirements: such as adherence to a style guide, documentation of your program and compliance with processes such as submission of your work prior to assessment.
  2. Java Programming: in Java demonstrating a mastery of the language and the accepted conventions for developing applications.
  3. Software Development Lifecycle: practices such as an iterative approach to development that includes thorough testing of your solution.
  4. Algorithm Development: that demonstrates that you have a clear idea of the logic required to complete the necessary tasks.

The code should closely resemble your logical solution as demonstrated in your documented algorithm.