0% found this document useful (0 votes)
129 views15 pages

Seminar 4. Seema

This document summarizes an object-oriented design seminar focused on exception handling and design patterns. The key points covered include: - The seminar aimed to implement exception handling and design patterns to create robust, maintainable code. - Design patterns and exception handling contribute to software quality and help make programs more scalable and easier to maintain. - Exceptions represent errors that can occur, and properly handling exceptions prevents crashes and unexpected behavior. - The document outlines best practices for exception handling like using checked and unchecked exceptions appropriately, including context in exception objects, and handling exceptions at the right abstraction level. - Maintaining object state when exceptions are thrown, avoiding empty catch blocks, and unit testing exception

Uploaded by

Seema Bashir
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
129 views15 pages

Seminar 4. Seema

This document summarizes an object-oriented design seminar focused on exception handling and design patterns. The key points covered include: - The seminar aimed to implement exception handling and design patterns to create robust, maintainable code. - Design patterns and exception handling contribute to software quality and help make programs more scalable and easier to maintain. - Exceptions represent errors that can occur, and properly handling exceptions prevents crashes and unexpected behavior. - The document outlines best practices for exception handling like using checked and unchecked exceptions appropriately, including context in exception objects, and handling exceptions at the right abstraction level. - Maintaining object state when exceptions are thrown, avoiding empty catch blocks, and unit testing exception

Uploaded by

Seema Bashir
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 15

Seminar 4

Object-Oriented Design, IV1350

Seema Fatima Bashir

[email protected]

22/5-2023
Introduction

I have collaborated with Razan Yakoub and Esra Salman to devise a solution for this seminar
and present it jointly. The primary objective of seminar 4 was to implement the use of
exception handling as well as use design patterns.

The intended learning outcomes for seminar 4 consisted of developing an object-oriented


program which specifically applies and implements establisxshed guidelines for object-
oriented architecture, design, and programming. One key aspect of assessing the quality of a
program is evaluating its adherence to these established guidelines. Object-oriented
architecture and design principles provide a structured approach to software development,
enabling modular, reusable, and maintainable code. By following these guidelines,
developers can create programs that are more robust, scalable, and easier to understand.

These guidelines emphasize concepts such as encapsulation, inheritance, and polymorphism,


which promote code reusability, modularity, and extensibility. Additionally, design patterns
further enhance the quality of object-oriented programs. By incorporating these established
guidelines into the development process, developers can ensure that their programs meet
industry standards and best practices, resulting in software that is efficient, reliable, and easy
to maintain.

To prepare for this seminar students were required to read chapters 8 and 9 from of the
provided course literature, "A First Course in Object-Oriented Development," and attend
lectures on module 4, which covered the fundamentals of implementation, exception handling
as well as the usage of design patterns.

Design patterns and exception handling are crucial aspects of software development that
contribute to the overall quality and maintainability of a program. Design patterns provide
proven solutions to common design problems, promoting code reusability, modularity, and
extensibility. By utilizing design patterns, developers can benefit from established best
practices and reduce the chances of introducing design flaws or anti-patterns into their
codebase. This leads to cleaner, more maintainable code that is easier to understand and
modify.

2
Additionally, exception handling is another essential aspect of coding to create robust and
error-tolerant software. Exceptions are unexpected events or errors that can occur during
program execution. Properly handling exceptions allows developers to gracefully handle and
recover from errors, preventing crashes and unexpected behaviour. By catching and handling
exceptions, developers can provide informative error messages or take appropriate actions to
handle exceptional conditions, ensuring that the program remains stable and reliable even in
the face of unforeseen circumstances. Effective exception handling also enhances the overall
user experience by providing meaningful feedback when errors occur, aiding in debugging
and troubleshooting.

3
Method

To prepare for this seminar, extensive preparation was undertaken, which involved a
comprehensive review of the course literature and lectures from Module 4 (Exceptions and
Design patterns). Specifically, Chapter 8 and 9 in "A First Course in Object Oriented
Development" were thoroughly examined to gain a better understanding of the concepts
involved.

The focus of this seminar is the ability to learn how to handle failures. Ensuring
comprehensive error handling is a fundamental aspect of developing a complete program. It
involves addressing all possible failures and handling them appropriately. Some failures can
be resolved, allowing the program to continue functioning despite exceptional conditions. In
other cases, it may only be possible to report the failure without further resolution.
Regardless, it is crucial to avoid undefined outcomes for system operations.

