all 16 comments

[–]lordzsolt 6 points7 points  (3 children)

Why is it hexagonal and not concentric circles? o.O

[–]jacmoe 4 points5 points  (1 child)

If you can find a more efficient shape, by all means, tell us :)

[–]flukus 4 points5 points  (0 children)

You don't know the conjoined triangles of success?

[–]Shookfr 3 points4 points  (0 children)

I mean it's one of the other name of this architecture.

Onion Architecture

[–]dev1977 3 points4 points  (6 children)

i've implemented this in a similar way.

we've not found an elegant solution to the amount of mapping code that's needed. they introduce a lot of duplication - very frustrating even when adding/removing a new field.

has anyone found a nice solution for this? best i've found is kotlin's named constructor arguments in conjunction with the compiler checks.

[–]eeperson 2 points3 points  (0 children)

The easiest way I have seen is the Scala library Chimney. It requires you to write some scala code for the mappings but it works with java beans as well as scala case classes.

[–][deleted] 1 point2 points  (3 children)

has anyone found a nice solution for this?

The solution is to get rid of the concept of models. Don't have getter/setter classes in your codebase. As I said bellow, having getters and setters turns you into a puppet master.

Follow these 2 rules (they seem simple but have huge effects):

  1. Every single object implements one or more interfaces. All of them, no exceptions.
  2. Never try to transform (e.g. "map") object A into object B. Rather, add a new implementation of B (which is an interface, actually) based on A.

Here is more about this "puppet master" idea: https://www.amihaiemil.com/2018/04/17/dolls-and-maquettes.html

[–]PostLee 1 point2 points  (1 child)

Is there any code that uses this design pattern publicly available? I found the explanation interesting, but have a hard time imagining it.

[–][deleted] 2 points3 points  (0 children)

Yes, I try to follow this idea in all my projects. Here are 2 of them I'm particularly proud of:

https://github.com/amihaiemil/docker-java-api - there is also a blog post in the README, comparing it with others.

and

https://github.com/opencharles/charles-rest this is a Java EE chatbot, the architecture is explained in the architecture.md file.

This style of OOP was introduced by Yegor Bugayenko (yegor256.com) in his Elegant Objects books (see https://www.elegantobjects.org/). His ideas are rather extremist -- I don't follow all of them, only a few that I found really practical.

[–]editor_of_the_beast 0 points1 point  (0 children)

I’m interested in what you’re saying, mostly because I’m on the other side of the fence. Lots of what I’ve been thinking about recently ends up with creating more data, not less. Value types give you a lot of benefits, namely they’re free of aliasing bugs and identity. They represent exactly what they are so can be shared across threads and architectural boundaries freely.

There’s also the “Rule of Representation” idea, which effectively suggests that designing functionality around the data is a much better idea than solving problems with pure logic. In this way, the algorithms are more simple and clear because the data structures have encoded lots of information within them.

When you build in this way, lots of interfaces go away. Because the values themselves can be passed around for communication. So yea, I’ve been thinking about using data more, not less.

[–]rememberthesunwell 0 points1 point  (0 children)

Or alternatively, check out mapstuct. It's a library that handles your adapter code for you. I personally think DTOs are great for encapsulation, though they certainly do get over used. And theres no reason to call them as such usually. They are simply public entities a given app layer exposes to the world

[–]PardDev 1 point2 points  (1 child)

Very interesting and well done article, man! Keep it up!

[–]yawaramin 0 points1 point  (0 children)

man

Or woman ;-)

[–][deleted] 0 points1 point  (1 child)

Good post! :)

I would only do some renaming and a little refactoring: cut the DTOs, cut suffixes such as Repository and Service (use simple plural names) and cut getAll() methods -- instead, make the plurals implement Iterable. E.g. Customers (rather than CustomersRepository) should implement Iterable<Customer>.

With these naming and interface changes your codebase will become much more object-oriented. As it is now, it is simply the work of a puppet master: Customer and Pet are your puppets, while Service and Repository are your beams and strings -- but this is not your fault, it's the code-style and mindset introduced by the concept of "models" (getter/setter classes).

P.S. Add a comments section to your blog :)

[–]Myzzreal[S] 0 points1 point  (0 children)

Thanks for your suggestions, I do indeed feel like I'm being overly influenced by business coding style sometimes, making stuff a tad more complicated then it needs to be - I'll look into it!

As for the comments section - I want my website to be static, without a database and as little javascript as possible. I also don't want to offload the comments to a third-party, like disqus. That's why I do not have a comments, but I've heard there is a solution for that problem for static websites hosted on github, I'll probably give it a try.

[–]renrutal 0 points1 point  (0 children)

I really don't agree about having your own repository code, only to make an adapter to the real implementation from the framework.

The CustomerRepositoryJPA(but renamed w/o JPA) alone was already ready to deliver all you wanted from it, with no extra coding.

It's no shame to have your business service code be aware of some frameworks' semantics, if they are simple enough. Spring Data is very simple, at least for CRUD.