Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Sealed Classes for state management

Sealed Classes for state management

Avatar for Nyi Nyi Zaw

Nyi Nyi Zaw

February 07, 2020
Tweet

More Decks by Nyi Nyi Zaw

Other Decks in Programming

Transcript

  1. - State management is one of the critical aspects of

    any platform. • One of our apps has multiple payment gateways. Users can make the payment with any gateway. • After the payment gateway auth, there will go to the business logic.
  2. Problem - In the beginning, we have only one payment

    in app. - At this time, it’s easy to maintain state like success, failure, retry - Later, we decided to add another payment gateways, In this time, we have a problem about state management. - Maintaining different flows for each gateway will drain the code management system. - So let’s create a flow that works uniquely for all gateways.
  3. Sealed Classes “Sealed classes are used for representing restricted class

    hierarchies, when a value can have one of the types from a limited set, but cannot have any other type. They are, in a sense, an extension of enum classes: the set of values for an enum type is also restricted, but each enum constant exists only as a single instance, whereas a subclass of a sealed class can have multiple instances which can contain state.”
  4. Example of sealed class usages sealed class NetworkStatus { data

    class Loading(var loading : Boolean) : NetworkStatus() data class Error(var errorMsg : String) : NetworkStatus() } when (networkStatus) { is NetworkStatus.Loading -> { loadingStatus(networkStatus.loading) } is NetworkStatus.Error ->{ hideLoading() showError(networkStatus.errorMsg) } }
  5. Now sealed class PurchaseAuthResult{ data class Sucess(val purchseToken : String)

    : PurchaseResult() data class Fail(val error : String) : PurchaseResult() object Retry : PurchaseResult() } sealed class PurchaseBilling{ object Sucess : PurchaseBilling() data class Fail(val errorCode : Int) : PurchaseBilling() }
  6. Then sealed class PrchaseResult { sealed class PaymentOne: PrchaseResult(){ data

    class Sucess(val purchseToken : String) : PaymentOne() data class Fail(val error : String) : PaymentOne() object Retry : PaymentOne() sealed class PurchaseBilling: PaymentOne(){ object Sucess : PurchaseBilling() data class Fail(val errorCode : Int) : PurchaseBilling() } } sealed class PaymentTwo: PrchaseResult(){ data class Sucess(val purchseToken : String) : PaymentTwo() data class Fail(val error : String) : PaymentTwo() object Retry : PaymentTwo() sealed class PurchaseBilling: PaymentTwo(){ object Sucess : PurchaseBilling() data class Fail(val errorCode : Int) : PurchaseBilling() } } . . . . . . . . . . . . . . . . }
  7. when(signal){ // GooglePlay Billing related is PrchaseResult.GoogplayBilling.Sucess -> { }

    is PrchaseResult.GoogplayBilling.Fail -> { } is PrchaseResult.GoogplayBilling.Retry -> { } is PrchaseResult.GoogplayBilling.PurchaseAcknowledgement.Sucess - is PrchaseResult.GoogplayBilling.PurchaseAcknowledgement.Fail -> // PayYouMoney Billing related is PrchaseResult.PayYouMoney.Sucess -> { } is PrchaseResult.PayYouMoney.Fail -> { } is PrchaseResult.PayYouMoney.Retry -> { } is PrchaseResult.PayYouMoney.PurchaseAcknowledgement.Sucess -> { is PrchaseResult.PayYouMoney.PurchaseAcknowledgement.Fail -> { } // Stripe Billing related is PrchaseResult.Stripe.Sucess -> { } is PrchaseResult.Stripe.Fail -> { } is PrchaseResult.Stripe.Retry -> { } is PrchaseResult.Stripe.PurchaseAcknowledgement.Sucess -> { } is PrchaseResult.Stripe.PurchaseAcknowledgement.Fail -> { } }