Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
I am about to develop a Java desktop application, which I would like to keep it in module wise, so it is easy for me to customize. For an example, let's take a billing system. Right now I can divide it to few modules
Accounting
Billing
Print Bill
Email Bill
If someone told me "I don't need to print the Bill", then I can remove the "Print Bill" module and so on.
I have seen in some applications (C++) where they have been developed as seperate applications and combined together somehow.
In Java, what is the best way of module wise development? The best way I know is creating packages and managing things via interfaces.
Whatever it is, the main advantage would be minimizing the effort when customizations appear. What are the suggestions?
Answering a question for "best way" is hard, because you could only answer it with "it depends" - on the specific circumstances as well as the opinion of the developer.
What I would suggest you to do is take an approach that defines clear interfaces between modules and maybe split them into separate jars. This allows you to hide the implementation details in the abstraction of the interface and you do not need to care about that but only call the correct interface.
Also for high customisation I'd favor "configuration over code" which means that you select the used modules by configuration and not by deploying specific binaries. Again with separate jars both is possible.
So I think your idea of using different packages and interfaces seems very valid to me. Maybe I'd pack them to different jars or use them depending on the configuration.
I think using a bunch of different executables and connect them by pipelining them is also an option, but I somehow dislike it, because it adds increased effort in handling the communication between different executables. This is an unnecessary overload when your application is handling it "all in one".
Separate the parts into artifacts, built into numerous jars. Hide everything behind interfaces. Then have an "application" project using all needed artifacts and integrating them together. Use dependency management tool like Maven or Gradle to build it all together, and Spring to integrate the modules in the resulting application.
For a desktop application, you may want to use some platform like Eclipse RCP or Netbeans RCP - they have each their own plugin system and dependency injection / integration frameworks.
A naive approach would be to only use packages to functionally partition your code. You also want your packages to have as few dependencies as possible. Any shared dependencies should be "moved up" in an other package like "core" or something else that would be a dependency of all the packages that need it.
A quick example based on yours :
package client would make it possible to manipulate clients
package accounting would handle client account information and depend on client
package billing would handle billing and depend on client (or accounting?)
package billing.receipt would handle receipt generation and depend on billing (and indirectly on client)
package billing.receipt.printing would handle receipt printing and depend on billing.receipt (and indirectly on billing and client)
package billing.receipt.email would handle receipt email sending and depend on billing.receipt (and indirectly on billing and client)
For a more industrial version, you should separate your code into different java projects with interdependencies that you could build into a single application with a tool like Maven. The packages separation would still hold, but using different projects and a formal build process would help enforcing weak-coupling.
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I have 2 services (service1 and service2),and both services are using the same data model "studentModel",I'm wondering how to share the studentModel between the two services.
1.Build a studentModel.jar , and all the services refer to this jar
2.Copy & Paste code
Please help me how to reuse code in microservices architecture.
I would recommend going even further. From my experience, the best approach would be the following:
to build a separate module with all models for the microservice
to build a separate client library (module) for the microservice
Following this approach, you can release a new client library each time you change your micro-service - it will be easy to maintain and manage.
In addition, it will help you to save a lot of time when your system grows. Just imagine, you're going to use your core service (e.g. user service or profile service) as a dependency for all other services. Copy-paste is definitely not an option in this case.
Update. Currently, we have such things as OpenAPI and GraphQL in our toolsets. It's enough to design a good schema for the supplier service and simply use code generation tools for consumers.
When it comes to microservices, its ok to keep duplicated files because you might end up with a distributed monolith. Remember the Bounded Context from DDD and use your thought process. No shared library means no coupling.
But again the DRY (Don't Repeat Yourself) says you should not have duplicate, but to what extent?
One failure in one Library should not cause all your microservices to fail using that library, then the whole purpose of microservice is of no use.
There are tools to shared code among microservices, you can have a look into https://bitsrc.io/
All these are my thought, there must be some better way.
For better version control, I would recommend you to build a jar and add it as a dependency on your microservices. Alternatively, you can also explore git sub modules by putting duplicate codes in sub modules and utilizing it in your respective microservice module.
I'd like to create a project in Java that as a shell or box or controller for other parts of itself (there might be an adequate naming for it). I want it to be possible to load additional program parts after the installation of the program, like plugins or addons or how you might call them.
As an example one could think of a program called Calculator having a MenuBar on top giving the possibility to load several JFrames (or JInternalFrame) that provide different calculation ways, for instance ListSums, InvoiceSums, BreakEvenCalculator, ... (and so on).
Now what I want to create is a kind of mask giving me the possibility to import for instance a new JInternalFrame with weather calculations. Literally adding a couple of menu entries and a set of new masks. Well, and this kind of plugin or addon shall be downloaded from a link I provide.
I already tried myself in googling for some ways how to do that, but I'm not quite sure what to search for.
Is there any site providing information about how to create plugins or addons like this?
Cheers in advance for every helpful soul!
Since your question is not very specific I am not sure if I understood correctly but I will try to answer anyways.
I am guessing, that you want to load java code dynamically at runtime (without restart / recompile of your program).
So there are some different approaches to achieve that:
1. Own "Framework"
You create a generic GUI which is able to generate GUI Elements dynamically on the fly. Then you define in your modules via you own DSL or XML your Module. The GUI is then generated based on your definitions which you can load dynamically. I used that once to automatically generate a GUI where a user can build his own dynamic reports and once for come generic installer tool which could create a new workspace with checkout of projects in one case and build & deploy & run a webapp in tomcat.
Pros:
Easy to start with
You know the code (because you have written it)
Cons:
Is very specific
time-consuming since it supports only the things you programmed into the framework
you can easily develop bad code if you do not know exaclty what you do / the requirements change / ...
2. Use some execution engine (e.g. Rhino or Nashorn (Java 8) )
You can develop your modules in JS and either generate the GUI from some modules (like described in 1.) - which I would do in case of a Swing GUI or even create the output from JS (which I would do in case of a WebApp since its just printing html)
Pros:
You can do everything which is supported in the engine / the module language
You are much more flexible than with 1.
Much less time needed
Cons:
Need to understand how the engine works
Starting is not as easy as 1. since you have more external dependencies
you are limited by the limits of the engine (in case of js e.g. the sandboxing like no writing to files, no swing integration / interaction by default,...)
3. OSGi / Spring dm Server
You can as well create your modules in java with own packaging and deploying on the fly into your application with OSGi.
If you want this for an WebApplication I would look into Spring dm Server: http://static.springsource.com/projects/dm-server/1.0.x/programmer-guide/html/ch03s02.html
Otherwise, OSGi should be the better fit.
Since there is much documentation out there on these two topics I wont go more into deep here.
Pros:
You can do everything because your modules will be just java
You use java well established standard mechanisms
Cons:
Need to understand how the framework works
Starting is not as easy as 1. or 2. since you will have to understand the techniques used
more external dependencies
If my answer helped you, I would be happy if you accept it, if not please provide more detailled information on what you want to achieve and what are your requirements.
Regards, Manuel
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
Recently I came across this javalobby post http://java.dzone.com/articles/how-changing-java-package on packaging java code by feature.
I like the idea, but i have few questions on this approach. I asked my question but didn't get a satisfactory reply. I hope someone on StackOverflow can clarify my questions.
I like the idea of package by feature which greately reduces the time for moving across the packages while coding and all the related stuff will be at one place(package). But what about interactions between the services in different packages?
Suppose we are building a blog app and we are putting all user related operations(controllers/services/repositories) in com.mycompany.myblog.users package. And all blog post related operations(controllers/services/repositories) in com.mycompany.myblog.posts package.
Now I want to show User Profile along with all the posts that he posted. Should I call myblog.posts.PostsService.getPostsByUser(userId) from myblog.users.UserController.showUserProfile()?
What about coupling between packages?
Also wherever I read about package by feature, everyone says its a good practice. Then why many book authors and even frameworks encourage to group by layers? Just curious to know :-)
Take a look at uncle Bob's Package Design Principles. He explains reasons and motivations behind those principles, which I have elaborated on below:
Classes that get reused together should be packaged together so that the package can be treated as a sort of complete product available for you. And those which are reused together should be separated away from the ones those are not reused with. For example, your Logging utility classes are not necessarily used together with your file io classes. So package all logging them separately. But logging classes could be related to one another. So create a sort of complete product for logging, say, for the want of better name commons-logging package it in a (re)usable jar and another separate complete product for io utilities, again for the want of better name, say commons-io.jar.
If you update say commons-io library to say support java nio, then you may not necessarily want to make any changes to the logging library. So separating them is better.
Now, let's say you wanted your logging utility classes to support structured logging for say some sort of log analysis by tools like splunk. Some clients of your logging utility may want to update to your newer version; some others may not. So when you release a new version, package all classes which are needed and reused together for migration. So some clients of your utility classes can safely delete your old commons-logging jar and move to commons-logging-new jar. Some other clients are still ok with older jar. However no clients are needed to have both these jars (new and old) just because you forced them to use some classes for older packaged jar.
Avoid cyclic dependencies. a depend on b; b on c; c on d; but d depends on a. The scenario is obviously deterring as it will be very difficult to define layers or modules, etc and you cannot vary them independly relative to each other.
Also, you could package your classes such that if a layer or module changes, other module or layers do not have to change necessarily. So, for example, if you decide to go from old MVC framework to a rest APIs upgrade, then only view and controller may need changes; your model does not.
I personally like the "package by feature" approach, although you do need to apply quite a lot of judgement on where to draw the package boundaries. It's certainly a feasible and sensible approach in many circumstances.
You should probably achieve coupling between packages and modules using public interfaces - this keeps the coupling clean and manageable.
It's perfectly fine for the "blog posts" package to call into the "users" package as long as it uses well designed public interfaces to do so.
One big piece of advice though if you go down this approach: be very thoughtful about your dependencies and in particular avoid circular dependencies between packages. A good design should looks like a dependency tree - with the higher level areas of functionality depending on a set of common services which depend upon libraries of utility functions etc. To some extent, this will start to look like architectural "layers" with front-end packages calling into back-end services.
There many other aspect other than coupling for package design i would suggest to look at OOAD Priciples, especially package design priciples like
REP The Release Reuse Equivalency Principle The granule of reuse is the granule of release.
CCP The Common Closure Principle Classes that change together are packaged together.
CRP The Common Reuse Principle Classes that are used together are packaged together.
ADP The Acyclic Dependencies Principle The dependency graph of packages must have no cycles.
SDP The Stable Dependencies Principle Depend in the direction of stability.
SAP The Stable Abstractions Principle Abstractness increases with stability.
for more information you can read book "Agile Software Development, Principles, Patterns, and Practices"
First off, I'm coming (back) to Java from C#, so apologies if my terminology or philosophy doesn't quite line up.
Here's the background: we've got a growing collection of internal support tools written for the web. They use HTML5/AJAX/other buzzwords for the frontend and Java for the backend. These tools utilize a lightweight in-house framework so they can share an administrative interface for security and other configuration. Each tool has been written by a separate author and I expect that trend to continue, so I'd like to make it easy for future authors to stay "standardized" on the third-party libraries that we've already decided to use for things like DI, unit testing, ORM, etc.
Our package naming currently looks like this:
com.ourcompany.tools.framework
com.ourcompany.tools.apps.app1name
com.ourcompany.tools.apps.app2name
...and so on.
So here's my question: should each of these apps (and the framework) be treated as a separate project for purposes of Maven setup, Eclipse, etc?
We could have lots of apps appear here over time, so it seems like separation would keep dependencies cleaner and let someone jump in on a single tool more easily. On the other hand, (1) maybe "splitting" deeper portions of a package structure over multiple projects is a code smell and (2) keeping them combined would make tool writers more inclined to use third-party libraries already in place for the other tools.
FWIW, my initial instinct is to separate them.
What say you, Java gurus?
I would absolutely separate them. For the purposes of Maven, make sure each app/project has the appropriate dependencies to the framework/apps so you don't have to build everything when you just want to build a single app.
I keep my projects separated out, but use a parent pom for including all of the dependencies and other common properties. Individual tools / projects have a name and a reference to the parent project, and any project-specific dependencies, if any. This works for helping to keep to common libraries and dependencies, since the common ones are already all configured, but allows me to focus on the specific portion of the codebase that I need to work with.
I'd definitely separate these kind of things out into separate projects.
You should use Maven to handle the dependencies / build process automatically (both for your own internal shared libraries and third party dependencies). There won't be any issue having multiple applications reference the same shared libraries - you can even keep multiple versions around if you need to.
Couple of bonuses from this approach:
This forces you to think carefully about your API design for the shared projects which will be a good thing in the long run.
It will probably also give you about the right granularity for source code control - i.e. your developers can check out and work on specific applications or backend modules individually
If there is a section of a project that is likely to be used on more than one project it makes sense to pull that out. It will make it a little cleaner as well if you need to update the code in one of the commonly used projects.
If you keep them together you will have fewer obstacles developing, building and deploying your tools.
We had the opposite situation, having many separate projects. After merging them into one project tree we are much more productive and this is more important to us than whatever conventions happen to be trending.
We currently have an application which is essentially a fully-functional demo for potential clients. All the functionality is there. However, we use generic branding/logos, call our own web services (which would later be swapped out for calls to client web-services), etc.
Here is my question. If we have two different clients, we would prefer as little duplicate code as possible. I understand that this could be done -- from a java perspective -- by simply including a shared JAR. However, we will need to change around resources. Also, one client may not want some functionality that another client does want. On top of this, if we are doing general bug fixes, we will normally want these fixes to be in both versions of the application.
We are using Git for version control and Maven for building the project.
One option we discussed is simply branching the project and maintaining separate versions. However, then we would have to manually merge changes that we want reflected in all versions of the app.
Another option we discussed is somehow swapping out resources, etc. using maven profiles. However, if we need to make any non-superficial changes to the code itself, this could be a problem. We might have to get into factories and different implementations.
Does anyone have recommendations on the best way to handle this?
We use a library project with git submodules to handle all of our similar projects. The master project is pretty hefty but we use a configuration file to determine what features should be in the finished product.