Skip to content

Instantly share code, notes, and snippets.

@Haneen-Abdulgllil
Forked from mazenmelouk/Adapter.java
Created February 28, 2024 09:09
Show Gist options
  • Save Haneen-Abdulgllil/8da9ad31a1e66d8b83d5a59fa3c1ef39 to your computer and use it in GitHub Desktop.
Save Haneen-Abdulgllil/8da9ad31a1e66d8b83d5a59fa3c1ef39 to your computer and use it in GitHub Desktop.
Simple Design Patterns Examples
import java.util.Map;
class Adapter {
private static final Map<String, MillimeterProductDimensions> PRODUCT_DIMENSIONS_IN_MILLIMETERS_STORE = Map.of(
"product1", new MillimeterProductDimensions(20, 10, 50)
);
static abstract class ProductDimensions {
private final double length;
private final double height;
private final double width;
private ProductDimensions(double length, double height, double width) {
this.length = length;
this.height = height;
this.width = width;
}
public double getLength() {
return length;
}
public double getHeight() {
return height;
}
public double getWidth() {
return width;
}
}
static class MillimeterProductDimensions extends ProductDimensions {
private MillimeterProductDimensions(double length, double height, double width) {
super(length, height, width);
}
}
static class InchProductDimensions extends ProductDimensions {
private InchProductDimensions(double length, double height, double width) {
super(length, height, width);
}
}
static class MillimeterToInchAdapter {
private final MillimeterProductDimensions millimeterProductDimensions;
public MillimeterToInchAdapter(MillimeterProductDimensions millimeterProductDimensions) {
this.millimeterProductDimensions = millimeterProductDimensions;
}
public InchProductDimensions convertToInches() {
// Convert millimeters to inches
return new InchProductDimensions(
millimeterProductDimensions.getLength() / 25.4,
millimeterProductDimensions.getWidth() / 25.4,
millimeterProductDimensions.getHeight() / 25.4
); // 1 inch = 25.4 millimeters
}
}
public static void main(String[] args) {
MillimeterProductDimensions millimeter = PRODUCT_DIMENSIONS_IN_MILLIMETERS_STORE.get("product1");
MillimeterToInchAdapter adapter = new MillimeterToInchAdapter(millimeter);
System.out.println("Length in inches: " + adapter.convertToInches());
}
}
class Decorator {
// Component Interface
interface Order {
String getDescription();
double getPrice();
}
// Concrete Component
static class BaseOrder implements Order {
private final String description;
private final double price;
public BaseOrder(String description, double price) {
this.description = description;
this.price = price;
}
@Override
public String getDescription() {
return description;
}
@Override
public double getPrice() {
return price;
}
}
// Decorator
static abstract class OrderDecorator implements Order {
protected Order decoratedOrder;
public OrderDecorator(Order decoratedOrder) {
this.decoratedOrder = decoratedOrder;
}
@Override
public String getDescription() {
return decoratedOrder.getDescription();
}
@Override
public double getPrice() {
return decoratedOrder.getPrice();
}
}
// Concrete Decorators
static class PriorityOrder extends OrderDecorator {
public PriorityOrder(Order decoratedOrder) {
super(decoratedOrder);
}
@Override
public String getDescription() {
return decoratedOrder.getDescription() + ", Priority Order";
}
@Override
public double getPrice() {
return decoratedOrder.getPrice() * 1.2; // Increase price for priority order
}
}
static class GiftWrap extends OrderDecorator {
public GiftWrap(Order decoratedOrder) {
super(decoratedOrder);
}
@Override
public String getDescription() {
return decoratedOrder.getDescription() + ", Gift Wrap";
}
@Override
public double getPrice() {
return decoratedOrder.getPrice() + 5.0; // Additional cost for gift wrap
}
}
// Client
public static void main(String[] args) {
// Create a base order
Order order = new BaseOrder("Shirt", 20.0);
System.out.println("Order: " + order.getDescription() + ", Price: $" + order.getPrice());
// Decorate with priority order
order = new PriorityOrder(order);
System.out.println("Order: " + order.getDescription() + ", Price: $" + order.getPrice());
// Decorate with gift wrap
order = new GiftWrap(order);
System.out.println("Order: " + order.getDescription() + ", Price: $" + order.getPrice());
}
}
import java.util.ArrayList;
import java.util.Iterator;
// Radio Station class
class RadioStation {
private String frequency;
public RadioStation(String frequency) {
this.frequency = frequency;
}
public String getFrequency() {
return frequency;
}
}
// Iterator interface
interface StationIterator {
boolean hasNext();
RadioStation next();
}
// Concrete Iterator
class StationListIterator implements StationIterator {
private ArrayList<RadioStation> stations;
private int position = 0;
public StationListIterator(ArrayList<RadioStation> stations) {
this.stations = stations;
}
public boolean hasNext() {
return position < stations.size();
}
public RadioStation next() {
if (hasNext()) {
return stations.get(position++);
} else {
return null;
}
}
}
// Aggregate interface
interface StationList {
StationIterator createIterator();
}
// Concrete Aggregate
class RadioStationList implements StationList {
private ArrayList<RadioStation> stations;
public RadioStationList() {
stations = new ArrayList<>();
}
public void addStation(RadioStation station) {
stations.add(station);
}
public StationIterator createIterator() {
return new StationListIterator(stations);
}
}
// Client code
public class RadioStationManager {
public static void main(String[] args) {
RadioStationList stationList = new RadioStationList();
stationList.addStation(new RadioStation("95.5 FM"));
stationList.addStation(new RadioStation("101.1 FM"));
stationList.addStation(new RadioStation("104.3 FM"));
StationIterator iterator = stationList.createIterator();
System.out.println("Radio Stations:");
while (iterator.hasNext()) {
RadioStation station = iterator.next();
System.out.println(station.getFrequency());
}
}
}
package com.melouk.personal.observer;
import java.util.ArrayList;
import java.util.List;
public class ObserverPattern {
public enum OrderStatus{
RECEIVED,
PACKING,
DELIVERING,
DELIVERED
}
public interface Observer {
void update(OrderStatus orderStatus);
}
public interface Subject {
void attach(Observer observer);
void detach(Observer observer);
void notifyObservers();
}
public static class Order implements Subject {//concrete subject
private final List<Observer> observers = new ArrayList<>();
private OrderStatus orderStatus;
public void setOrderStatus(OrderStatus orderStatus) {
this.orderStatus = orderStatus;
notifyObservers();
}
@Override
public void attach(Observer observer) {
observers.add(observer);
}
@Override
public void detach(Observer observer) {
observers.remove(observer);
}
@Override
public void notifyObservers() {
for (Observer observer : observers) {
observer.update(orderStatus);
}
}
}
public static class Warehouse implements Observer {
@Override
public void update(OrderStatus orderStatus) {
//when it's received it should
System.out.println("Warehouse: Order status - " + orderStatus);
}
}
public static class Carrier implements Observer {
@Override
public void update(OrderStatus orderStatus) {
System.out.println("Carrier: Order status - " + orderStatus);
}
}
public static class Customer implements Observer {
@Override
public void update(OrderStatus orderStatus) {
// can send updates via email, mobile notification
System.out.println("Customer: Order status - " + orderStatus);
}
}
public static void main(String[] args) {
Order order = new Order();
Observer restaurant = new Warehouse();
Observer carrier = new Carrier();
Observer customer = new Customer();
order.attach(restaurant);
order.attach(carrier);
order.attach(customer);
// Signal the order is received
order.setOrderStatus(OrderStatus.RECEIVED);
// Ideally we could send the order id in the notification so that the warehouse can look it up
// and package it
order.setOrderStatus(OrderStatus.PACKING);
order.setOrderStatus(OrderStatus.DELIVERING);
order.setOrderStatus(OrderStatus.DELIVERED);
}
}
class PaymentsFactory {
// Payment interface
public interface Payment {
void processPayment();
}
// Concrete payment classes
public static class CreditCardPayment implements Payment {
@Override
public void processPayment() {
System.out.println("Processing credit card payment...");
}
}
public static class PayPalPayment implements Payment {
@Override
public void processPayment() {
System.out.println("Processing PayPal payment...");
}
}
enum PaymentMethod {
PAYPAL,
CREDIT_CARD
}
// Payment factory interface
public static class PaymentFactory {
Payment createPayment(PaymentMethod paymentMethod) {
return switch (paymentMethod) {
case PAYPAL -> new PayPalPayment();
case CREDIT_CARD -> new CreditCardPayment();
};
}
}
// Client class
public static class PaymentClient {
private final PaymentFactory factory;
public PaymentClient(PaymentFactory factory) {
this.factory = factory;
}
public void makePayment(PaymentMethod paymentMethod) {
Payment payment = factory.createPayment(paymentMethod);
payment.processPayment();
}
}
// Example usage
public class Main {
public void main(String[] args) {
// Create payment factories
PaymentClient paymentClient = new PaymentClient(new PaymentFactory());
// Make payments using clients
paymentClient.makePayment(PaymentMethod.CREDIT_CARD);
paymentClient.makePayment(PaymentMethod.PAYPAL);
}
}
}
import java.util.Date;
public class Person {
// Required attributes
private final String firstName;
private final String lastName;
// Optional attributes
private String middleName;
private String[] addresses;
private String nationality;
private String religion;
private Date dateOfBirth;
private String sex;
private String countryOfResidency;
private Person(Builder builder) {
this.firstName = builder.firstName;
this.middleName = builder.middleName;
this.lastName = builder.lastName;
this.addresses = builder.addresses;
this.nationality = builder.nationality;
this.religion = builder.religion;
this.dateOfBirth = builder.dateOfBirth;
this.sex = builder.sex;
this.countryOfResidency = builder.countryOfResidency;
}
// Getter methods for attributes
public static class Builder {
// Required attributes
private final String firstName;
private final String lastName;
// Optional attributes
private String middleName;
private String[] addresses;
private String nationality;
private String religion;
private Date dateOfBirth;
private String sex;
private String countryOfResidency;
// Constructor with required attributes
public Builder(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
// Setter methods for optional attributes
public Builder middleName(String middleName) {
this.middleName = middleName;
return this;
}
public Builder addresses(String[] addresses) {
this.addresses = addresses;
return this;
}
public Builder nationality(String nationality) {
this.nationality = nationality;
return this;
}
public Builder religion(String religion) {
this.religion = religion;
return this;
}
public Builder dateOfBirth(Date dateOfBirth) {
this.dateOfBirth = dateOfBirth;
return this;
}
public Builder sex(String sex) {
this.sex = sex;
return this;
}
public Builder countryOfResidency(String countryOfResidency) {
this.countryOfResidency = countryOfResidency;
return this;
}
// Build method to create Person object
public Person build() {
return new Person(this);
}
}
// Other methods and functionalities of the Person class
}
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
class Proxy {
interface DataLoader {
List<Double> loadData(String key);
}
static class RemoteDataLoader implements DataLoader {
@Override
public List<Double> loadData(String key) {
//Assume it does a remote call
return List.of(new Random().nextDouble());
}
}
static class CachingDataLoader implements DataLoader {
private final DataLoader remoteDataLoader;
private final Map<String, List<Double>> cache;
public CachingDataLoader(DataLoader remoteDataLoader) {
this.remoteDataLoader = remoteDataLoader;
this.cache = new ConcurrentHashMap<>();
}
@Override
public List<Double> loadData(String key) {
return cache.computeIfAbsent(key, remoteDataLoader::loadData);
}
}
static class MetricsDataLoader implements DataLoader {
private final DataLoader remoteDataLoader;
MetricsDataLoader(DataLoader remoteDataLoader) {
this.remoteDataLoader = remoteDataLoader;
}
@Override
public List<Double> loadData(String key) {
long tick = System.nanoTime();
List<Double> result = remoteDataLoader.loadData(key);
long toc = System.nanoTime();
System.out.println("Time taken = " + (toc - tick) + " ns");
return result;
}
}
public static void main(String[] args) {
DataLoader remoteDataLoader = new RemoteDataLoader();
DataLoader cachingDataLoader = new CachingDataLoader(remoteDataLoader);
DataLoader metrics = new MetricsDataLoader(remoteDataLoader);
System.out.println(cachingDataLoader.loadData("a"));
System.out.println(cachingDataLoader.loadData("a"));
System.out.println(metrics.loadData("a"));
}
}
public class Singleton {
private static Singleton instance;
// Private constructor to prevent instantiation from outside
private Singleton() {}
// Static method to return the singleton instance
public static Singleton getInstance() {
if (instance == null) {// Check if the instance is not created.
instance = new Singleton();
}
return instance;
}
}
public class SingeltonEager {
// Here the instance is created upon class creation.
private static final SingeltonEager INSTANCE = new SingeltonEager();
// Private constructor to prevent instantiation from outside
private SingeltonEager() {}
public static SingeltonEager getInstance() {
return INSTANCE;
}
}
public class SingletonThreadsafe {
private static volatile SingletonThreadsafe instance;
// Private constructor to prevent instantiation from outside
private SingletonThreadsafe() {}
// Static method to return the singleton instance with double locking
public static SingletonThreadsafe getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
// Interface defining the payment strategy
interface PaymentStrategy {
void pay(double amount);
}
// Concrete implementation for Credit Card payment
class CreditCardPayment implements PaymentStrategy {
private String cardNumber;
private String expiryDate;
private String cvv;
public CreditCardPayment(String cardNumber, String expiryDate, String cvv) {
this.cardNumber = cardNumber;
this.expiryDate = expiryDate;
this.cvv = cvv;
}
@Override
public void pay(double amount) {
System.out.println("Paid " + amount + " via Credit Card.");
// Additional logic specific to credit card payment
}
}
// Concrete implementation for PayPal payment
class PayPalPayment implements PaymentStrategy {
private String email;
private String password;
public PayPalPayment(String email, String password) {
this.email = email;
this.password = password;
}
@Override
public void pay(double amount) {
System.out.println("Paid " + amount + " via PayPal.");
// Additional logic specific to PayPal payment
}
}
// Context class that allows clients to use different payment strategies
class PaymentContext {
private PaymentStrategy paymentStrategy;
public PaymentContext(PaymentStrategy paymentStrategy) {
this.paymentStrategy = paymentStrategy;
}
public void setPaymentStrategy(PaymentStrategy paymentStrategy) {
this.paymentStrategy = paymentStrategy;
}
public void processPayment(double amount) {
paymentStrategy.pay(amount);
}
}
// Client code demonstrating the usage of different payment strategies
public class PaymentExample {
public static void main(String[] args) {
PaymentStrategy creditCardStrategy = new CreditCardPayment("1234 5678 9012 3456", "12/25", "123");
PaymentStrategy paypalStrategy = new PayPalPayment("example@example.com", "password");
PaymentContext paymentContext = new PaymentContext(creditCardStrategy);
paymentContext.processPayment(100.00); // Pay via Credit Card
paymentContext.setPaymentStrategy(paypalStrategy);
paymentContext.processPayment(50.00); // Pay via PayPal
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment