• Post Reply Bookmark Topic Watch Topic
  • New Topic

Limiting Method Access  RSS feed

 
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I am still rather new to Java and have a general design pattern question.

Let's say I've implemented a typical observer design pattern as follows.

Class A implements an oberser interface which has a public callback method.
Class A object subscribes to class B object and B makes the callback when a specific action occurs.

Is there a way to limit access to the callback method to the observed class? My point being that the callback method is public and anyone could call it and not just the observed object that we subscribed to.

I know that inner classes is an option but is there any other way to do it in Java?
 
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Rob Shoults wrote:I am still rather new to Java and have a general design pattern question.

Let's say I've implemented a typical observer design pattern as follows.

Class A implements an oberser interface which has a public callback method.
Class A object subscribes to class B object and B makes the callback when a specific action occurs.

Is there a way to limit access to the callback method to the observed class? My point being that the callback method is public and anyone could call it and not just the observed object that we subscribed to.


No, not the method per se, but there's no need to limit that.

Create your A instance, pass a reference to it to B, and don't give that reference to anybody else. Since nobody else has a reference to your object, other than B, nobody else can call that method, other than B. Of course, B might delegate to another class, but you don't care about that. You're giving it to B, so you're trusting B to call it appropriately; you don't care whether he does it himself or gives it to somebody else.

I know that inner classes is an option but is there any other way to do it in Java?


Not sure how you think inner classes would make a difference here.
 
Rob Shoults
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
That is a solution for some cases but I was looking for something a little more specific. It probably wouldn't work well in cases where Class A was a highly referenced class like a manager. For example, in a Chat application, the ChatManager class might want to observe ChatSession objects. To say that an instance of ChatManager is only known to a ChatSession is unlikely. In addition, if ChatManager is known only to ChatSession, then this limits the uesfulness of ChatManager in the overall application. It would be nice to have a way to say that method ChatManager.Update was only callable from a ChatSession object.

You asked why I thought inner classes would make a difference.
The solution I am looking for could be accomplished by making class B an inner class of A and providing a private callback method on class A.

I want that type of restriction without the use of inner classes. I say I don't want inner classes because I want a pattern (assuming there is one) that I might be able to use across multiple OO languages. I also think that inner classes can get ugly when mutliple layers are involved.
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Rob Shoults wrote:That is a solution for some cases but I was looking for something a little more specific. It probably wouldn't work well in cases where Class A was a highly referenced class like a manager.


Then you don't have A implement that interface. You have it delegate to some other class that you create one of and hand to B.

If you think you need to limit which classes call a public method, you almost certainly have a design flaw.

One other option, if you control the interface you're implementing, is to make that interface package private.

You asked why I thought inner classes would make a difference.
The solution I am looking for could be accomplished by making class B an inner class of A and providing a private callback method on class A.


That's outside your "A is a highly referenced class like a manager" case, so my original comments apply.
 
Ranch Hand
Posts: 808
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jeff Verdegan wrote:
Rob Shoults wrote:I know that inner classes is an option but is there any other way to do it in Java?

Not sure how you think inner classes would make a difference here.

Because they could be made private, and he would know that no other code could call the notify method. I haven't encountered a situation where I had this concern. It's unusual for observers to be widely accessible anyway, as they tend to be instantiated anonymously.
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Dennis Deems wrote:
Jeff Verdegan wrote:
Rob Shoults wrote:I know that inner classes is an option but is there any other way to do it in Java?

Not sure how you think inner classes would make a difference here.

Because they could be made private, and he would know that no other code could call the notify method.


Which is the same thing as making sure only the B of interest gets a reference to our A in the first place. But yeah, I guess if he hadn't thought of that...
 
dennis deems
Ranch Hand
Posts: 808
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Rob Shoults wrote:That is a solution for some cases but I was looking for something a little more specific. It probably wouldn't work well in cases where Class A was a highly referenced class like a manager. For example, in a Chat application, the ChatManager class might want to observe ChatSession objects. To say that an instance of ChatManager is only known to a ChatSession is unlikely. In addition, if ChatManager is known only to ChatSession, then this limits the uesfulness of ChatManager in the overall application. It would be nice to have a way to say that method ChatManager.Update was only callable from a ChatSession object.

The manager should delegate this to another object. I consider it best for observers to be narrowly focused and minimally accessible.
 
Ranch Hand
Posts: 47
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I want a pattern (assuming there is one) that I might be able to use across multiple OO languages.


How many "multiple OO languages"? 2? 3? Which 2 or 3? How about all of them? o_O
Many of them don't have much access control at all, so you're out of luck with this idea.

If all OO languages were exactly the same, there would be no point in having more than one, but variety is the spice of life, lol (also, it's a pre-requisite for evolution).

Look at the donut and not the hole: having to accommodate language specific idiosyncrasies in a specific implementation of a more general pattern provides you with a perspective on both the language and the pattern.

 
Rob Shoults
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think the best option in this case is to use a standard observer pattern without inner classes. This exposes the callback method on the observer which I was trying to avoid but I can still enforce the callback identity by tracking a reference to the object i subscribed to and then checking it against that reference when it is passed back to the callback. This can be implemented in pretty much any OO language that can handle a standard oberserver pattern.

Thanks for everyone's feedback. I will consider this resolved.
 
It is sorta covered in the JavaRanch Style Guide.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!