0% found this document useful (0 votes)
17 views8 pages

Object-Oriented Design Patterns Lab 2021

The document contains two problems related to design patterns. Problem 1 asks to implement different shapes (circle, triangle, rectangle) using the factory pattern. It provides the interface and classes to calculate the area of each shape. Problem 2 asks to implement cash withdrawal authorization rules using the chain of responsibility pattern. It defines handlers for cashier, senior officer, and manager and chains them together to process withdrawal requests of different amounts.

Uploaded by

Nïloy Ft Aminul
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)
17 views8 pages

Object-Oriented Design Patterns Lab 2021

The document contains two problems related to design patterns. Problem 1 asks to implement different shapes (circle, triangle, rectangle) using the factory pattern. It provides the interface and classes to calculate the area of each shape. Problem 2 asks to implement cash withdrawal authorization rules using the chain of responsibility pattern. It defines handlers for cashier, senior officer, and manager and chains them together to process withdrawal requests of different amounts.

Uploaded by

Nïloy Ft Aminul
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

IMPERIAL COLLEGE OF ENGINEERING

Affiliated by Rajshahi University college code: 385

Department of CSE

Assignment on:
CSE-4122 (Object Oriented Design and Design Pattern Lab)

Question solves 2021

SUBMITTED To:
Shams Mahmud
Lecturer,
IMPERIAL COLLEGE OF ENGINEERING

SUBMITTED By:

Md: Aminul Haque


Id:1838520119
[Link]. Engineering part 4 Odd Semester
IMPERIAL COLLEGE OF ENGINEERING
University of Rajshahi
Department of Computer Science and Engineering [Link]. (Engg.)
Part-4 Odd Semester Practical Examination-2021
Course: CSE-4122 (Object Oriented Design and Design Pattern Lab)

Problem: 1
Write a program to create various shapes like (Circle, Triangle, Rectangle)and calculate the
area of the shape. You should use Factory Pattern for shape creation so that all shapes can
be created using a single factory object.
Each shape should have their defining properties (For example circle should have radius,
triangle should have length of its three side etc.) and a method named getArea() to calculate
the area of the shape.
When creating a particular shape, you should initialize the shapes property with any default
values (ie. for circle, radius = 1; for rectangle width = 2 and height = 1.5 etc.)

Problem: 2
Suppose we want to withdraw cash from our bank account using check. Bank has the
following business rule for cash withdrawal based on the amount written on check.
d) For Tk. 10,000 only cashier's authorization is sufficient to withdraw money from account.
e) For Tk. 10,000 to 10,00,000 authorization from both cashier and senior officer is needed
f) For Tk 10,00,000 authorization from Senior officer and Manager is mandatory.
Implement this business rule using Chain of Responsibility design pattern.

Special instructions for both problems


All your class/method/variable name should follow proper naming convention.
(ie. Class names should be TitleCased, method and variable name should be camelCased,
and constants (if any) should be UPPERCASED, etc.)
Use meaningful name for all your classes, methods and variables that reflect their purpose.
Your code MUST be indented properly before submit.
Problem 1

// [Link] interface
public interface Shape {
double getArea();
}

// [Link] class
class Circle implements Shape
{
private double radius;

public Circle() {
[Link] = 1.0; // Default radius
}

public Circle(double radius)


{
[Link] = radius;
}

@Override
public double getArea()
{
return [Link] * radius * radius;
}
}

//[Link] class
public class Rectangle implements Shape
{
private double width;
private double height;

public Rectangle()
{
[Link] = 2.0; // Default width
[Link] = 1.5; // Default height
}

public Rectangle(double width, double height)


{
[Link] = width;
[Link] = height;
}

@Override
public double getArea()
{
return width * height;
}
}

