Skip to main content

Java - OOPS-2

ยท 4 min read

Locker and Package OOP Designโ€‹

Class/ComponentOOP ConceptPurpose
Locker (abstract)Abstract classShared locker logic, open/close, lock/unlock
PackageClassRepresents a package with a unique identifier and size
StandardLocker, LargeLockerInheritanceDifferent locker behaviors extending base functionality
Door, LockCompositionBuilding blocks that make up a complete locker
Openable, LockableInterfacesCapability contracts for locker components
LockerControllerPolymorphismManages different locker types uniformly

Abstract Class โ€” Elevatorโ€‹

Base class with partial implementation

public abstract class Locker {

// ๐ŸŸก State variables - no behaviors.

protected final string lockerId;
protected boolean isOccupied;
protected Package currentPackage;

// ๐ŸŸก Compositions
// These are classes with behaviors (door.open(), lock.unlock())
protected final Openable door; // interface type; logic for opening/closing the door
protected final Lockable lock; // interface type; logic for locking/unlocking the locker

public Locker(String lockerId, Openable door, Lockable lock) {
this.lockerId = lockerId;
this.door = door;
this.lock = lock;
}

// ๐ŸŸก Abstract methods - each locker type must implement these
public abstract boolean canFit(Package pkg);

// ๐ŸŸก Shared method with concrete implementation
public void storePackage(Package pkg) {
// open door
// generatePasswordAndLock
// close door and return password
}

public void releasePackage(String packageId) {
// unlock
// Open door
// close door
}
}

Concrete Classes - StandardLocker, LargeLockerโ€‹

public class StandardLocker extends Locker {

public StandardLocker(String lockerId) {
super(lockerId, new ManualDoor(), new ManualLock())
}

@Override
public boolean canFit(Package pkg) {
// check package size
}
}

public class LargeLocker extends Locker {

public LargeLocker(String lockerId) {
super(lockerId, new ElectricDoor(), new ElectricLock());
}

@Override
public boolean canFit(Package pkg) {
// check package size
}
}

Interfaces - Openable, Lockableโ€‹

public interface Openable{
void open();
void close();
}

public interface Lockable {
String generatePasswordAndLock();
boolean unlock(String password);
}

Interface Implementationsโ€‹

public class ManualDoor implements Openable {
@Override
public void open() {
// manual door opening logic
}

@Override
public void close() {
// manual door closing logic
}
}

public class ElectricDoor implements Openable {
@Override
public void open() {
// electric door opening logic
}

@Override
public void close() {
// electric door closing logic
}
}
public class ManualLock implements Lockable {
private String password;

@Override
public String generatePasswordAndLock() {
// manual lock locking logic
}

@Override
public boolean unlock(String password) {
// manual lock unlocking logic
}
}

public class ElectricLock implements Lockable {
private String password;
@Override
public String generatePasswordAndLock() {
// electric lock locking logic
}

@Override
public boolean unlock(String password) {
// electric lock unlocking logic
}
}

In Locker class, instead of concrete class (e.g. ManualLock or ElectricLock), use interfaces (Lockable)

protected final Openable door;
protected final Lockable lock;

LockerControllerโ€‹

public class LockerController {
private final List<Locker> lockers;
private final Map<String, Locker> passwordToLockerMap = new HashMap<>();

public LockerController(List<Locker> lockers) {
this.lockers = lockers;
}

public String assignLocker(Package pkg) {
// Find first available locker that can fit the package
for (Locker locker : lockers) {
if (!locker.isOccupied && locker.canFit(pkg)) {
String password = locker.storePackage(pkg);
passwordToLockerMap.put(password, locker);
return password;
}
}
throw new RuntimeException("No available locker found for package: " + pkg.getId());
}

public void retrievePackage(String password) {
Locker locker = passwordToLockerMap.get(password);
if (locker == null) {
throw new RuntimeException("Invalid password");
}
locker.releasePackage(password);
passwordToLockerMap.remove(password);
}
}
public class LockerSystem {
public static void main(String[] args) {
List<Locker> lockers = List.of(
new StandardLocker("L1"),
new StandardLocker("L2"),
new LargeLocker("L3"),
new LargeLocker("L4")
);

LockerController controller = new LockerController(lockers);

Package pkg1 = new Package("PKG001", PackageSize.SMALL);
Package pkg2 = new Package("PKG002", PackageSize.MEDIUM);

String password1 = controller.assignLocker(pkg1);
String password2 = controller.assignLocker(pkg2);

controller.retrievePackage(password1);
}
}