CloudCoders / Design-Patterns

Project for learning and discuss about design patterns
16 stars 1 forks source link

Added state pattern #25

Closed tonilopezmr closed 7 years ago

tonilopezmr commented 7 years ago

17 Also could be implemented using Flyweight I will investigate more about that.

State pattern is using to change the state of a single object, like semaphore, that change the state internally with objects.

This objects often could be Singletons because don't need more than 1 instance.

Cotel commented 7 years ago

Could this pattern be used to establish an order when preparing noodles? Maybe this pattern fits into Little Kai. It happened to me with Composite pattern that these silly examples are not enough to see where they can be useful 🤔

Cotel commented 7 years ago

I am going to add an alternative version based on this State design pattern in Kotlin

tonilopezmr commented 7 years ago

@Cotel your implementation have not behaviour in your state objects!

Cotel commented 7 years ago

If you look at the example where I took this idea there is no behaviour either:

sealed class AuthorizationState {

    class Unauthorized : AuthorizationState()

    class Authorized(val userName: String) : AuthorizationState()
}

class AuthorizationPresenter {

    private var state: AuthorizationState = Unauthorized()

    fun loginUser(userLogin: String) {
        state = Authorized(userLogin)
    }

    fun logoutUser() {
        state = Unauthorized()
    }

    val isAuthorized: Boolean
        get() {
            when (state) {
                is Authorized -> return true
                else -> return false
            }
        }

    val userLogin: String
        get() {
            when (state) {
                is Authorized -> return (state as Authorized).userName
                is Unauthorized -> return "Unknown"
            }
        }

    override fun toString(): String {
        return "User '$userLogin' is logged in: $isAuthorized"
    }
}
tonilopezmr commented 7 years ago

I know that you are seen in there, but I think this is a not good example because State changes internal state object, and this example the state is changed outside. Overall this is my little improvements about the previous code:

sealed class AuthorizationState {

  object Unauthorized : AuthorizationState()

  //No singleton object because you can use a constructor with different values
  class Authorized(val userName: String) : AuthorizationState()
}

class AuthorizationPresenter {

  private var state: AuthorizationState = AuthorizationState.Unauthorized

  fun loginUser(userLogin: String) {  //another object change the user login
    state = AuthorizationState.Authorized(userLogin)
  }

  fun logoutUser() { //another object change the Authorization state
    state = AuthorizationState.Unauthorized
  }

  val isAuthorized: Boolean  
    get() {
      return state is AuthorizationState.Authorized  //Much better
    }

  val userLogin: String  //Only get the username if is exists nothing about state 
    get() {
      when (state) {
        is AuthorizationState.Authorized -> return (state as AuthorizationState.Authorized).userName
        is AuthorizationState.Unauthorized -> return "Unknown"
      }
    }

  override fun toString(): String {
    return "User '$userLogin' is logged in: $isAuthorized"
  }
}
Cotel commented 7 years ago

Well, the next function in Semaphore is not ideal, but it helps to see how the pattern works in this case. In a real environment, there would be a method which for example would change the state after writing a variable or something. There is no need for this next method.

Anyway, is this pattern ready to be merged?

tonilopezmr commented 7 years ago

What? it's right I think, if you want change the behaviour you only need change a single state object, or add one new.

In the another example if you want change something you are violating the Open-closed principle, because you need add or remove or change the nextLight method, and in my example only added a new State object, or remove.

Cotel commented 7 years ago

So the kotlin example is bad too. It needs to write new methods if he wants more states, isn't i?

tonilopezmr commented 7 years ago

Yes I'm speaking about your example and kotlin design-patterns example

tonilopezmr commented 7 years ago

We are discuss in class

tonilopezmr commented 7 years ago

Well finally what do you think? State is a pattern that change the internal object state with another objects 💯

Cotel commented 7 years ago

I've made some changes to this pattern so the state now is truly internal and no one can modify it from outside unless they use the defined method for it.