//[Link] class
public class Triangle implements Shape {
private double sideA;
private double sideB;
private double sideC;

public Triangle() {
[Link] = 1.0; // Default side lengths
[Link] = 1.0;
[Link] = 1.0;
}

public Triangle(double sideA, double sideB, double sideC) {


[Link] = sideA;
[Link] = sideB;
[Link] = sideC;
}

@Override
public double getArea() {
double s = (sideA + sideB + sideC) / 2;
return [Link](s * (s - sideA) * (s - sideB) * (s - sideC));
}
}

//[Link]
class ShapeFactory {
public static Shape createShape(String shapeType, double... parameters) {
switch ([Link]())
{
case "circle":
if ([Link] == 1) {
return new Circle(parameters[0]);
} else {
return new Circle();
}
case "triangle":
if ([Link] == 3)
{
return new Triangle(parameters[0], parameters[1], parameters[2]);
} else {
return new Triangle();
}
case "rectangle":
if ([Link] == 2) {
return new Rectangle(parameters[0], parameters[1]);
} else {
return new Rectangle();
}
default:
return null;
}
}
}

//[Link]

public class Main


{
public static void main(String[] args)
{
Shape circle = [Link]("circle", 3.0);
Shape triangle = [Link]("triangle", 4.0, 5.0, 6.0);
Shape rectangle = [Link]("rectangle", 2.0, 3.0);

[Link]("Area of Circle: " + [Link]());


[Link]("Area of Triangle: " + [Link]());
[Link]("Area of Rectangle: " + [Link]());
}
}
Problem 2:

// Define the Handler Interface

interface AuthorizationHandler
{
void authorize(int amount);
void setNextHandler(AuthorizationHandler nextHandler);
}

// Create Concrete Handlers

class Cashier implements AuthorizationHandler


{
private AuthorizationHandler nextHandler;

@Override
public void authorize(int amount) {
if (amount <= 10000) {
[Link]("Cashier authorizes the withdrawal.");
} else if (nextHandler != null) {
[Link](amount);
} else
{
[Link]("Authorization denied.");
}
}

@Override
public void setNextHandler(AuthorizationHandler nextHandler)
{
[Link] = nextHandler;
}
}
class SeniorOfficer implements AuthorizationHandler
{
private AuthorizationHandler nextHandler;

@Override
public void authorize(int amount) {
if (amount > 10000 && amount <= 1000000)
{
[Link]("cashier and senior officer authorizes the withdrawal.");
} else if (nextHandler != null)
{
[Link](amount);
} else {
[Link]("Authorization denied.");
}
}

@Override
public void setNextHandler(AuthorizationHandler nextHandler)
{
[Link] = nextHandler;
}
}

class Manager implements AuthorizationHandler {


@Override
public void authorize(int amount) {
if (amount > 1000000) {
[Link]("Senior officer and Manager authorizes the withdrawal.");
} else {
[Link]("Authorization denied.");
}
}

@Override
public void setNextHandler(AuthorizationHandler nextHandler)
{
// Manager is the last handler in the chain .
throw new UnsupportedOperationException("Manager cannot have a next handler.");
}
}
//Base class
public class CashWithdrawal
{
public static void main(String[] args)
{
AuthorizationHandler cashier = new Cashier();
AuthorizationHandler seniorOfficer = new SeniorOfficer();
AuthorizationHandler manager = new Manager();

// Create the chain of responsibility


[Link](seniorOfficer);
[Link](manager);

// Request to withdraw money with different amounts


[Link](10000);
[Link](25000);
[Link](150000);
[Link](5000000);
}
}

Common questions

Powered by AI

The business rule for cash withdrawal is implemented using the Chain of Responsibility pattern, where authorization handlers (Cashier, Senior Officer, Manager) are part of a linked chain, each checking if they can handle the given amount. The Cashier handles amounts up to Tk. 10,000; the Senior Officer handles amounts between Tk. 10,000 and Tk. 1,000,000 with Cashier's co-authorization; and the Manager oversees amounts over Tk. 1,000,000 with Senior Officer's co-authorization. This separation allows for flexible and clear authorization processes based on institutional roles, enabling future modifications without impacting existing logic structure .

The default initialization strategy for shape properties involves setting predefined values for each shape's dimensions. For instance, a Circle is initialized with a default radius of 1.0, while a Rectangle gets a width of 2.0 and a height of 1.5, and a Triangle is initialized with all sides set to 1.0. This approach ensures robustness by providing a valid state for any shape upon creation, avoiding errors linked to uninitialized variables, and allowing developers to verify behaviors before setting custom values .

Using default constructors offers the advantage of quickly creating objects with a stable initial state, which aids in testing and ensures operational robustness when specific parameters are not yet determined. In the context of the shapes example, it allows the creation of shape objects without needing immediate parameter values; however, it risks inadvertently obscuring bugs if default values lead to incorrect assumptions in calculations or tests. Balancing this requires clear documentation and potentially warning log outputs when default values are used .

To integrate a complex geometrical shape, you would first ensure the new shape class implements the `Shape` interface, defining the `getArea` method. Next, update `ShapeFactory`'s `createShape` method with a new case for the complex shape, passing any necessary parameters, or setting defaults. Extensions might include overloading with specific constructors or employing dependency injection for greater complexity in shape creation. This keeps with Factory Pattern principles by preserving single-responsibility and openness for extension .

The code examples adhere to naming conventions where class names are TitleCased (e.g., `ShapeFactory`), methods are camelCased (e.g., `createShape`), and constants are in UPPERCASE (e.g., unspecified). Following these conventions enhances readability and understanding, as developers can quickly identify the purpose and scope of identifiers by name alone. Consistent naming also facilitates code collaboration in teams and reduces the likelihood of bugs related to misinterpreting variable roles .

The Factory Pattern facilitates the creation of different shapes by encapsulating the instantiation logic within a single factory class, thereby promoting code reusability and separation of concerns. In the example, the `ShapeFactory` class uses a static method `createShape`, which takes a shape type as a String and optional parameters (such as radius for a circle, length for a rectangle, etc.). Depending on the shape type provided, the factory instantiates the appropriate shape object (Circle, Triangle, or Rectangle) with relevant constructor parameters, or defaults if none are provided .

The Triangle class defaults to side lengths of 1.0, creating an equilateral triangle. While simple, this choice might not be representative in practical applications needing diverse triangle types. Alternative default values closer to more common triangle proportions (e.g., a right triangle or scalene triangle) could enhance utility by better reflecting real-world scenarios, potentially leading to broader testing coverage and improved initial test outcomes .

The `Shape` interface defines a common contract through the `getArea` method, which all shape classes (Circle, Triangle, Rectangle) implement. This promotes polymorphism by allowing the use of shape objects interchangeably in the application. For instance, the `ShapeFactory` and `Main` classes can operate on any shape object through the `Shape` interface, regardless of the specific implementation. This is beneficial as it reduces code coupling, increases flexibility, and simplifies the introduction of new shapes without altering client code .

The Chain of Responsibility pattern effectively supports the dynamic validation of authorization rules by separating concerns among different roles (Cashier, Senior Officer, Manager) and allowing them to decide on handling requests based on their authority levels. Each handler in the chain either processes the request (if conditions are met) or passes it along to the next handler. However, to improve, adding a logging mechanism for each authorization step could provide transparency, and using a more flexible configuration system for setting authorization limits instead of hardcoded values could enhance maintainability and scalability .

The `createShape` method in `ShapeFactory` returns null if an invalid shape type is passed, which may lead to NullPointerExceptions when methods are called on shape objects. This lack of exception handling prevents immediate feedback of invalid input, potentially leading to runtime errors that are harder to trace. Implementing exception handling would allow explicit error messages and stop the execution flow when invalid data is encountered, improving the robustness and debugging process .

You might also like