Practical Implementation of Common Java Design Patterns

Design pattern are proven, reusable solutions to recurring problems in software design. They provide structured approaches that help developers build scalable, maintainable systems — applicable across domains like DDD or enterprise applications.

Core Patterns Covered

  • Strategy Pattern
  • Factory Pattern
  • Singleton Pattern
  • Proxy Pattern
  • Factory Method Pattern
  • Observer Pattern
  • Template Method Pattern
  • Adapter Pattern

Scenario-Based Implementation: Discount Pricing System

A retail system applies different discount rules based on purchase amount:

  • ≥ 2000 → 20% off
  • 500–1999 → 10% off
  • < 500 → 5% off

Strategy Pattern Refactored

public interface DiscountPolicy {
    String getIdentifier();
    BigDecimal applyDiscount(BigDecimal originalPrice);
}

@Component
public class PremiumDiscount implements DiscountPolicy {
    @Override
    public String getIdentifier() { return "PREMIUM"; }
    @Override
    public BigDecimal applyDiscount(BigDecimal price) {
        return price.multiply(BigDecimal.valueOf(0.8));
    }
}

@Component
public class StandardDiscount implements DiscountPolicy {
    @Override
    public String getIdentifier() { return "STANDARD"; }
    @Override
    public BigDecimal applyDiscount(BigDecimal price) {
        return price.multiply(BigDecimal.valueOf(0.9));
    }
}

@Component
public class BasicDiscount implements DiscountPolicy {
    @Override
    public String getIdentifier() { return "BASIC"; }
    @Override
    public BigDecimal applyDiscount(BigDecimal price) {
        return price.multiply(BigDecimal.valueOf(0.95));
    }
}

Auto-wired strategy dispatcher using Spring:

@Configuration
public class DiscountConfig {

    @Bean
    public Function<String, DiscountPolicy> discountRouter(List<DiscountPolicy> policies) {
        return policies.stream()
            .collect(Collectors.toMap(
                DiscountPolicy::getIdentifier,
                Function.identity()
            ))::get;
    }
}

@RestController
@RequestMapping("/pricing")
public class PricingController {

    private final Function<String, DiscountPolicy> discountRouter;

    public PricingController(Function<String, DiscountPolicy> router) {
        this.discountRouter = router;
    }

    @GetMapping("/calculate")
    public BigDecimal calculate(@RequestParam BigDecimal amount, @RequestParam String tier) {
        DiscountPolicy policy = discountRouter.apply(tier);
        return policy.applyDiscount(amount);
    }
}

Payment Gateway Factory (Simplified)

public interface PaymentProcessor {
    boolean process(PaymentRequest request);
}

public class AlipayProcessor implements PaymentProcessor {
    @Override
    public boolean process(PaymentRequest req) {
        System.out.println("Processing via Alipay...");
        return true;
    }
}

public class WechatPayProcessor implements PaymentProcessor {
    @Override
    public boolean process(PaymentRequest req) {
        System.out.println("Processing via WeChat Pay...");
        return true;
    }
}

@Component
public class PaymentFactory {

    private final Map<String, PaymentProcessor> processors = new HashMap<>();

    @PostConstruct
    public void init() {
        processors.put("ALIPAY", new AlipayProcessor());
        processors.put("WECHAT", new WechatPayProcessor());
    }

    public PaymentProcessor getProcessor(String method) {
        if (!processors.containsKey(method)) {
            throw new IllegalArgumentException("Unsupported payment method: " + method);
        }
        return processors.get(method);
    }
}

Thread-Safe Singlteon (Static Inner Class)

public class ConfigurationManager {
    private ConfigurationManager() {}

    private static class Holder {
        static final ConfigurationManager INSTANCE = new ConfigurationManager();
    }

    public static ConfigurationManager getInstance() {
        return Holder.INSTANCE;
    }
}

Proxy Pattern: Property Rental

public interface RentalService {
    void leaseProperty();
}

public class Landlord implements RentalService {
    @Override
    public void leaseProperty() {
        System.out.println("Property leased directly by owner.");
    }
}

public class AgencyProxy implements RentalService {
    private final Landlord landlord = new Landlord();

    @Override
    public void leaseProperty() {
        System.out.println("Agency collects fee and facilitates lease...");
        landlord.leaseProperty();
    }
}

Factory Method Pattern: Network Service Router

public interface NetworkHandler {
    NetworkResponse handle(NetworkRequest request);
}

@Service
public class MobileNetworkHandler implements NetworkHandler {
    @Override
    public NetworkResponse handle(NetworkRequest req) {
        return new NetworkResponse("Mobile");
    }
}

@Service
public class FiberNetworkHandler implements NetworkHandler {
    @Override
    public NetworkResponse handle(NetworkRequest req) {
        return new NetworkResponse("Fiber");
    }
}

@Service
public class NetworkFactory {
    private final Map<String, NetworkHandler> handlers;

    public NetworkFactory(List<NetworkHandler> handlerList) {
        this.handlers = handlerList.stream()
            .collect(Collectors.toMap(h -> h.getClass().getSimpleName().replace("Handler", ""), h -> h));
    }

    public NetworkHandler getHandler(String type) {
        return handlers.get(type.toUpperCase());
    }
}

Observer Pattern: Weather Monitoring

interface WeatherSubject {
    void register(WeatherObserver observer);
    void notifyObservers();
}

interface WeatherObserver {
    void update(float temp, float humidity);
}

class WeatherStation implements WeatherSubject {
    private final List<WeatherObserver> observers = new ArrayList<>();
    private float temperature, humidity;

    @Override
    public void register(WeatherObserver o) { observers.add(o); }

    @Override
    public void notifyObservers() {
        for (WeatherObserver obs : observers) {
            obs.update(temperature, humidity);
        }
    }

    public void setReadings(float temp, float hum) {
        this.temperature = temp;
        this.humidity = hum;
        notifyObservers();
    }
}

class DisplayBoard implements WeatherObserver {
    @Override
    public void update(float temp, float humidity) {
        System.out.printf("Current: %.1f°C, Humidity: %.0f%%%n", temp, humidity);
    }
}

Template Method: House Construction Blueprint

abstract class ConstructionTemplate {
    public final void buildStructure() {
        layFoundation();
        erectFrame();
        installWalls();
        mountWindows();
        System.out.println("Construction completed.");
    }

    private void layFoundation() {
        System.out.println("Pouring concrete foundation...");
    }

    protected abstract void erectFrame();
    protected abstract void installWalls();

    private void mountWindows() {
        System.out.println("Installing double-glazed windows.");
    }
}

class TimberFrameHouse extends ConstructionTemplate {
    @Override protected void erectFrame() { System.out.println("Assembling timber frame..."); }
    @Override protected void installWalls() { System.out.println("Mounting wooden panel walls..."); }
}

class SteelFrameHouse extends ConstructionTemplate {
    @Override protected void erectFrame() { System.out.println("Welding steel beams..."); }
    @Override protected void installWalls() { System.out.println("Attaching metal cladding..."); }
}

Adapter Pattern: Network Interface Converter

class EthernetCable {
    public void transmitData() {
        System.out.println("Transmitting via Ethernet cable.");
    }
}

interface UsbPort {
    void sendData();
}

class EthernetToUsbAdapter implements UsbPort {
    private final EthernetCable cable = new EthernetCable();

    @Override
    public void sendData() {
        cable.transmitData();
    }
}

class Laptop {
    public void connect(UsbPort port) {
        port.sendData();
    }
}

Tags: java DesignPatterns StrategyPattern FactoryPattern SingletonPattern

Posted on Sat, 16 May 2026 10:55:08 +0000 by fansa