Last active
November 23, 2018 09:24
-
-
Save mzakyalvan/86f8c55497d65fbb6a996902638caef3 to your computer and use it in GitHub Desktop.
Strategy pattern sample
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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