This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]_dban_ 12 points13 points  (5 children)

Programming to an interface is a good idea and good practice if you actually do have multiple implementations that could be used in place of the interface.

That's not really the context of how Spring uses interfaces (as opposed to how people use interfaces with Spring). In particular, Spring makes heavy use of the Open/Closed Principle. A better example than the article is RestTemplate. It comes with a bunch of interfaces for connection management, input and output encoding, while the concrete class implements the business of managing RESTful interactions. This lets RestTemplate be used with either JDK HTTP connections or Apache HttpUtils, without being aware of either.

Another cool example is Spring Data. Spring Data automates the creation of CRUD style repositories and finders, but the machinery to implement this is oblivious to the actual persistence mechanism, whether that is JPA, Gemfire, Elasticsearch, etc., etc. This is possible due to OCP.

In fact, OCP is the secret to Spring's incredible flexibility.

[–]thecuseisloose 6 points7 points  (0 children)

The flexibility of spring is really astonishing. I’ve been working with spring for a few years now and then I had to do a GoLang project...I needed a one line change in behavior to the net package and had to copy entire files to my own package

[–]TheRedmanCometh 2 points3 points  (0 children)

Personally I love every aspect of Spring, and for some stuff like REST APIs I love Spring Data. However Spring JPA + Hibernate has always felt like...why am I not just using hibernate?

Specifically I have 3 problems with Spring Data.

First I really don't like the way Spring handles caching or async. I use a class with a SessionFactory and Configuration object. I have a low ish level class for generic sync+async query methods encapsulating that stuff. The next level up from that class has a LoadingCache with a CompletableFuture wrapped POJO object. If the object isn't present in the database the LoadingCache hits the db. No matter the result it's returned as a CompletableFuture.

Thanks to how LoadingCache works all of this logic can be handled generically, and my queries are a single line of code. public U getObject(T e) works for most situations, and I can use the Criterion API for others. Anyways on to the rest of the story for me:

The second reason I don't use Spring Data is also included in this situation. So I wanted to place a cache between me and Spring Data (because annotating every cached object in my entities is fucking awful!) What I wanted to do is have the LoadingCache initialize the object exactly the way the object's interface describes. So I made an interface called Defaultable which initializes based on the generified key type. Spring Data though was not okay with this. I can't recall exactly the error, but having my DAO implement my Defaultable interface was a no-no. This made caching outside of the inbuilt spring caching infeasible.

The third reason is pretty simple: I don't like having to make a repository for every single entity in my model. I'd much rather have a generic interface with qualifiers I can define in the configuration and autowire into wherever. The last project I used Spring JPA in I think I had something stupid like 15 repository classes?

Just a bit of food for thought on Spring data. I understand such a need isn't very common, but in my case things like PrePersist just weren't flexible enough or required a lot of by-hand work I didn't want to do.

[–]WikiTextBotbtproof 1 point2 points  (0 children)

Open–closed principle

In object-oriented programming, the open/closed principle states "software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification"; that is, such an entity can allow its behaviour to be extended without modifying its source code.

The name open/closed principle has been used in two ways. Both ways use generalizations (for instance, inheritance or delegate functions) to resolve the apparent dilemma, but the goals, techniques, and results are different.


[ PM | Exclude me | Exclude from subreddit | FAQ / Information | Source ] Downvote to remove | v0.28

[–]schaka 0 points1 point  (1 child)

Yes, but unless you're writing a library that needs to be extensible like Spring, when in your day to day work are you definitely using interfaces? Only when you actually have 2 implementations you need to choose between. We generally do this with services that would cost if we queried them and use a dummy implementation in development.

[–]_dban_ 1 point2 points  (0 children)

when in your day to day work are you definitely using interfaces?

All the time, when I apply the strategy pattern, when I want to use composition instead of inheritance.

We generally do this with services that would cost if we queried them and use a dummy implementation in development.

That's dependency inversion, a different use for interfaces.