I am curious about java project structure, as well as best practices in regards to classes, interfaces, etc.
If anyone knows of a good open source project that follows good best practices I would appreciate it; it seems like every one is slightly different, with some downright contradicting Oracle documentation on the topic. If anyone could give me a breakdown (or a critique of my structure for a theoretical project it would be appreicated). I understand the /src, bin, lib, doc, etc. as well as com.* structure reasonably well I believe. My issue is exactly WHAT should be in each class, in each file, etc.
My biggest issue is how to exactly break up functionality between classes. For example; I have two classes:
Person.java
Runner.java (This is entry point; is there a naming convention for the entry points? It also seems that classes with main(), run(), etc. are a different 'tier'....how to decide where the entry point should be? Should a class with only main () be made (as well as the actual execution of necessary calculations?)
Person has all the the common variables you would expect....
int height, weight;
String ethnicity;
boolean gender; etc.etc.
Person(int h, int w.....) {this.height=h....}
public getters/setters for all variables
Now I am looking for a program that will do two things:
Take all the attributes of every Person (Say we have instantiated an array of Person()), concatanate them to a String and add that to a new Array.
Order the people by height, then weight, and put into a List.
So for the first thing; should Person class have a method "String concatToString(){}", or should the code that does the concatanetion be in Runner...for example:
Runner.java:
public class Runner {
String getPersonString(Person p) {
StringBuffer Sb = new StringBuffer();
Sb.append(p.get(height));
etc.
return Sb.toString();
}
main() {
for(int i=0; i<arr.len; i++) {
getPersonString(arr[i]);
}
//more code that we will be further executing etc...; mostly just function calls in
class Runner
}
}
Now for the second problem how should I approach this...create a new class; create a priorityQueue and comparator in runner.java? Create another class PersonPQueue that has the comparator in it?
These issues consistently pop up in my code and I am never certain how to split my code correctly. Any great and clear examples would be much appreciated. I have checked out some open source projects and many were too large for me to wrap my head around the design decisions in a reasonable amount of time or had contradictory design choices.
Thanks!
There's a lot going on in your posting. It's a huge topic for a Q&A site. Anyway, I'll answer some specific points.
Take all the attributes of every Person (Say we have instantiated an
array of Person()), concatanate them to a String and add that to a new
Array.
Implement toString() in your Person class, that formats a Person in a certain way. The thing that calls toString() would probably not be in the Person class. Without more context, I can't say for sure.
Order the people by height, then weight, and put into a List.
If this were to be the only way to sort Person, I'd make the getter for the sorted list a method in Person and add the Comparator class to the bottom of the Person class. If the application gets more complex, where several sorts could be used, I'd consider moving the Comparators to their own class files.
My final advice would be to not sweat it too much and to do it the easiest/quickest way. The reason is that many of these decisions are arbitrary and don't really matter in the scheme of things.
I would avoid making the Person.PersonComparator class public outside of Person. The reason is that if something changes and you decide the comparators should be outside of Person, you could eventually have applications out there referring to the internals of Person. Now when you want to re-org Person, a bunch of code has to be changed. What a pain!
What you have to do is to understand the business and their needs going forward. If they are not sure how to sort Person then program defensively, perhaps, and put the comparators outside of it. Or implement an Interface or Facade design pattern to further insulate your code from the fickleness of the users. For items that are well defined, do the easiest thing. This affords more time for testing, reduces unhelpful unneeded abstractions, and increases the chance of project success.
Related
I am trying to create a game involving machines and items. I have a simple item interface and every item will implement this.
I would usually just create a class for every item, but there could potentially be thousands of items, and it doesn't feel right to create thousands of files for all the items. This applies to other large amounts of types of objects I might have. (ground tiles, entities)
I need a type safe way to store all these implemented interfaces. I need to easily be able to create a new item in my code, with only the name of the item.
I was thinking of having a huge class with subclasses holding lots of final constants that would all be anonymous classes, but this also seems like a bad way of doing this.
Is there any good way to do what I have in mind? (Sorry that this is a little vague)
My item interface is currently,
package com.bobona.craftable.model;
import com.bobona.craftable.CraftableGame;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
public interface Item {
String getId();
Map<String, Integer> getValues();
void onUse(AtomicReference<CraftableGame> game, Long entityUsedByIndex);
void onSecondaryUse(AtomicReference<CraftableGame> game, Long
entityUsedByIndex);
}
You're going to need to think about the hierarchy of your game first before you start coding anything.
You haven't described anything about this game, like what's in it or what the objects are or what things can interface with what, so I'll describe a popular game I like - Factorio.
In this game, amongst other things, there are a few things to describe:
Items which allow you to craft other items
Belts which move items
Assemblers which turn items into other items
So I would start with describing the basic hierarchy of how these things interact.
A class for items, and an enum to allow us to describe what the item is and how we can interact with it (if it's craftable or not, which are rules owned by the assemblers)
A class for belts, with as many belt types as we want to support (right now the game has 3)
A class for assemblers, which describe how many items can be accepted at once as well as how fast they craft things
You'll have to understand how your items interact with the environment before you describe rules. For example:
Items can be placed on belts through the use of an inserter.
Items can be placed into an assembler through the use of an inserter.
This will require more thought on your part. But, the number of classes you should have would be small provided that there are only a handful of elements in the world.
This is a difficult design problem, and there is no one size fits all answer as far as I know. As mentioned by Makoto in another answer, much of your approach will be dictated by the actual details of your specific game.
I would usually just create a class for every item, but there could potentially be thousands of items, and it doesn't feel right to create thousands of files for all the items.
I completely agree with this statement.
I need a type safe way to store all these implemented interfaces.
I'm not sure that this is possible (literally as written), if we accept the previous statement that separate classes or interfaces aren't the correct approach. However, if instead of type safe you'll settle for verifiable at runtime by some yet-unspecified mechanism, then I think it's quite doable.
[From Comment] It also wouldn't be nice to use non type-safe values to define items in recipes, as that would quickly become a pain to debug and refactor.
I agree you'll want some sort of verification, but as previously mentioned full-blown compile-time type safety might not be feasible while also avoiding thousands of separate classes. I think the key here is to reliably detect errors, respond to them in a way that doesn't break the game, and generate sensible debug messages for the developer.
There are a lot of ways to go about accomplishing this; which one you choose is going to depend on your exact requirements, your preferences, and a number of implementation details that I have no way of knowing. Some things that I think you should look into or consider:
Inheritance probably won't work at all, for the reasons you've already identified.
Composition or the flyweight pattern might improve things initially, but probably won't scale the way you want.
You could go for a RDBMS approach, as outlined here.
You might try a JSON based approach or equivalent, as outlined here.
The component pattern fits my understanding of your problem very well.
This is an incredibly well written answer detailing how to implement the component pattern for entities (which I think include the types of items you were describing) using bit fields.
This is a very similar question to yours on the gamedev stackexchange with some good answers.
Personally I like the component pattern, and am a fan of using JSON or an equivalent language for specifying the items themselves. Hopefully at least some of the above information will help you as you iteratively modify your architecture to meet your gameplay requirements.
would usually just create a class for every item, but there could potentially be thousands of items, and it doesn't feel right to create thousands of files for all the items.
Yes, you should not be doing that. Classes act as blueprint of your object. We don't create a new class for every new object. If you see that all your items share a common attribute (e.g. name), then those can be used as the attribute of your base class:
public abstract class Entity{
protected String name;
public Entity(String name){
this.name = name;
}
}
Then for those object which is an Item, you can extends it to base class:
//example
public abstract class Monster extends Entity{
protected int damage;
//constructor not shown
}
If you also need to indicate whether an Entity is Ground or Air. You can also use Interface as such:
public Interface OnAir{
}
public Interface OnGround{
}
Then you can have:
//example
public class FlyingMonster extends Monster implements OnAir {
//your other attributes here
}
public class LandMonster extends Monster implements OnGround {
//your other attributes here
}
Now you have the flexibility to manipulate the type of object you want.
To store all your monsters (ground and air):
ArrayList<Monster> monsters = new ArrayList<>();
To store all entities including monsters:
ArrayList<Entity> entities= new ArrayList<>();
The above solution is to reply your question. However, I should mention that in game making, I wouldn't want to create that many classes. But instead I would store all my entities in a datafile. If there are special attributes for your entity. For example, a fire-based weapon which does 30% extra damage to all ice-based creture. I would not code this in Java as well. But instead store it in a script file. That fire-based weapon will then be referenced to the script file.
The same logic applies to your Non-Playable Characters.
So what is the benefit of storing them in scripts and datafiles? You can add / remove / edit your entities without the need to recompile your codes. You can change how the weapons work, how your character behaves, how your NPCs talk without changing anything in Java.
This means that you can now add new items into the game by just typing into the textfile.
Searching for design patterns and better code optimization mostly pops up articles on inheritance and relationships between classes and tools on how to create class diagrams. I would like a little insight on how to, say split, a big class. Am working on a java program with a class that has crossed 1600 lines of code and about 20 methods. What it does is query for data from a data source and generate huge text file.
Now there are lots of data modification logic(for each logic I have created small methods) that goes on to queried data like:
-check data dates of users and perform changes
-append strings
-logic to check if a record needs to be ignored
and storing filtered data in Collection and generating text file. I don't think creating separate class for each small logic is good idea. Perhaps I can create separate utility class and stuff static methods into it? I can't post code for confidentiality issues. If someone can shed a little light to get me thinking in right direction that would be great. Thanks.
The best thing you can do is forget what the code does, and think about what it is.
From the description you gave, you are "still" thinking about what your code is supposed to do. It queries a data source, checks dates, appends strings, filters, etc. This is not wrong for a functional or procedural approach, but not ideal for object-oriented code.
Try a little bit to forget what it supposed to do, and think about what "things" it is about. Are those things Accounts, Users, Machines, VirtualServers, etc. What is that huge text file? Is it a UsageReport, a BalanceSheet, etc.
Once you got the "things", you can start thinking about what "responsibilities" you need to assign each of them. Again, "querying the database" is not a responsibility. You have to do something with the data you get, for example generating a UsageReport, that is a responsibility.
That is OO in a nutshell. A few more pointers: Try to avoid utilities, try to avoid getters, try to avoid setters even more. Try to avoid Services, Processor, Handler, Renderer and similar classes. Those are not "things", but usually procedures in disguise.
Perhaps you should consider whether your initial premise is correct. The single responsibility principle states that a class should only have one reason to change.
In the case of the class you're describing, there are multiple responsibilities: querying a data source, filtering, string manipulation (presentation?), text file generation.
Each of these should be separated into its own class. This decouples the concerns and provides smaller more manageable code.
SRP (Single Responsibility Principle) suggests that we should have only one reason to change a class. i.e. a class should have only one single responsibility. So one class should do only one thing. So in an ideal object oriented environment, we would have classes for each of our work.
Ex:
Assume you are building a Calculator app with basic math support. Assume you have to implement Summing two numbers feature. In ideal way, you would have to do something like this.
public interface NumberMath{
public float value();
}
public class Sum implements NumberMath{
private float num1;
private float num2;
public Sum(float num1, float num2){
this.num1 = num1;
this.num2 = num2;
}
#Overrride
public float value(){
return num1 + num2;
}
}
I think you already found that it will make our code much verbose. So practically no one will follow object orientation (or SRP) in ideal way. Instead most of us would prefer one class containing methods for sum, subtract, division, multiplication etc. It makes our code less verbose.
But in your case 1600 lines of code with 20 methods for 1 class can't be good.
The best ways you can decompose your huge single class into multiple simple classes
Identify independent methods.
Combine similar small methods(behaviors) into a single class with a proper scope for that class, and a name that would properly define that scope.
Try to completely avoid code duplication by adhering into method reuse instead.
Again it is somewhat difficult to provide a very specific answer for your problem since details are limited. Anyway hope this helps. :)
I have just started to learn Java and is curious is it any good practice in Java for good object decomposition? Let me describe a problem. In big software project it's always a big classes like 'core' or 'ui' that tends to have a lot of methods and are intended as a mediators between smaller classes. For example, if user clicks a button on some window, this window's class sends a message to 'ui' class. This 'ui' class catches this message and acts accordingly by doing something with application user interface ( via calling method of one of it's member objects ) or by posting message to application 'core' if it's something like 'exit application' or 'start network connection'.
Such objects is very hard to break apart since they are a mere mediators between a lots of small application objects. But having a classes in application with hundreds and thousands of methods is not very handy, event if such methods are trivial task delegation from one object to another. C# solves such problem by allowing to break class implementation into multiple source files: you can divide god object any way you choose, and it will work.
Any practices by dividing such objects in Java?
One way to begin breaking such a large object apart is to first find a good subset of fields or properties managed by the large object that are related to each other and that don't interact with other fields or properties of the object. Then, create a new, smaller object using only those fields. That is, move all logic from the large class to the new smaller class. In the original large class, create a delegation method that simply passes the request along. This is a good first step that only involves changing the big object. It doesn't reduce the number of methods, but it can greatly reduce the amount of logic needed in the large class.
After a few rounds of doing this, you can begin to remove some of the delegation by pointing other objects directly at the newer, smaller objects, rather than going through the previously-huge object that was in the middle of everything.
See Wikipedia's Delegation pattern discussion for example.
As a simple example, if you have a personnel object to represent staff at a company, then you could create a payroll object to keep track of payroll-related values, a ratings object to keep track of employee ratings, an awards object to keep track of awards that the person has won, and so on.
To wit, if you started out with one big class containing the following methods, each containing business logic, among many other methods:
...
public boolean isManagement() { ... }
public boolean isExecutive() { ... }
public int getYearsOfService() { ... }
public Date getHireDate() { ... }
public int getDepartment() { ... }
public BigDecimal getBasePay() { ... }
public BigDecimal getStockShares() { ... }
public boolean hasStockSharePlan() { ... }
...
then this big object could, in its constructor, create a newly created object StaffType and a newly created object PayInformation and a newly created object StaffInformation, and initially these methods in the big object would look like:
// Newly added variables, initialized in the constructor (or as appropriate)
private final StaffType staffType;
private final StaffInformation staffInformation;
private final PayInformation payInformation;
...
public boolean isManagement() { return staffType.isManagement(); }
public boolean isExecutive() { return staffType.isExecutive(); }
public int getYearsOfService() { return staffInformation.getYearsOfService(); }
public Date getHireDate() { return staffInformation.getHireDate(); }
public int getDepartment() { return staffInformation.getDepartment(); }
public BigDecimal getBasePay() { return payInformation.getBasePay(); }
public BigDecimal getStockShares() { return payInformation.getStockShares(); }
public boolean hasStockSharePlan() { return payInformation.hasStockSharePlan(); }
...
where the full logic that used to be in the big object has been moved to these three new smaller objects. With this change, you can break the big object into smaller parts without having to touch anything that makes use of the big object. However, as you do this over time, you'll find that some clients of the big object may only need access to one of the divisible components. For these clients, instead of them using the big object and delegating to the specific object, they can make direct use of the small object. But even if this refactoring never occurs, you've improved things by separating the business logic of unrelated items into different classes.
The next logical step may be to change the BigClass into a java package. Next create new objects for each group of related functionality (noting in each class that the object is part of the new package).
The benefits of doing this are dependency reduction and performance.
No need to import the entire
package/BigClass just to get a few
methods.
Code changes to related
functionality don't require a
recompile/redeploy of the entire
package/BigClass.
Less memory used
for allocating/deallocating objects,
since you are using smaller classes.
I've seen some cases where this is solved by inheritance: let's say class Big takes care of 5 different things, and (for various reasons) they all have to be in the same class. So you pick an arbitrary inheritance order, and define:
BigPart1 // all methods dealing with topic #1
BigPart2 extends BigPart1 // all methods dealing with topic #2
...
Big extends BigPart4 // all methods dealing with the last topic.
If you can really layer things up, so that the breakage makes sense (Part2 actually uses stuff from Part1, but not vice versa, etc.) then maybe it makes some sense.
The place where I've seen this is in WebWorks, where a single class had tons of getter/setter methods -- the setters used for dependency injection (e.g., URL args passed to the object upon execution) and the getters for making values accessible to various page templates (I think it was JSPs).
So, the breakdown grouped stuff logically, e.g., assuming the class was called MyAction, there was MyActionBasicArgs (fields and setters for basic CGI arguments), extended by MyActionAdvancedArgs (advanced-option args), extended by MyActionExposedValues (getters), extended by MyActionDependencies (setters used by Spring dependency injection, non-CGI args), extended by MyAction (which contained the actual execute() method).
Because of the way dependency injection in WebWorks works (or at least, used to work, back then), it had to be one huge class, so breaking it down this way made things more maintainable. But first, please, please, see if you can simply avoid having a single huge class; think carefully about your design.
Yes, C# provides partial classes. I assume this is what you are referring to when you say:
C# solves such problem by allowing to break class implementation into multiple source
files: you can divide god object any way you choose, and it will work.
This does help make huge classes more manageable. However, I find partial classes best used when one needs to extend code created by a code generator. When a class is as large as you're talking about, it can almost always be divided into smaller classes by proper object oriented design. Using a partial class sidesteps the more correct object oriented design, which is sometimes OK as the end goal is stable, reliable, maintainable code, and not a textbook example of OO code. However, many times, putting the code of a large object into a large number of smaller partial class instances of the same class is not the ideal solution.
If you can possibly find subsets of the properties of the "god" object that do not interact with one another, then each one of those sets would logically make a good candidate for a new object type. However, if all properties of this "god" object depend on one another, then there is not much you can do to decompose the object.
I don't know why you would ever have such a large class.
I suppose if you were using a gui builder code generation and being lazy about it, you might end up in such a situation, but codegen usually ends up nasty unless you take control yourself.
Splitting a single class arbitrarily is a terrible solution to a terrible manufactured problem. (Code reuse, for one thing will become virtually impossible)
If you have to use a GUI builder, have it build smaller components, then use the small components to build up a bigger GUI. Each component should do exactly one job and do it well.
Try not to EVER edit generated code if you can avoid it. Putting business logic into a genned "frame" is just a horrid design pattern. Most code generators aren't very helpful with this, so try to just make a single, minimal edit to get at what you need from external classes (think MVC where the genned code is your View and the code you edit should be in your Model and Controller).
Sometimes you can just expose the getComponents method from the Frame object, get all the components out by iterating through the containers and then dynamically bind them to data and code (often binding to the name property works well), I've been able to safely use form editors this way, and all the binding code tends to be very easily abstracted and reused.
If you're not talking about generated code--Well in your "God" class, does it do exactly one small job and do it well? If not, pull out a "Job", put it in it's own class, and delegate to it.
Is your GOD class fully factored? When I've seen huge classes like this, I've usually seen a lot of copy/paste/edit lines. If there is enough of a similarity to copy and past and edit some section, then there is enough to factor these lines into a single chunk of code.
If your big class is a GUI class, consider decorators--reusable and moves stuff out of your main class. A double win.
I guess the answer to your question is that in Java we just use good OO to ensure that the problem doesn't arise in the first place (or we don't--Java's certainly not immune to the problems you are talking about any more than any other language)
By now my average class contains about 500 lines of code and about 50 methods.
IDE is Eclipse, where I turned “Save Actions” so that methods are sorted in alphabetical order, first public methods, and then private methods.
To find any specific method in the code I use “Quick Outline”. If needed, “Open Call Hierarchy” shows the sequence of methods as they called one by one.
This approach gives following advantages:
I can start typing new method without thinking where to place it in the code, because after save it will be placed by Eclipse to appropriate place automatically.
I always find public methods in the upper part of the code (don’t have to search the whole class for them)
However there are some disadvantages:
When refactoring large method into smaller ones I’m not very satisfied that new private methods are placed in different parts of code and therefore it’s little bit hard to follow the code concept. To avoid that, I name them in some weird way to keep them near each one, for example: showPageFirst(), showPageSecond() instead of showFirstPage(), showSecondPage().
May be there are some better approaches?
Organize your code for its audiences. For example, a class in a library might have these audiences:
An API client who wants more detail on how a public method works.
A maintainer who wants to find the relevant method to make a small change.
A more serious maintainer who wants to do a significant refactoring or add functionality.
For clients perusing the source code, you want to introduce core concepts. First we have a class doc comment that includes a glossary of important terms and usage examples. Then we have the code related to one term, then those related to another, then those related to a third.
For maintainers, any pair of methods that are likely to have to change together should be close by. A public method and its private helper and any constants related to it only should show up together.
Both of these groups of users are aided by grouping class members into logical sections which are separately documented.
For example, a collection class might have several mostly orthogonal concerns that can't easily be broken out into separate classes but which can be broken into separate sections.
Mutators
Accessors
Iteration
Serializing and toString
Equality, comparability, hashing
Well, naming your methods so that they'll be easier to spot in your IDE is really not good. Their name should reflect what they do, nothing more.
As an answer to your question, probably the best thing to do is to split you class into multiple classes and isolate groups of methods that have something in common in each of such classes. For example , if you have
public void largeMethodThatDoesSomething() {
//do A
//do B
//do C
}
which then you've refactored such that:
public void largeMethodThatDoesSomething() {
doA();
doB();
doC();
}
private void doA() {};
private void doB() {};
private void doC() {};
you can make a class called SomethingDoer where you place all these 4 metods and then use an instance of that class in your original class.
Don't worry about physically ordering your methods inside the class, if you can't see it just use Ctrl-O and start typing the method name and you will jump straight to it.
Having self-describing method names results in more maintainable code than artificially naming them to keep them in alphabetical order.
Hint: learn your shortcut keys and you will improve your productivity
Organizing the way you described sounds better than 99% of the Java code I have seen so far. However, on the other side, please make sure your classes don't grow too much and methods are not huge.
Classes should usually be less than 1000 lines and methods less than 150.
Lately I've been struggling with some recurrent design problem which I don't know how to solve elegantly.
Say I am making a game with a couple of players and for each player some connected pieces. Together these pieces form a semi-complex collection or structure. Now I could implement this structure in 2 ways: Either store the structure implicitly through pointers in the pieces themselves i.e:
class BigPiece extends Piece {
Piece opposingPiece, nextPiece, previousPiece, index;
}
Or I could implement this structure in a collection class and keep the information centralized:
class SomeCollection<Collection<Piece>> {
SomeOtherCollection<Collection<Piece>> collection
= new SomeOtherCollection<Collection<Piece>>();
public SomeCollection() {
collection.add(new PieceCollection<Piece>();
collection.add(new PieceCollection<Piece>();
collection.add(new PieceCollection<Piece>();
}
public Piece getPiece(int playerIndex, int pieceIndex) {
collection.get(playerIndex).get(pieceIndex);
}
public Piece getOpposingPiece(int playerIndex, int pieceIndex) {
int nextPlayerIndex = collection.listIterator(playerIndex).nextIndex();
return this.collection.get(nextPlayerIndex).get(pieceIndex);
}
}
Now I usually favor the second one, but that's just based on my guts and I don't have that much experience in class design, especially not with big applications. I can see pros and cons on both sides.
The problem I usually have with the first solution is that you still have to create the associations in some builder or factory which actually links the objects together. This doesn't seem very robust to me. Who can reassure me all the pointers are actually correct throughout the application's lifetime?
The second solution centralizes the data more. This really dumbs down the higher classes though (such as individual Pieces). The problem I usually have with this is that whenever I want to traverse this collection, I have to do it on some lower level. You can't ask a piece 'Hey, what's your opposing piece?'. No, you'd have to get a game object to get a pointer to your collection which you then ask what the opposing piece is. This makes more 'managery' classes which collect data from all around your application (method chaining =( ) to finally implement your algorithm. This seems to violate the Law of Demeter.
Sure I could add a pointer to the corresponding collection from each individual piece as well, but I don't know if that's such a good idea since this only seems to be duplicate information.
My personal recommendation is moreso the second option as opposed to the first. As you pointed out, a piece shouldn't (at least in this context) know what its opposing/next/previous piece is.
A manager class would make more logical sense to better facilitate communication between the classes instead of pieces having references to other pieces. I admit I don't fully know about the Law of Demeter but Wikipedia leads me to believe it is all about encapsulation which the manager classes would actually help as well!
I don't think Pieces (again, in this context) should be able to, say, move another piece. However a manager class would logically want to.
That is my suggestion, I hope it helps!