Skip to content

Instantly share code, notes, and snippets.

@mzakyalvan
Last active November 23, 2018 09:24
Show Gist options
  • Save mzakyalvan/86f8c55497d65fbb6a996902638caef3 to your computer and use it in GitHub Desktop.
Save mzakyalvan/86f8c55497d65fbb6a996902638caef3 to your computer and use it in GitHub Desktop.
Strategy pattern sample
package com.example.demo;
import io.reactivex.Flowable;
import io.reactivex.Single;
import lombok.Getter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import java.util.List;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Autowired
private BookingService bookingService;
@Bean
public ApplicationRunner sampleRunnner() {
return args -> {
BookingRequest sriwijayaRequest = new BookingRequest(SupplierType.SRIWIJAYA);
bookingService.bookFlight(sriwijayaRequest)
.test()
.assertSubscribed()
.await()
.assertValue(bookingResponse -> bookingResponse instanceof BookingResponse &&
bookingResponse.getSupplierType().equals(SupplierType.SRIWIJAYA)
)
.assertComplete();
BookingRequest garudaRequest = new BookingRequest(SupplierType.GARUDA);
bookingService.bookFlight(sriwijayaRequest)
.test()
.assertSubscribed()
.await()
.assertValue(bookingResponse -> bookingResponse instanceof BookingResponse &&
bookingResponse.getSupplierType().equals(SupplierType.GARUDA)
)
.assertComplete();
BookingRequest citilinkRequest = new BookingRequest(SupplierType.CITILINK);
bookingService.bookFlight(citilinkRequest)
.test()
.assertSubscribed()
.await()
.assertError(throwable -> throwable instanceof RuntimeException && throwable.getMessage().equals("No booking strategy found"));
};
}
}
interface BookingService {
Single<BookingResponse> bookFlight(BookingRequest bookRequest);
}
@Service
class DefaultBookingService implements BookingService {
@Autowired
private List<BookingStrategy> bookinStrategies;
@Override
public Single<BookingResponse> bookFlight(BookingRequest bookRequest) {
return Single.just(bookRequest)
.flatMap(request -> Flowable.fromIterable(bookinStrategies)
.filter(bookingStrategy -> bookingStrategy.supports(request))
.take(1).single(BookingStrategy.NOT_SUPPORT)
.flatMap(bookingStrategy -> bookingStrategy.performBooking(request))
);
}
}
enum SupplierType {
SRIWIJAYA, LION, GARUDA, CITILINK
}
@Getter
class BookingRequest {
private SupplierType supplierType;
public BookingRequest(SupplierType supplierType) {
this.supplierType = supplierType;
}
}
@Getter
class BookingResponse {
private SupplierType supplierType;
public BookingResponse(SupplierType supplierType) {
this.supplierType = supplierType;
}
}
interface BookingStrategy {
BookingStrategy NOT_SUPPORT = new BookingStrategy() {
@Override
public boolean supports(BookingRequest request) {
return true;
}
@Override
public Single<BookingResponse> performBooking(BookingRequest request) {
return Single.error(new RuntimeException("No booking strategy found"));
}
};
boolean supports(BookingRequest request);
Single<BookingResponse> performBooking(BookingRequest request);
}
@Component
class SriwijayaBookingStrategy implements BookingStrategy {
@Override
public boolean supports(BookingRequest request) {
return request.getSupplierType() == SupplierType.SRIWIJAYA;
}
@Override
public Single<BookingResponse> performBooking(BookingRequest request) {
return Single.just(new BookingResponse(request.getSupplierType()));
}
}
@Component
class LionBookingStrategy implements BookingStrategy {
@Override
public boolean supports(BookingRequest request) {
return request.getSupplierType() == SupplierType.LION;
}
@Override
public Single<BookingResponse> performBooking(BookingRequest request) {
return Single.just(new BookingResponse(request.getSupplierType()));
}
}
@Component
class GarudaBookingStrategy implements BookingStrategy {
@Override
public boolean supports(BookingRequest request) {
return request.getSupplierType() == SupplierType.GARUDA;
}
@Override
public Single<BookingResponse> performBooking(BookingRequest request) {
return Single.just(new BookingResponse(request.getSupplierType()));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment