State pattern and Method delegation problems
Hi,
I have an abstract class, let's name the classSuper and Super provides a lot of protected methods with default implementation for it's child classes. And Super is in packagecom.mycompany.superpackage
Now, I have a class that extendsSuper and let's name itChild. Child class uses State pattern to do it's job, and Child is in packagecom.mycompany.childpackage
Because Child uses state pattern, it has to outsource it's work to it's State objects but to do the work the State objects are required to access the protected methods of theSuper class. The problem I am having is, the State objects are in a different package from that of the Super class and to work around the problem, I have to redeclare them in my Child class and just delegate the call to the Super implementation.
But there are just too many methods to even do that, is it the only way out?
Thank you,
Srikanth
[976 byte] By [
sri1025a] at [2007-10-3 7:09:48]

A couple things here:
What kinds of services do these protected methods provide. Are you sure that this is the only way to structure this?
There are two ways to restrict access to something in Java: 1. make that something protect, package-protected, or private or 2. Restrict access to the Object itself. What I mean is that you can make a method public but only those classes that can get access to the Object reference can call it. Yes, everyone can see that the method exists but that's rarely, if ever, going to matter.
So along the lines of the encapsulation comment above, you could have a public interface and/or public class which has what you want to expose to everyone that wraps a public class (with a non-public constructor) with public methods that you hand to the state objects but to no one else.
> A couple things here:
>
> What kinds of services do these protected methods
> provide. Are you sure that this is the only way to
> structure this?
>
The kind of services the base class provides are very critical which the child classes can't do and shouldn't care. For eg: the base class waits on a lock object for some action to be done by some other module in the code.
I have tried to restructure it a bit, there are other child classes for this base class on which I dont have the direct control. The only reason why I am a state pattern here is to avoid a big switch case or if else statements.
> There are two ways to restrict access to something in
> Java: 1. make that something protect,
> package-protected, or private or 2. Restrict access
> to the Object itself. What I mean is that you can
> make a method public but only those classes that can
> get access to the Object reference can call it. Yes,
> everyone can see that the method exists but that's
> rarely, if ever, going to matter.
>
And I can't make the methods public because they are all as I said critical functions which only the child is allowed to do and that too only through inheritence. It is making perfect sense for the base class to keeping them protected.
It seems like there is no other way but to redeclare them and delegate the call to super.
Thank you!
> And I can't make the methods public because they are
> all as I said critical functions which only the child
> is allowed to do and that too only through
> inheritence. It is making perfect sense for the base
> class to keeping them protected.
I think you missed my point. A member method cannot be called without a reference to an object. If you restrict access to the object, it's just as protected as if you made the methods protected.
> I think you missed my point. A member method cannot
> be called without a reference to an object. If you
> restrict access to the object, it's just as protected
> as if you made the methods protected.
No, I understood what you meant. But I think I missed out in telling a point. I have the Base class which contains two types of methods:
1) Methods that will be used by other parts of the program (just like calling an API in a library)
2) Classes that use this class as it's base and use the protected methods through inheritance.
For eg:
In java.util, we have an abstract class called Calender and java.util.Calendar has a protected method called complete(). This method is used by the child class GregorianCalendar (through inheritance only). That means only the classes in that package and the child classes (GregorianCalendar) of Calendar can access that method.
And if let's say I am writing GregorianCalendar and I am using State pattern for some reason (don't see logic here) and if one of my State object needs to call this complete() method, then the GregorianCalendar must redeclare it in it's class with the same signature and delegate the call to super.
So changing the access modifier to public is not a solution here, cause the one who is going to use this Calendar as an API should not be able to access the complete() method.
> No, I understood what you meant. But I think I missed
> out in telling a point. I have the Base class which
> contains two types of methods:
>
> 1) Methods that will be used by other parts of the
> program (just like calling an API in a library)
> 2) Classes that use this class as it's base and use
> the protected methods through inheritance.
Split the protected methods into a separate class. You can use an inner or nested class for this purpose. Perhaps an example will help.
public class PublicAPI
{
public void method()
{
//...
}
protected ProtectedAPI getProtected()
{
return new ProtectedAPI();
}
public class ProtectedAPI
{
private ProtectedAPI(){}
public void hidden()
{
//...
}
}
}
> Split the protected methods into a separate class.> You can use an inner or nested class for this> purpose.Ahaa... This is a good idea.Thank you,Srikanth
Glad to help.A couple of caveats. Because this class is public, anyone can see the definition and if they get a reference to one of these objects, they can use it. This means you have to be very careful not to let the cat out of the bag, so to speak. Probably the biggest disadvantage of this is if someone is trying to maintain your code and doesn't understand what you are doing, they may spend a lot of time, trying to figure out how to get at this class. A good dose of documentation is in order.