This week's book giveaway is in the Design forum.
We're giving away four copies of Design for the Mind and have Victor S. Yocco on-line!
See this thread for details.
Win a copy of Design for the Mind this week in the Design forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Java design - access specifiers

 
Mandy Ram
Greenhorn
Posts: 16
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,
I have a doubt in designing the packages for project.

Let us consider we have 3 packages.

com.example.abcBO;
com.example.defBO;
com.example.ghiBO;

In the package com.example.ghiBO; I have a class which has a method method1() which will be used by the business classes in other packages too(in the packages abdBO and defBO).To accomplish this, I have to make the method method1() as public, so that I can access it any other packages.

The end product of my application is a jar file.I want to package my code as a jar file and give it to the users so that they can use my api.
In the above case, as my method1() is public, the users who uses the jar file also can actually call/use the method1() as its public.But, I don't want the users to call the method1() directly in their code.

To summarize, I want to use the method1() in other packages of my application but I don't want the users to call directly.

The possible solutions I can think of are:

1) Keep the class which is containing the method1() in the packages where we want to use the functionality and make the method1() as protected/default.
- If the method1() needs to be used to two different packages, the same file should be placed in two different packages which is not a good design.(No code reusability)

2) Make the method1() as protected and the classes which wants to use the method1() should extend the class which contains the method1()
-I don't want to do this, as extending this class in another classes wont make sense(wont pass "is a" relationship and not a object oriented approach)

So, Can any help me to understand what needs to be done if I want any method to be used in different packages of my application but not to allow the user who use my jar file to use the same.

Please let me know if am not clear.

Thanks,
Ram





 
Winston Gutkowski
Bartender
Pie
Posts: 10234
58
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Mandy Ram wrote:So, Can any help me to understand what needs to be done if I want any method to be used in different packages of my application but not to allow the user who use my jar file to use the same.

Simply put: you can't. It's a weakness of Java's recognition of packages that it treats, for example, java.util and java.util.regex as totally separate packages; otherwise you'd be able to use package-private (default) access.

However, my question would be: why do you think you need to do this?

In my experience, the need for an "internally-public" method is fairly rare, and might reflect a flaw in your design logic. If the method is that useful, chances are that it may be just as well to create a safe public version; but without a specific example, it's difficult to know exactly.

Winston
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I thought that Java 7 introduced the notion of "modules" or something like that, which allowed more sophisticated access control. Am I imagining that?
 
Mike Simmons
Ranch Hand
Posts: 3037
10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jeff Verdegan wrote:I thought that Java 7 introduced the notion of "modules" or something like that, which allowed more sophisticated access control. Am I imagining that?

That was the plan, but it seems to have fizzled when they tried to sort out Jigsaw vs. OSGi. JSR 294 is listed as "dormant". I imagine we'll get something like JSR 294 when we get Jigsaw. Whenever that is.
 
Mandy Ram
Greenhorn
Posts: 16
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston Gutkowski wrote:
Mandy Ram wrote:So, Can any help me to understand what needs to be done if I want any method to be used in different packages of my application but not to allow the user who use my jar file to use the same.

Simply put: you can't. It's a weakness of Java's recognition of packages that it treats, for example, java.util and java.util.regex as totally separate packages; otherwise you'd be able to use package-private (default) access.

However, my question would be: why do you think you need to do this?

In my experience, the need for an "internally-public" method is fairly rare, and might reflect a flaw in your design logic. If the method is that useful, chances are that it may be just as well to create a safe public version; but without a specific example, it's difficult to know exactly.

Winston


Thanks for your reply.The example can be, I have my DAO methods for deletion/creation/updation/modofocation in the com.example.dao package.

This DAO classes will be called from the service layer which are in different package and these service classes will be called from the main interface implementation class.

I want my users only to use the methods in the interface but not call the DAO methods or service methods directly.

So either I need to keep all the DAO,Service, Interface,Interface implementation classes in the same package? I felt, that is not a good design and so had kept them in different packages.


1) What would be good design for this type of problems?

2) If the answer is that I should keep all of them in a single package and there's no other way, even then I see a flaw that the users who are using my jar file can create the same package structure and even then can use my protected DAOmethods.

Help me out please!

Thanks,
Ram





 
Paul Clapham
Sheriff
Pie
Posts: 20955
31
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Mandy Ram wrote:2) If the answer is that I should keep all of them in a single package and there's no other way, even then I see a flaw that the users who are using my jar file can create the same package structure and even then can use my protected DAOmethods.


That's a very good observation. However if you seal those packages within your jar, that problem will be solved.
 
Mike Simmons
Ranch Hand
Posts: 3037
10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Of course, if your users are determined to use those DAO methods, they can extract the .class files from the jar, then re-jar the contents in an unsealed jar.

Still, this tells users how they're intended to use the code. If they really want to violate encapsulation, they can find ways to do it. But that becomes their problem, not yours.
 
Jesper de Jong
Java Cowboy
Saloon Keeper
Posts: 15214
36
Android IntelliJ IDE Java Scala Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston Gutkowski wrote:However, my question would be: why do you think you need to do this? In my experience, the need for an "internally-public" method is fairly rare, and might reflect a flaw in your design logic.

C# has this, there's an "internal" keyword, and things that are "internal" are visible inside the module (equivalent of a JAR file), but not outside it.

Jeff Verdegan wrote:I thought that Java 7 introduced the notion of "modules" or something like that, which allowed more sophisticated access control. Am I imagining that?

That was the plan a few years ago, but it's not in Java 7 and now there are even doubts if the module system is going to be included in Java 8.

When Java is ever going to have a module system, there will probably also be a mechanism which gives you more control over which classes and methods are visible inside and outside the JAR. But that's not going to be in Java anytime soon.
 
Winston Gutkowski
Bartender
Pie
Posts: 10234
58
Eclipse IDE Hibernate Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Mandy Ram wrote:I want my users only to use the methods in the interface but not call the DAO methods or service methods directly.

OK, so make your interface public and the rest of the DAO stuff package-private.

I guess the real question here is: what are you trying to protect? It sounds to me as though you may be confusing design visibility with runtime access. The latter is an application issue, not a language one.

To me, DAO objects are part of a transportation layer, and don't really need to be public at all, except via business functions, and personally I'd probably look to make that a self-contained package with, as you suggested yourself, public interfaces. Preventing business functions from being executed inappropriately is the responsibility of the application, so I don't really see much harm in exposing them through a public interface.

I think maybe it's the "business function" side of things that you might want to look at a bit more closely. Rather than exposing building-block methods like deleteCustomer(), which deal with the mechanics (the 'how'), expose methods that have to do with an application function, eg: closeAccount() (the 'what').

There's a very good starter article about this style of design here.

Winston
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic