What are strategies in java with examples

Lora 51 Published: 10/30/2024

What are strategies in java with examples

I'm happy to help you with that!

Java is an object-oriented programming language known for its platform independence and versatility. Here, we'll dive into some of the most effective strategies used in Java, along with examples:

Single Responsibility Principle (SRP): Each class should have a single responsibility and not be overly complex.

Example:

// Bad implementation

public class Employee {

public void updateName(String name) {

this.name = name;

}

public void calculateSalary() {

// calculation logic

}

}

// Good implementation

public interface UpdateName {

void setName(String name);

}

public interface CalculateSalary {

int calculate();

}

public class Employee implements UpdateName, CalculateSalary {

private String name;

@Override

public void setName(String name) {

this.name = name;

}

@Override

public int calculate() {

// calculation logic

}

}

Don't Repeat Yourself (DRY): Avoid duplicating code by extracting reusable blocks into separate methods or classes.

Example:

// Duplicate code

public class BankAccount {

public void debit(int amount) {

System.out.println("Debiting " + amount);

}

public void credit(int amount) {

System.out.println("Crediting " + amount);

}

}

// Improved implementation using DRY principle

public abstract class Transaction {

public abstract void processTransaction(int amount);

}

public class Debit extends Transaction {

@Override

public void processTransaction(int amount) {

System.out.println("Debiting " + amount);

}

}

public class Credit extends Transaction {

@Override

public void processTransaction(int amount) {

System.out.println("Crediting " + amount);

}

}

Encapsulation: Hide internal implementation details and expose only necessary information through a controlled interface.

Example:

// Poor encapsulation

public class Person {

private String name;

public void setName(String name) {

this.name = name;

}

public String getName() {

return name;

}

}

// Improved encapsulation using access modifiers

public class Person {

private final String name; // Immutable

public Person(String name) {

this.name = name;

}

public String getName() {

return name;

}

}

Composition: Combine objects to form a new, more complex object that exhibits specific behaviors.

Example:

// Simple implementation

public class Car {

private Engine engine;

public void startEngine() {

engine.start();

}

}

public class Truck extends Car {

// ...

}

// Composition example

public interface Engine {

void start();

}

public class GasolineEngine implements Engine {

@Override

public void start() {

System.out.println("Gasoline engine started");

}

}

public class ElectricEngine implements Engine {

@Override

public void start() {

System.out.println("Electric engine started");

}

}

public class Car {

private final Engine engine;

public Car(Engine engine) {

this.engine = engine;

}

public void startEngine() {

engine.start();

}

}

Factory Method: Provide a way to create objects without specifying the exact class type.

Example:

// Simple implementation

public abstract class Vehicle {

public abstract void drive();

}

public class Car extends Vehicle {

@Override

public void drive() {

System.out.println("Driving a car");

}

}

public class Truck extends Vehicle {

@Override

public void drive() {

System.out.println("Driving a truck");

}

}

// Factory method example

public interface VehicleFactory {

Vehicle createVehicle();

}

public class CarFactory implements VehicleFactory {

@Override

public Vehicle createVehicle() {

return new Car();

}

}

public class TruckFactory implements VehicleFactory {

@Override

public Vehicle createVehicle() {

return new Truck();

}

}

These strategies can help you write more maintainable, flexible, and scalable code in Java. Remember to apply these principles judiciously, as over-engineering can be detrimental to the overall system performance.

Strategy pattern java 8 example

I'd be happy to help! Here's an example of the Strategy pattern implemented in Java using Java 8:

Strategy Pattern

The Strategy pattern is a behavioral design pattern that defines a family of algorithms, encapsulates each one as a separate class, and makes them interchangeable at runtime.

Example: Payment Processors

Imagine you're building an e-commerce platform that needs to support different payment processors like PayPal, Credit Card, Bank Transfer, etc. Each processor has its own way of processing payments, but they all share the same interface (e.g., processPayment()). This is a perfect scenario to apply the Strategy pattern.

Here's how you could implement this in Java using Java 8:

interface PaymentProcessor {

void processPayment(Payment payment);

}

class PayPalProcessor implements PaymentProcessor {

@Override

public void processPayment(Payment payment) {

// Process payment through PayPal API

System.out.println("Processing payment through PayPal");

}

}

class CreditCardProcessor implements PaymentProcessor {

@Override

public void processPayment(Payment payment) {

// Process payment through credit card API

System.out.println("Processing payment through credit card");

}

}

class BankTransferProcessor implements PaymentProcessor {

@Override

public void processPayment(Payment payment) {

// Process payment through bank transfer API

System.out.println("Processing payment through bank transfer");

}

}

abstract class Payment {

protected PaymentProcessor processor;

public Payment(PaymentProcessor processor) {

this.processor = processor;

}

public void makePayment() {

processor.processPayment(this);

}

}

public class Main {

public static void main(String[] args) {

PayPal payment = new PayPal(new PayPalProcessor());

CreditCard creditCard = new CreditCard(new CreditCardProcessor());

BankTransfer bankTransfer = new BankTransfer(new BankTransferProcessor());

payment.makePayment();

creditCard.makePayment();

bankTransfer.makePayment();

}

}

In this example, we have an abstract class Payment that has a reference to a PaymentProcessor. The makePayment() method is responsible for processing the payment using the processor's processPayment() method.

We then define three concrete subclasses of Payment, each representing a different type of payment (PayPal, Credit Card, and Bank Transfer). Each of these classes takes a PaymentProcessor as its constructor argument, which is used to process the payment when the makePayment() method is called.

In the Main class, we create instances of Payment, passing in their corresponding processors. We then call the makePayment() method on each instance, and it will use the associated processor to process the payment.

The benefits of this approach are:

You can add or remove payment processors without modifying the core logic of your program. You can switch between different payment processors at runtime without affecting the rest of your code. Your code becomes more modular, reusable, and maintainable.

I hope this helps illustrate how you could implement the Strategy pattern in Java using Java 8!