Exceptions represent abnormal situations that disrupt the normal program execution. For
instance, if a method requires a server connection to fulfil its task but fails to establish one, it
must promptly return to the caller, signalling the occurrence of the abnormal situation -
inability to connect to the server. The caller must then switch to error handling since it did not
receive the expected result. Exception handling simplifies this scenario by allowing the use of
exceptions instead of complex if statements to check for error codes when reporting failures
via return values. By utilizing exceptions, code flexibility and understandability are
improved, making error handling more efficient and manageable within the program.

The use of exceptions in the code for error handling a is a best practice that should always be
followed when the programming language such as java supports it. It should be noted that
reporting errors through return values can lead to confusion and difficulty in finding
appropriate error codes. Exceptions, on the other hand, allows for specific error information
to be associated with the exception, providing more context. With exceptions, error handling
is consolidated in the catch block, separate from the main program flow in the try block.

Additionally, for error handling in your method, it is important to determine whether to use
checked or unchecked exceptions. Checked exceptions are suitable for business logic errors,
where a specific rule is broken but the program hasn't crashed. An example is when a user

4
attempts to withdraw more money than their account balance. On the other hand, unchecked
exceptions are used for programming errors, such as NullPointerException, indicating a bug
in the program.

These exceptions should ideally be minimized except during development and testing. There
is a third category of errors that halt the program's task but cannot be eliminated during
development, like when the program needs to call an unresponsive server. In such cases, it is
common to use unchecked exceptions to avoid cluttering the code with catch blocks that only
report the error.

In order to facilitate debugging and error message generation, it is important to include


information about the error condition in the exception object. Exception objects, being
regular objects, can have fields storing any relevant information. Two types of information
should be included: the data that describes the exceptional condition and an error message.
The error message is not intended for end users but rather for developers or administrators
seeking to understand the issue.

Furthermore, it is also essential to use the appropriate abstraction level for exceptions in a
method. For instance, if a low-level layer throws an exception with detailed technical
information about an error condition, it should not be displayed to the user. Displaying such
technical details would not be user-friendly and could potentially create security
vulnerabilities if exposed to all users, including attackers. Additionally, catching a database
exception in the view layer creates an undesired dependency between the view and the
integration layer. Therefore, it is often more suitable to catch the specific exception in the
lower layer and throw a more generic exception. This approach prevents exceptions from
traversing multiple layers and provides a better separation of concerns.

Another important aspect to consider in the case of exceptions is to ensure that an object
remains in a consistent state even if it throws an exception. To maintain object usability, it is
crucial to clearly define and preserve the state of the object, including the values of its data
elements. When a method throws an exception, it indicates a failure in performing its task.
Therefore, the object should revert to its state prior to the method call, and no field should
change its value when an exception is thrown. Several strategies can be employed to achieve
this, with the preferred approach being chosen in the following order.

5
It should also be noted that writing an empty catch block is highly discouraged as it ignores
exceptions entirely, which is rarely beneficial. If an exception occurs within a try block,
execution proceeds to the empty catch block where nothing happens. Subsequently, execution
continues as if no exception had been thrown, leading to a lack of notification about the
exception and making it challenging to comprehend the program's behavior. In the case
study, the exceptions are caught in the view layer, which simulates user interaction. Although
the view is not fully implemented, error handling can be incorporated in the simulation. It is
crucial to ensure that the catch blocks are not empty, and the actions taken within them
should consider providing information to both users and developers/administrators.

To ensure a user-friendly experience, the user interface should accurately represent the
system's state and provide clear indications of any unsuccessful operations. When displaying
error messages, it is crucial to strike a balance between providing necessary information
without overwhelming the user with technical details. Consistency in message format and
meaning across the system is essential to avoid confusion. To achieve this, it is recommended
to have a single component responsible for generating error messages, promoting cohesion
and encapsulation. This error message component is typically placed within the view layer, as
error messages are part of the user interface. By consolidating error handling code and
encapsulating user interface handling in this component, a more effective and cohesive
design can be achieved.

Unit tests for exception handling are also an essential to ensure robustness. These tests should
cover scenarios where exceptions should and should not be thrown, validate exception
messages and content, and confirm proper handling in catch blocks. These tests enhance
software reliability and correctness.

An additional part of seminar 4 is handling design patterns. These concepts of polymorphism


and inheritance are introduced to enhance design solutions, building upon the fundamental
principles of coupling, cohesion, and encapsulation. Polymorphism and inheritance serve as
powerful tools, but their value lies in how effectively they align with the criteria of coupling,
cohesion, and encapsulation. Ultimately, the quality of more advanced designs relies on
meeting these criteria to a greater extent.

