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

Sealed Classes for state management

Sealed Classes for state management

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 -> { } }