Java – Making Methods Invisible/Non-Usable to Some Classes

javasetters

I am developing an application in Java whereby I would like to pass an object as part of an interface into other methods of classes written by other developers in the team. The object I'm passing in has setters and getters in the normal manner, but I don't want some of the classes written by others to access some of the setters of the object passed (different setters would be available to different classes when they use the object). Is this possible in Java? i.e. to define which classes may use which methods in other classes on a per-class basis?

I guess what I'd like to do is something like:

someObject.method(passInObject[but don't give access to passInObject.thisSetter])

Where 'someObject' is an object of a class written by a team member, and 'passInObject' is an object from my class but I want to protect some of the members in it from this specific someObject class.

I'm guessing not and I will need to use inheritance to override those setters I don't want specific other modules to use/see, but it seems clunky to have a new inherited class per using class based on protecting some internal values from only some using classes. I could to a check in the code that a member's value hasn't been changed but that's too late and the damage is done (undoing may be expensive). I could check the name of the class in the setter method itself and do nothing if the name is on a 'banned' list, but that seems very clunky and error prone too. What I want is the calling code to restrict which members can be called in the passed object.

Or am I missing something and there is a common pattern to deal with this?

Best Answer

That cannot be done. Your problems arise from violating ISP.

That said, the only idea I can think of is to force client classes to register with your classes in order to be able to call their methods or they get a NotRegisteredException. Once they register you can check their type and rise a YouAreNotAllowedToCallThisMethodException if the registered class is not in a list of allowed classes.

That's a very inelegant solution and I'd rather correct the ISP violations by segregating interfaces. But, that doesn't prevent your co-workers from using the interfaces you don't want them to use.

The following code examples are from this great answer by user Marjan Venema from another question.

interface IEverythingButTheKitchenSink
{
     void DoDishes();
     void CleanSink();
     void CutGreens();
     void GrillMeat();
}

vs

interface IClean
{
     void DoDishes();
     void CleanSink();
}

interface ICook
{
     void CutGreens();
     void GrillMeat();
}