6
In order to design polymorphism and inheritance, it is nec- essary to model interfaces,
implementations. Polymorphism refers to the ability of an object to take on different forms or
have multiple implementations while adhering to a common interface. This concept is
valuable in software design as it allows for flexibility and extensibility. By defining a shared
interface, specific implementations can vary in their behavior while still providing the same
set of methods or functionalities. This means that objects can be used interchangeably based
on their common interface, promoting code reuse and modular design. Polymorphism
enhances the overall maintainability and scalability of a software system by enabling the
introduction of new implementations without impacting existing code that relies on the
shared interface.

7
Results
The following link displays the GitHub project for this seminar:

https://github.com/RazanYakoub01/IV1350_Seminar_4.git

Figure 3.1: Exception class representing the ItemNotFoundException exception.

The figure above defines a checked exception class called ItemNotFoundException which extends the
Exception class. It is used to indicate that an item is not found in the inventory catalog. The exception
provides a specific message explaining the situation when it is thrown. By extending Exception,
ItemNotFoundException becomes a checked exception that needs to be handled explicitly in the
calling code.

Figure 3.2: add Item class in the contructor used to catch exceptions: SQLException and
ItemNotFoundException

8
The addItem method throws two checked exceptions and catches two specific exceptions. It
throws InvalidItemIdentifierException and DatabaseConnectionException in its method
signature, indicating that these exceptions can occur during its execution. Within the method,
it catches SQLException and ItemNotFoundException using separate catch blocks.

If a SQLException occurs while calling findItemInformation, it throws a


DatabaseConnectionException. Similarly, if an ItemNotFoundException is caught, it throws
an InvalidItemIdentifierException. These catch blocks handle specific exceptions and rethrow
them as different exceptions, allowing the calling code to handle them appropriately.

Figure 3.3: The error log file presented to developers .

The text log file displays the error incase there has been a failure to connect to the data base.
The error message in the figure states that there is problem connecting to the data base
refering to the DataBaseConnectionException.

Figure 3.4: The unit tests conducted for SQLException and the ItemNotFoundException

9
The tests in figure above ensure that the findItemInformation method behaves correctly under
different conditions and exceptions, helping to validate the functionality of the method in a
controlled testing environment. Additionally, in the validItemIdentifier test method, an
expected item with specific attributes is created. The findItemInformation method is called
with a valid item identifier, and the returned item is compared with the expected item using
the assertEquals assertion. If the expected and returned items do not match, an assertion
failure message is provided.

The getNullItem test method verifies the behavior when the findItemInformation method is
called with an item identifier that is not found in the inventory. If the expected exception is
not thrown, an assertion failure message is displayed. Similarly, the getDatabaseFailure test
method checks the behavior when a database failure occurs during the findItemInformation
method. It uses the assertThrows assertion to verify if a SQLException is thrown. If the
expected exception is not thrown, an assertion failure message is shown.

Figure 3.5: The observer- log text file representing the total revenue for all sales.

The observer text file in the figure above shows the total revenue for all the sales a t specific time.
This is part of a behavior patten in which the object, payment register is updated. The text file notifies
observes whenever changes are made.

10
Figure 3.6: The view output seen by the user.

The figure above displays the output of view seen by the user. Hence the information is correlated to
what the cashier needs to be does, performs, and needs to be informed about. First a sales process is
described. It begins with the initiation of a new sale and the entry of item information. Several items
are scanned, each identified by its name, price, and VAT.

It also displays an error occurring when attempting to find an item with the identifier 12345,
indicating that it is not found in the system. Additionally, it also shows the failure of an item
information retrieval for the item with the identifier 190501 due to a server being offline.

The cashier is then prompted to choose a payment method and enter the amount paid. Once
completed, a receipt is printed. Finally, the total revenue for all sales up to a specific date and time is
reported as 6780.8 SEK. This summary captures the sequence of actions, error occurrences, payment
processing, and the resulting revenue.

Figure 3.7: The external Inventory system is implemented as a singleton object.

11
The code above implements the Singleton design pattern for the ExternalInventorySystem
class. It ensures that only one instance of the class can be created and provides a global point
of access to that instance.The class has a private static variable instance that holds the
singleton instance. The constructor is made private, preventing instantiation of the class from
outside its scope.

The getInstance() method is used to retrieve the singleton instance. It is declared as


synchronized to ensure thread-safety in a multi-threaded environment. If the instance variable
is null, meaning the singleton instance has not been created yet, a new instance is created and
assigned to instance. Finally, the instance is returned. By using this approach, the
ExternalInventorySystem class ensures that only one instance is created throughout the
program's execution, and it provides a way to access that instance globally.

12
Discussion
For seminar four we have chosen to implement checked exceptions. An example of this is
seen in Figure 3.1, which defines an exception called ItemNotFoundException which extends
the base class called Exception. This exception intends to be used when an item is not found
in the inventory catalogue. Checked exceptions are usually used for business logic errors.
Consequently, the ItemNotFoundException is considered a checked exception as it indicates
a business rule violation. It signifies that the requested item is not present in the inventory
system catalog, which a special condition that the program must handle.

