OO设计问题

Chr*_*yer 5 oop smalltalk pharo

我有一个系统,我必须建模household,其中有一个TVSubscription.这可以是一个digital一个,或一个analog一个.

user登录到SetTopBox.然后他就可以租了Movies.

所以目前的方案如下:

//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]
Run Code Online (Sandbox Code Playgroud)

从技术上讲,这是正确的.但我有(抱歉肛门)问题:

我必须传递aSTB2个方法调用以最终使用它.需要在此双重派遣,因为我ChildAdult他们可以租AdultMovieChildrensMovie.因此,我使用双重调度而不是类型检查(要求).因此我想到了以下解决方案:

我可以存储currentlyLoggedInaSTB,并存储loggedInOnaSTB.然而,这使得对象指向彼此.

我的直觉告诉我这是一种难闻的气味.我不确定如何修复它.

理想情况下,我想做这样的事情:

aUser rent: aMovie.
Run Code Online (Sandbox Code Playgroud)

Ben*_*man 1

我不是专家,只是我脑海中的另一种选择......

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.
Run Code Online (Sandbox Code Playgroud)

a用户租用:aMovie。