I'm having a problem using the state pattern, I don't know how to check if a State
is of a certain instance without using instanceOf
(because that is considered a bad practice).
TCPConnection
holds a TCPState
object.
Let's say I want to get all the TCPConnections
that have the state TCPEstablished
. How would I do this?
A way would be:
public List<TCPConnection> getAllEstablished() {
List<TCPConnection> list = new ArrayList<TCPConnection>();
for(TCPConnection tcp : allConnections) {
if(tcp.getState().instanceOf(TCPEstablished)) {
list.add(tcp);
}
}
return list;
}
But this uses instanceOf
and I would prefer not to use that. Are there any better ways? Or is my use of instanceOf
valid?
Yes, the use of instanceOf
is considered a smell. Furhermore, checking for the type of a state object goes contrary to the idea of the state pattern itself (encapsulate state-dependant behavior in the subtypes such that such checks become unnecessary).
Nevertheless you could technically get rid of the instanceOf
by adding another operation to TCPState
, e.g. bool isEstablished()
, and implement it such that it returns true
only on TCPEstablished
.
interface TCPState {
...
boolean isEstablished();
}
class TCPEstablished implements TCPState {
...
boolean isEstablished() {
return true;
}
}
class TCPClosed implements TCPState {
...
boolean isEstablished() {
return false;
}
}
Add the operation to TCPConnection
:
class TCPConnection {
...
boolean isEstablished() {
return this.getState().isEstablished();
}
}
Then your operation getAllEstablished
would look like this:
List<TCPConnection> getAllEstablished() {
List<TCPConnection> list = new ArrayList<TCPConnection>();
for(TCPConnection tcp : allConnections) {
if(tcp.isEstablished()) {
list.add(tcp);
}
}
return list;
}
instanceOf
is gone. But is it worth it?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With