简体   繁体   中英

Should domain classes in a modularised Maven project be based on interfaces?

I have converted a monolitic Maven into reusable multi-module projects. I have created three projects from the original project. Now I have faced a problem. I am creating a new application, but I want to do so by using the two other projects which could be used by other projects in the future. However, the reusable projects have their own domain classes, however I need to extend the functionality of them in the new app. The domain classes in the reusable projects are generic.

Now, is the only choice to extend these classes in the new application that I create? Is this bad? Some of the classes that I have is for instance Question . However, this class needs to have more functionality in the app I create. Are there other solutions to this?

Now, is the only choice to extend these classes in the new application that I create? Is this bad?

In my opinion it's a perfectly valid solution to create a module with generic classes to be extended by applications that use this module. That's how many frameworks work. You should work with interfaces where appropriate but you would still need to hold the generic (potentially abstract) classes in your module to be extended by your application.

Personally, I never use abstract classes and restrict the use of extends to interfaces only. The reason is that class inheritance makes for some pretty messy code. It took me a few years to realize that every time I used class inheritance, there would come a moment where I regretted that decision and had to refactor it to something less convoluted and more flexible. So if you are asking if you should use class inheritance, my recommendation would: no, never! Regardless of what problem you are trying to solve. If your design requires you to use inheritance, it's a problem with your design and you need to rethink it. Ban inheritance and you will end up with better code.

Only use interfaces if the number of implementations is going to be larger than 1. Also, split your interaces into nice chohesive groups of methods. This makes them far more reusable. You can implement more than one and unlike classes, it is fine for them to extend other interfaces. For your domain classes, you probably have a Foo class and you want a Bar class that is very similar but has a few extra methods. In other words, it is partly a Foo and partly something else. That's something you might want to express using interfaces.

In any case, you should keep domain classes as simple as possible. Basically anything but setters, getters, equals, hashCode, and toString, should be off limits. If Java had structs, that is what you would use instead. I've dealt with domain models with inheritance in the past and it's just not worth the trouble. It leads to a convoluted mess of database schemas, mapping code, etc. It's what gives Java a bad name these days.

I've dealt with multi module maven projects before. It seems like a good idea in the beginning until you realize that the number of modules just keeps on increasing. As soon as you have two modules, it will only take a few moments before you'll decide to have three. And actually they don't really provide great encapsulation anyway, as you are finding out with this little dilemma. You are talking about splitting your domain classes over at least two modules and messing up the design further by using inheritance. That makes for some pretty ugly code and all your good intentions with respect to modularization just went out of the window. If you had a unified code base, you'd refactor the domain model to fit both use cases in the right place.

In big enterprises, module structure tends to reflect organizational hierarchy and leads to organization driven architecture. That's a very bad thing. It complicates your dependency management, versioning, release schedules, makes for lengthy builds, bad design, and actually obstructs reuse and effective collaboration (which is probably the exact opposite of what you want to achieve). If you can, put everything back in one module and modularize using packages and apply some sane rules about not allowing things like circular dependencies (use static code analysis tools) and having decent test coverage. Your life will be vastly simpler.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM