Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OO-design issue

I have a system where I have to model a household, which has a TVSubscription. This can either be a digital one, or an analog one.

A user logs into a SetTopBox. He can then rent Movies.

So the current scheme is the following:

//Existing instantiated variables in scope
aMovie
aUser
aSetTopBox
//End

--> execute this command: 
aUser rent: aVideo on: aSTB

Code:
User>>rent: aVideo on: aSTB
aVideo rentBy: self on: aSTB

Video>>rentBy: aUser on: aSTB
aUser rentActionMovie: self on: aSTB

User>> rentActionMovie: aMovie on: aSTB
aSTB rentActionMovie: aMovie by: self

STB>>rentActionMovie: aMovie by: aUser
(loggedInUser isNil)
    ifTrue: [ loggedInUser := aUser.
              --Do stuff to charge the movie]
    ifFalse: [ -- Show error that user is not logged in]

Technically speaking this is correct. But I have (Sorry for being anal) issues with this:

I have to pass aSTB 2 methods calls down to eventually use it. The double dispatch here is needed because I have Child and Adult and they can rent AdultMovie and ChildrensMovie. Therefore I use a double dispatch instead of typechecking (requirement). Therefore I thought of the following solution:

I can store currentlyLoggedIn on aSTB, and store a loggedInOn on aSTB. This however, makes the objects point to eachother.

My gut feeling tells me this is a bad smell. I'm not really sure how to fix it though.

Ideally I would like to do something like this:

aUser rent: aMovie.
like image 896
Christophe De Troyer Avatar asked Oct 03 '22 03:10

Christophe De Troyer


1 Answers

I am no expert, but just an alternative off the top of my head...

STB>>initialize
    aUser := UserNotLoggedIn new.

STB>>rentMovie: aMovie by: aUser
    (aMovie okayFor: aUser)
        ifTrue:  [ --Do stuff to charge the movie]

AdultMovie>>okayFor: aUser
    ^aUser canRentAdultMovie

ChildrensMovie>>okayFor: aUser
    ^aUser canRentChildMovie

User>>canRentChildMovie
    ^true

User>>canRentAdultMovie
    self displayErrorCannotRentAdultMovie
    ^false

Adult>>canRentAdultMovie
    ^true

UserNotLoggedIn>>canRentChildMovie
    self displayErrorUserNotLoggedOn
    ^false

UserNotLoggedIn>>canRentAdultMovie
    self displayErrorUserNotLoggedOn
    ^false

Child "just the same as User"

User>rent: aMovie.
    aSetTopBox rentMovie: aMovie by: self.

aUser rent: aMovie.

like image 70
Ben Coman Avatar answered Oct 12 '22 10:10

Ben Coman