Java Generics – how to strike a balance between expressiveness and simplicity

I’m developing some code that utilizes generics, and one of my guiding principles was to make it usable for future scenarios, and not just today’s. However, several coworkers have expressed that I may have traded off readability for the sake of extensibility. I wanted to gather some feedback about possible ways to resolve this.

To be specific, here is an interface that defines a transform – you start with a source collection of items, and you apply the transform to each element, storing the results in a destination collection. Additionally, I want to be able to return the destination collection to the caller, and rather than forcing them to use a Collection reference, I want them to be able to use whatever collection type they actually provided for the destination collection.

Finally, I make it possible for the type of items in the destination collection to be different from the type of items in the source collection, because maybe that’s what the transform does. In my code, for instance, several source items make up one destination item after the transform.

This yields the following interface:

interface Transform<Src, Dst> {
    <DstColl extends Collection<? super Dst>> DstColl transform(
                Collection<? extends Src> sourceCollection,
                DstColl                   destinationCollection);
}

I tried to be all nice and apply Josh Bloch’s PECS principle (producer extends, consumer super) to make sure the interface is usable with super- and sub-types where appropriate. The end result is somewhat of a monstrosity.

Now, it would have been nice if I could extend this interface and specialize it somehow. For example, if I don’t really care about playing nice with subtypes of the source items and supertypes of the destination items, I could have:

interface SimpleTransform<Src, Dst> {
    <DstColl extends Collection<Dst>> DstColl transform(
                  Collection<Src> sourceCollection,
                  DstColl         destinationCollection);
}

But there is no way to do that in Java. I want to make implementations of this interface something that others would actually consider doing, as opposed to running in fear. I’ve considered several options:

  • Don’t return the destination collection. Seems weird given that you do a transform but get nothing back.
  • Have an abstract class that implements this interface, but then translates the parameters to something easier to use and calls another method “translateImpl()” which has the simpler signature and thus presents less of a cognitive burden for implementers. But then it’s weird to have to write an abstract class just to make an interface user-friendly.
  • Forgo extensibility and just have the simpler interface. Possibly couple that with not returning the destination collection. But then that limits my options in the future.

What do you think? Am I missing an approach I could use?

4

Guava Collections already provides this functionality and if you can hold off a little longer, Java 8 will provide this also :-). FWIW I think your use of ? extends T is the correct idiom, not much you can do given that Java uses Type Erasure

4

I personally do not see much problem with the way you’ve defined your interface, however I am used to toying with Generics and I can understand that your coworkers would find your code to be a bit of a mouthful if that is not their case.

If I were you, I would go with the third solution you state: make things simpler at the expense of potentially having to go back to it later. Because after all, maybe you won’t have to in the end; or you would end up being able to use it fully at some point, but not enough to make up for the effort you’ve put into making this interface so generic, as well as the effort your coworkers may have made to wrap their heads around it.

Another thing to consider is how often you use this interface, and at which level of complexity. Also, how useful this interface proves to be in your project(s). If it allows for high reusability of some components (and not just potential, but actual), it is a good thing. If a much simpler interface works as well 90% of the time, you could ask yourself whether for the remaining 10% a complex interface would prove useful or not.

I do not think it would be a very good idea to not use super and extend, though if you can do without them for the moment, I am sure your colleagues won’t mind seeing them disappear. However, do you really have so many situations where you need to change the type of Collection as well?

Some already given advices are really good, and I agree with Frank about following the YAGNI principle unless you have very good reasons not to. You can still change the code when the need for more complexity will arise, but it is not of much use to develop things you are not pretty sure will be used soon. Also, Martijn’s advice of using Guava is one to consider seriously. I haven’t had the opportunity to use it yet, but I have heard a lot of good about it, including in a presentation where the Transformer pattern got discussed (you can watch it online on InfoQ if you are interested).

As an aside, wouldn’t it be better in your current interface to have destinationCollectionbe of type Class<DstColl>?

I like to wrap Java collections. The proper encapsulation can really help. This pattern does need to be related based on type, but greatly leaves every line of code unaware of the type of collection.

For example suppose there is a list of products. The product class would be immutable and have a few utility methods in it. The product list class can add one product or another list to it. If you wanted to run a method over the whole list, it would be in the product list class. There is a method that would take a filter list class and give a new product list with those filtered. The filtered would be deleted from the original.

There is a filter interface that decides if ONE product passes the filter. There would be a filters list class that has a list of filters and implements the interface by requiring ALL filters to pass a product for the product to pass.

Funny thing is I can a stack and change it to a linked list with no noticeable changes like this. It can loop and do conditionals very noticeable and simply. So it dresses up imperative code and adds flexibility. And is orgonized well.

1

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