0% found this document useful (0 votes)
24 views

Lab Experiment 2

This document discusses design patterns in Java. It provides code examples to demonstrate the factory and abstract factory patterns. It also discusses design principles and compares design patterns to algorithms.

Uploaded by

VIJESH
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
24 views

Lab Experiment 2

This document discusses design patterns in Java. It provides code examples to demonstrate the factory and abstract factory patterns. It also discusses design principles and compares design patterns to algorithms.

Uploaded by

VIJESH
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 18

S.

Vijesh
ID NO.2200031659

LAB EXPERIMENT – 2
Creational Design Pattern II - Factory and Abstract Design Pattern

PRE-LAB:

1]

UML Relationship Diagram for Factory Design Pattern


S.Vijesh
ID NO.2200031659

2]

UML Relationship Diagram for Abstract Design Pattern


S.Vijesh
ID NO.2200031659

IN-LAB:

A]

package Game;

interface Weapon {

void attack();

package Game;

class Sword implements Weapon {

public void attack() {

System.out.println("Attacking with a sword!");

package Game;

class Axe implements Weapon {

public void attack() {

System.out.println("Attacking with an axe!");

package Game;

interface PowerUp {

void activate();

package Game;
S.Vijesh
ID NO.2200031659

class HealthPowerUp implements PowerUp {

public void activate() {

System.out.println("Health power-up activated!");

package Game;

class ShieldPowerUp implements PowerUp {

public void activate() {

System.out.println("Shield power-up activated!");

package Game;

interface AbstractGameFactory {

Weapon createWeapon();

PowerUp createPowerUp();

package Game;

class EasyGameFactory implements AbstractGameFactory {

public Weapon createWeapon() {

return new Sword();

public PowerUp createPowerUp() {

return new HealthPowerUp();

package Game;
S.Vijesh
ID NO.2200031659

class HardGameFactory implements AbstractGameFactory {

public Weapon createWeapon() {

return new Axe();

public PowerUp createPowerUp() {

return new ShieldPowerUp();

package Game;

abstract class Enemy {

abstract void attack();

package Game;

class EasyEnemy extends Enemy {

void attack() {

System.out.println("Easy enemy is attacking!");

package Game;

class HardEnemy extends Enemy {

void attack() {

System.out.println("Hard enemy is attacking!");

package Game;

interface EnemyFactory {
S.Vijesh
ID NO.2200031659

Enemy createEnemy();

package Game;

class EasyEnemyFactory implements EnemyFactory {

public Enemy createEnemy() {

return new EasyEnemy();

package Game;

class HardEnemyFactory implements EnemyFactory {

public Enemy createEnemy() {

return new HardEnemy();

package Game;

class GameManager {

private static GameManager instance;

private int currentLevel;

private AbstractGameFactory gameFactory;

private GameManager() {

currentLevel = 1;

gameFactory = new EasyGameFactory();

public static synchronized GameManager getInstance() {

if (instance == null) {

instance = new GameManager();


S.Vijesh
ID NO.2200031659

return instance;

public void setDifficulty(String difficulty) {

if (difficulty.equalsIgnoreCase("easy")) {

gameFactory = new EasyGameFactory();

} else if (difficulty.equalsIgnoreCase("hard")) {

gameFactory = new HardGameFactory();

public void startGame() {

System.out.println("Starting game at level " + currentLevel + " with " +


gameFactory.getClass().getSimpleName());

Weapon weapon = gameFactory.createWeapon();

PowerUp powerUp = gameFactory.createPowerUp();

EnemyFactory enemyFactory = (currentLevel <= 3) ? new EasyEnemyFactory() :


new HardEnemyFactory();

Enemy enemy = enemyFactory.createEnemy();

weapon.attack();

powerUp.activate();

enemy.attack();

System.out.println("Game over!");

public void nextLevel() {

currentLevel++;

System.out.println("Proceeding to level " + currentLevel);

}
S.Vijesh
ID NO.2200031659

package Game;

public class GameDemo {

public static void main(String[] args) {

GameManager gameManager = GameManager.getInstance();

gameManager.startGame();

gameManager.setDifficulty("hard");

gameManager.nextLevel();

gameManager.startGame();

OUTPUT:
Starting game at level 1 with EasyGameFactory

Attacking with a sword!

Health power-up activated!

Easy enemy is attacking!

Game over!

Proceeding to level 2

Starting game at level 2 with HardGameFactory

Attacking with an axe!

Shield power-up activated!

Easy enemy is attacking!

Game over!
S.Vijesh
ID NO.2200031659

Sample VIVA-VOCE Questions (In-Lab):

1] Increased code reusability Design patterns allow you to reuse code that
has already been written and tested. This can save you time and effort
when you are developing new code.
Improved code readability and maintainability Design patterns can make
your code more readable and maintainable by providing a common
vocabulary and set of conventions. This can make it easier for other
developers to understand your code and make changes to it in the future.
Reduced coupling. Design patterns can help to reduce coupling between
different parts of your code. This can make your code more flexible and
easier to change.
Improved testability. Design patterns can make your code more testable by
providing a well-defined interface for interacting with different parts of
your code. This can make it easier to write unit tests for your code.
Increased performance. Design patterns can sometimes lead to increased
performance by providing a more efficient way to implement certain
algorithms or data structures.

Here are some specific design patterns that can be used in Java:

Singleton pattern: The Singleton pattern ensures that there is only one
instance of a class. This can be useful for objects that need to be globally
accessible or that need to maintain a single state.
Factory pattern: The Factory pattern provides a way to create objects
without specifying their concrete class. This can be useful for creating
objects that depend on runtime parameters or that need to be created in a
specific way.
S.Vijesh
ID NO.2200031659

Abstract Factory pattern: The Abstract Factory pattern provides a way to


create families of related objects. This can be useful for creating objects
that are related to each other in a complex way.
Strategy pattern: The Strategy pattern allows you to encapsulate an
algorithm inside of an object. This can be useful for creating objects that
can be used with different algorithms.
Observer pattern: The Observer pattern allows you to create one-to-many
relationships between objects. This can be useful for objects that need to be
notified of changes to other objects.

2]
Single Responsibility Principle (SRP): A class should only have one
responsibility. This means that a class should only do one thing and do
it well.
Open-Closed Principle (OCP): Classes should be open for extension but
closed for modification. This means that you should be able to add
new functionality to a class without having to modify the existing
code.
Liskov Substitution Principle (LSP): Subclasses should be substitutable for
their base classes. This means that you should be able to use a subclass in
place of its base class without any problems.
Interface Segregation Principle (ISP): Clients should not be forced to
depend on methods they do not use. This means that you should not force a
client to implement methods that it does not need.
Dependency Inversion Principle (DIP): Depend on abstractions, not on
concretions. This means that you should depend on interfaces or abstract
classes, not on concrete classes.
These principles can help you to write better design patterns in Java. By
following these principles, you can make your code more flexible,
maintainable, and extensible.
S.Vijesh
ID NO.2200031659

3] The main differences between design patterns and design principles:


Design patterns are concrete solutions to recurring design problems. They
are typically implemented as classes or objects that can be reused in
different applications.
Design principles are general guidelines that can be used to improve the
design of software. They are not specific solutions to problems, but they
can help you to write better code.
Design patterns and design principles are both important tools for software
development. Design patterns can help you to solve specific problems,
while design principles can help you to write better code in general. By
understanding the differences between design patterns and design
principles, you can use them together to create better software.

4] The differences between design patterns and algorithms:


Design patterns are solutions to recurring design problems. They are
typically implemented as classes or objects that can be reused in different
applications.
Algorithms are step-by-step procedures for solving a specific problem.
They are typically implemented as functions or methods.

Design patterns and algorithms are both important tools for software
development. Design patterns can help you to solve specific problems,
while algorithms can help you to solve specific problems in an efficient
way. By understanding the differences between design patterns and
algorithms, you can use them together to create better software.
Design patterns are often implemented using algorithms. For example, the
Singleton pattern can be implemented using a lazy initialization algorithm.
Algorithms can be used to implement design patterns. For example, the
Factory pattern can be implemented using a simple algorithm that returns
a new instance of a class based on a given input.
S.Vijesh
ID NO.2200031659

5] A wrapper pattern is a design pattern that encapsulates an object to


provide a different interface to it. This can be useful for a variety of reasons,
such as:
To provide a simpler or more abstract interface to the
object. To adapt the object to a different environment.
To provide additional functionality to the object.
The wrapper pattern is the adapter pattern. The adapter pattern is used to
adapt an object to a different interface. This can be useful for objects that
need to work with different types of objects. For example, an adapter
pattern can be used to adapt a file object to work with a database object.

POST-LAB:

A]
package Experiment_2;

interface Vehicle {

String ride();

package Experiment_2;

class Car implements Vehicle {

@Override

public String ride() {

return "You are riding a car.";

package Experiment_2;

class Bike implements Vehicle {


S.Vijesh
ID NO.2200031659

@Override

public String ride() {

return "You are riding a bike.";

package Experiment_2;

class Scooter implements Vehicle {

@Override

public String ride() {

return "You are riding a scooter.";

package Experiment_2;

interface VehicleFactory {

Vehicle createVehicle();

package Experiment_2;

class CarFactory implements VehicleFactory {

@Override

public Vehicle createVehicle() {

return new Car();

package Experiment_2;

class BikeFactory implements VehicleFactory {

@Override
S.Vijesh
ID NO.2200031659

public Vehicle createVehicle() {

return new Bike();

package Experiment_2;

class ScooterFactory implements VehicleFactory {

@Override

public Vehicle createVehicle() {

return new Scooter();

package Experiment_2;

interface PaymentMethod {

String pay(double amount);

package Experiment_2;

class CreditCard implements PaymentMethod {

@Override

public String pay(double amount) {

return "Paying $" + amount + " with credit card.";

package Experiment_2;

class PayPal implements PaymentMethod {

@Override

public String pay(double amount) {


S.Vijesh
ID NO.2200031659

return "Paying $" + amount + " with PayPal.";

package Experiment_2;

interface PaymentFactory {

PaymentMethod createPaymentMethod();

package Experiment_2;

class CreditCardFactory implements PaymentFactory {

@Override

public PaymentMethod createPaymentMethod() {

return new CreditCard();

package Experiment_2;

class PayPalFactory implements PaymentFactory {

@Override

public PaymentMethod createPaymentMethod() {

return new PayPal();

package Experiment_2;

class UserAuthentication {

private static UserAuthentication instance;

private UserAuthentication() {

}
S.Vijesh
ID NO.2200031659

public static synchronized UserAuthentication getInstance() {

if (instance == null) {

instance = new UserAuthentication();

return instance;

public boolean authenticate(String username, String password) {

return true;

package Experiment_2;

import java.util.Scanner;

public class RideSharingApp {

public static void main(String[] args) {

// User authentication using Singleton pattern

UserAuthentication auth = UserAuthentication.getInstance();

Scanner scanner = new Scanner(System.in);

System.out.print("Enter username: ");

String username = scanner.nextLine();

System.out.print("Enter password: ");

String password = scanner.nextLine();

boolean authenticatedUser = auth.authenticate(username, password);

if (authenticatedUser) {

// Requesting a ride using Factory Method pattern

System.out.print("Enter vehicle type (car, bike, scooter): ");

String vehicleType = scanner.nextLine();


S.Vijesh
ID NO.2200031659

VehicleFactory vehicleFactory = null;

switch (vehicleType.toLowerCase()) {

case "car":

vehicleFactory = new CarFactory();

break;

case "bike":

vehicleFactory = new BikeFactory();

break;

case "scooter":

vehicleFactory = new ScooterFactory();

break;

default:

System.out.println("Invalid vehicle type.");

System.exit(1);

Vehicle vehicle = vehicleFactory.createVehicle();

System.out.println(vehicle.ride());

// Selecting a payment method using Abstract Factory pattern

System.out.print("Enter payment method (credit card, paypal): ");

String paymentMethodType = scanner.nextLine();

PaymentFactory paymentFactory = null;

switch (paymentMethodType.toLowerCase()) {

case "credit card":

paymentFactory = new CreditCardFactory();

break;

case "paypal":
S.Vijesh
ID NO.2200031659

paymentFactory = new PayPalFactory();

break;

default:

System.out.println("Invalid payment method.");

System.exit(1);

PaymentMethod paymentMethod = paymentFactory.createPaymentMethod();

System.out.print("Enter amount to pay: ");

double amount = Double.parseDouble(scanner.nextLine());

System.out.println(paymentMethod.pay(amount));

} else {

System.out.println("Authentication failed. Please try again.");

scanner.close();

OUTPUT:

Enter username: tagore

Enter password: tagore

Enter vehicle type (car, bike, scooter): car

You are riding a car.

Enter payment method (credit card, paypal): credit card

Enter amount to pay: 20000

Paying $20000.0 with credit card.

You might also like