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?

5

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();
}

6

Hiding inherited methods is a terrible idea and almost guaranteed to cause you grief.

I would say that this is what Interfaces are for; a “disclosure agreement” between two or more classes that accurately describes what each is allowed to know about the other[s].

Of course, this will get just a mite fiddly if its mixed with inheritance as you describe – should your base class implement the Interface or should each derived class do it for itself? YMMV.

2

You cannot do exactly what you want – see the other answers, but there are a couple of things you could do.

  1. You could have a package private interface that exposes the setters, and a public interface that exposes the getters.
    • You mention that you want to use the setters in multiple packages in your own code. Why is this? This is a code smell for me – if your own code might mess with the internal workings of a class outside of the package where the class is defined, it sounds like you are breaking encapsulation and you should consider refactoring.
  2. You could have a builder/factory object which releases immutable snapshots of these classes.
    • This is the preferred approach, especially if your application uses multithreaded code. Creating a POJO that contains all the data (but none of the mutability) of your original class will add the safety that you desire, plus it will make the code much easier to debug later.

No matter what you do, spending some energy on limiting the situations where shared objects can mutate, especially outside the package, will both help to address this problem and make your code easier to maintain later on.


Further reading:

  • Feature envy Martin Fowler
  • What is a” feature envy” code and why is it considered a code smell?

There are many ways to do that in Java depending on your specific scenario.

By one hand, we could start analyzing if access modifiers could help in this scenario.

For instance, in Java the package can be used to modularize your code.

package a;

public class A {
   private String foo;
   public String getFoo(){ return this.foo; }
   void setFoo(String foo){ this.foo = foo; }
}

In the code above, only classes in the package A would ever be allowed to access the method setFoo since it is defined with a package-level access but everyone could invoke getFoo() since it is public.

If you know the users of your class will be in different package (which is the most typical scenario) than this would work perfectly for you. Use the package to define your cohesive modules and expose only what you want to be exposed.

If you want to hide functionality for the members of your own package than chances are that something could be wrong with the design maybe you need a subpackage or use more interfaces as suggested in the other answer.

1

It is possible that your mistake is taking a too fine-grained approach to access. Are you certain that each user of your class will have different access? Perhaps your actual problem is that you should be implementing a Role mechanism where only a user with a specific role can have access to certain methods.

A Role mechanism can be implemented using different interfaces or even using a Proxy for real fine-grained control.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật