Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Facade Design Pattern - Kotlin
class FacadeDesignPattern {
companion object {
@JvmStatic
fun main(args: Array<String>) {
try {
if (FacadeOrderManager.getInstance.createOrder("1")) {
println("Order Successful")
}
} catch (e: Exception) {
println("Error while placing order: ${e.message}")
}
}
}
}
/**
* This is the entry point for a client to order a product from our system.
*/
interface FacadeOrderManager {
companion object {
// Objects are declared as lazy
private val inventoryService: InventoryService by lazy { InventoryServiceImpl() }
private val paymentService: PaymentService by lazy { PaymentServiceImpl() }
private val shippingService: ShippingService by lazy { ShippingServiceImpl() }
/**
* Return the instance of [FacadeOrderManager]
*/
val getInstance: FacadeOrderManager by lazy {
FacadeOrderManagerImpl(
inventoryService,
paymentService,
shippingService
)
}
}
/**
* Oder a product, which may throw [Exception] if something goes wrong in the process.
*
* @param pId Product ID
*
* @throws [Exception]
*
* @return [Boolean]
*/
@Throws(Exception::class)
fun createOrder(pId: String): Boolean
}
/**
* Implementation of [FacadeOrderManager].
* This class is responsible to manage order process for a specific product.
* If any kind of error happen, throw [Exception] by following Programming by Contract.
* @param inventoryService service to check inventory status.
* @param paymentService to make payment.
* @param shippingService to ship a product to the customer.
*/
class FacadeOrderManagerImpl(
private val inventoryService: InventoryService,
private val paymentService: PaymentService,
private val shippingService: ShippingService
) : FacadeOrderManager {
override fun createOrder(pId: String): Boolean {
// Check if product available
when (inventoryService.checkIsAvailableInStock(pId)) {
true -> {
// Check if payment is successful
when (paymentService.makePaymentForProduct(pId) == "payment_token") {
true -> {
// Check if shipping is successful
when (shippingService.shipOrderedProduct(pId)) {
true -> {
return true
}
else -> {
throw Exception("Failed to shipping process for the product : $pId")
}
}
}
else -> {
throw Exception("Payment failed")
}
}
}
else -> {
throw Exception("Product is not in stock")
}
}
}
}
/**
* Our inventory service class, is responsible to check stock status for a specific product.
*/
interface InventoryService {
fun checkIsAvailableInStock(pId: String): Boolean
}
/**
* Implementation of [InventoryService]
*/
class InventoryServiceImpl : InventoryService {
override fun checkIsAvailableInStock(pId: String): Boolean {
return pId == "1"
}
}
/**
* Our payment service class, is responsible to make payment for a specific product.
*/
interface PaymentService {
fun makePaymentForProduct(pId: String): String
}
/**
* Implementation of [PaymentService]
*/
class PaymentServiceImpl : PaymentService {
override fun makePaymentForProduct(pId: String): String {
// Mocking
return "payment_token"
}
}
/**
* Our shipping service class, is responsible to ship a specific product.
*/
interface ShippingService {
fun shipOrderedProduct(pId: String): Boolean
}
/**
* Implementation of [ShippingService]
*/
class ShippingServiceImpl : ShippingService {
override fun shipOrderedProduct(pId: String): Boolean {
// Mocking
return true
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment