OO encapsulation - object conversion to get to "innards"
I have a object in which I'm trying to follow the "Tell Don't Ask" principle. So without showing the code I'm telling the object to do things. The object is a ball, so I have the ability to serve the ball towards another object. This method will internally adjust the velocity of the ball to head towards the object it was served to.
The problem I have is when I wish to display the ball on a GUI. For this I will need the x and y coordinates, so when I'm drawing I'm tempted to add a method on the ball to c开发者_运维百科onvert to a DTO which will allow me access to the x and y positions.
The problem I have with this I could just forget about this DTO, add the properties to the ball and be done with it, however this will mean the ball could be adjusted witout adhering to the core logic I'm working with.
Is there any advice for this scenario?
Here's some pseudo code to help visualise the problem. The ball's DTO is used within the ball to manage it's internal state, yet at some point I need to know where it is. Every way I come up with violates the whole point of encapsulation.
ball = new Ball();
ball.ServeTo(player)
// Logic, blah blah blah...
// Wish to draw now...
drawer.Draw(ball.ToDTO())
// Problem is I could easily do this
ball = ball.ToDTO()
ball.x = 100
// Just violated core logic, should not be able to move here etc...
I strongly suggest reading two articles on subject "Why Getters and Setters Evil" and "More on getters and setters". Especially latter one offers using builder pattern solution to this problem.
- Why getter and setter methods are evil
- More on getters and setters
You can implement only getters and not setters to limit access. Alternatively, the ball could draw itself by calling some kind of draw behavior and passing in the "drawer" to use.
精彩评论