By extending the Exception class, ItemNotFoundException becomes a checked exception. It


should be noted that checked exceptions must be explicitly declared in the method signature
or handled using a try-catch block when the method that throws the exception is called. This
is displayed in figure 3.2, where the ItemNotFoundException is caught in the controller.

Additionally, figure 3.2 also shows that another two exceptions are thrown in the controller.
These include DatabaseConnectionException aswell as an InvalidItemIdentifierException,
these two exceptions are caught using a try catch block in the view class. This is done in
order to notify the user. In this case the user would be notified with messages regarding a
certain item identifier and that it cannot be found. We believe this message is important for
the cashier so that he or she is immeadietly notified that there is something wrong with the
item identifier on the package or simply that the item does not belong to the store.

The exception class displayed in figure 3.1 along with the remaining classes handling
exceptions have names specifying the error condition. An example of this is the name of one
of the exception classes created for this seminar, which is InvalidItemIdentifier. This
exception class elaborates what has gone wrong aswell as why it was thrown. Moreover, the
exception classes also include the information about the error condition. Figure 3.1 displays,
an error message which reads “ The requested item is not found in the inventory catalogue”.
This message is useful for both debugging purposed and for generating error messages, that
an object catching an exception can get the information about the case of the error.

Furthermore, all exceptions automatically have inherited the functionalities provided in


Java.lang.Exception. All of the exception classes in the project handle error messages aswell

13
have corresponding contructors for those classes. It should also be noted that the exception
classes along with the rest of the classes in the project have java doc comments, stating
parameters and elaborating on the public methods.

Another important aspect of exceptions is notifying the developer in case of bugs. Figure 3.3
displays the exception stack traces printed to the log, in a text file. The text file displayed in
the figure holds a more detailed report about the exception than that which is shown to the
user. In the log file, we have chosen to log the DatabaseConnectionException as it will report
that there has been a failure to connect to the data base, which signifies that the program isn’t
working as indented. Thus, a big interest to the developers or the IT staff. It should also be
noted that we have not logged the InvalidItemIdentifier, as this exception handles input data.
We believe that the input data had no significant effect on the logic itself. Hence only the user
is notified in this case.

During our seminar, we focused on testing exception handling in our classes to ensure that
exceptions were only thrown when intended and not during successful execution. To achieve
this, we designed specific test scenarios to cover different cases where exceptions were
expected. Figure 3.4 illustrates the testing of the findItemInformation method in the
ExternalInventorySystem class using three methods to ensure comprehensive coverage.

In the first case, we created a predefined element that would trigger a SQLException,
allowing us to test the system's behavior when encountering a database failure. By simulating
this scenario, we verified that the exception was appropriately thrown and handled.

The second case involved a hardcoded list of items, and we designed a test to check if the
system would throw an ItemNotFoundException when an input item identifier was not
present in the list. This test confirmed that the exception was correctly thrown when
attempting to retrieve information for a non-existent item.

By implementing distinct test methods for each exception-throwing scenario, we aimed to


thoroughly validate the exception handling functionality of our system. The tests covered
successful execution as well as expected exceptions, ensuring the robustness and reliability of
our exception handling mechanism.

14
Moving on to the implementation of design patterns, we incorporated the Observer,
Singleton, and Strategy patterns. In the PaymentRegister class, we utilized the observer
pattern to notify observers of changes in the total revenue. The observed object,
PaymentRegister, calls the updateTotalRevenue method on the observers, TotalRevenueView
and TotalRevenueFileOutput, passing the current revenue as an argument. This decoupling
between the observed object and observers promotes flexibility and loose coupling.

For the Singleton pattern, we applied it to the ExternalInventorySystem class, ensuring that
only one instance of the class has access to the item catalog database. This approach enhances
security, integrity, and system efficiency by centralizing access and eliminating conflicts or
inconsistencies that multiple instances could introduce.

Lastly, we successfully employed the Strategy pattern to handle discount calculations. By


encapsulating each calculation algorithm in separate strategy classes
(CustomerDiscountStrategy, ItemDiscountStrategy, SaleAmountDiscountStrategy) and
relying on the DiscountStrategy interface, we achieved modular, flexible, and extensible
discount calculation logic. This pattern allows the system to dynamically handle different
discount strategies at runtime.

In summary, our solution incorporates the Observer, Singleton, and Strategy patterns
effectively, providing robust exception handling, decoupled observation of revenue changes,
centralized access to the item catalog, and flexible discount calculation strategies.

15

You might also like