I'm trying to make a class which represents an Ability of a Champion in my game. The impediment I've faced is that I don't know how to design an Ability class with multiple properties i.e. damaging, stuning, slowing. My idea was to create enum class which represents all these properties and then assign them to my abilities, for example:
public enum Effect {
DAMAGE,
SLOW,
STUN,
...
}
But what if I have an ability that stuns and deals damage at the same time? Should I create an Effect[] array and to deal with it somehow or should I create interface-markers like Serializable(it's the creaziest idea I've had)? Or maybe there is some technique for cases like that?
An array with Effect objects seems fine, a list would be even better. You can even create your own wrapper class to provide additional methods calculating entity properties based on applied effects.
For example:
public class Effects
{
public int calculateDamage(int baseDamage)
{
int damage = baseDamage;
if (effects.contains(Effect.DAMAGE)) {
// some effect stacking :)
damage *= 1.5 * Collections.frequency(effects, Effect.DAMAGE);
}
if (effects.contains(Effect.STUN)) {
damage = 0;
}
return damage;
}
private final List<Effect> effects = new ArrayList<>();
}
Collections.frequency() is a utility method from Apache Commons library, which I highly recommend.
you can create a class of type Effect with all properties as Boolean attributes and then assign true or false to them as you like, and if you like to extend properties to ones you can't decide at compile time think about putting one hashmap of type HashMap in Effect class
Related
I'm writing a code in Java, one for creating matrices specifically, and I've many different methods I use. I'm trying to separate like methods into separate files, so they're easier to modify, but I can't come up with a way to do it without horrendous inheritance. Is what I'm trying to do possible, or should I bite the bullet and put them all on one file?
For example, I have 4 separate files. The only way I can think of where I don't have to import many different classes is:
MatrixBase --> MatrixSort --> MatrixMethods --> Matrix
I get the feeling that this inheritance for one class is unnecessary, when all I want to do is store similar method in the same file.
What is my best solution?
Strategy is one of the OOP design patterns that allows to separate methods from objects. Although it's primary purpose is to provide a mechanism of supplying alternative algorithm implementations at runtime, you may want to check if it suits your case.
You are likely not using the best Object Oriented Design Approach if you have too much code in a single class. Also, importing many classes is fine in Java. However, I will give you a reasonable option within the bounds of your question. hope it helps.
Try using composition in order to make the functions available in a single location while still breaking them logically into separate classes. ... So lets assume you have MatrixMath as your root class to access all of your matrix manipulation. Lets suppose you want to have a collection of algebra and a collection of sorting.
// container that has all of your matrix math objects
public class MatrixMath {
MatrixMath(){};
public final MatrixAlgebra algebra = new MatrixAlgebra();
public final MatrixSort sort = new MatrixSort();
}
// put all of the algebra type functions here
public class MatrixAlgebra {
MatrixMultiply(){};
public static Matrix multiply(final Matrix a, final Matrix b) {
Matrix result;
// do something
return result;
}
}
// and your sorting functions here...
public class MatrixSort {
...
}
now to access matrix multiply you can use this:
// create a reference to your MatrixMath class so that you
// can use your function.
public class Matrix {
final MatrixMath math = new MatrixMath();
Matrix times(Matrix other) {
return math.algebra.multiply(this,other);
}
}
If you are truly just making functions and you make everything static you can use static references everywhere.
One approach is to make your functions static and move them into static utility classes.
So instead of
Matrix m = ...;
Matrix mt = m.transpose();
float det = mt.determinant();
Vector x = ..;
Vector b = ..;
Vector y = m.solve(x,b);
You end up with
Matrix m = ...
Matrix mt = MatrixGeometry.transpose(m);
float det = MatrixMath.determinant(m);
Vector x = ..;
Vector b = ..;
Vector y = LinearAlgebra.solve(m,x,b);
The fun part is working out which functions should stay member functions, and which should be static.
There is a down-side if you're using inheritance in your Matrix type though. If your heirachy looks like this,
static interface Matrix { ... }
class DenseMatrix implements Matrix { ... }
class SparseMatrix implements Matrix { ... }
class BandedMatrix implements Matrix { ... }
Then you will probably end up with implementations containing type based dispatch:
class LinearAlgebra {
public static Vector solve(Matrix m, Vector x, Vector b) {
if(m instanceof DenseMatrix)
return solveDense((DenseMatrix)m, x, b);
if(m instanceof SparseMatrix)
return solveSparse((SparseMatrix)m, x, b);
...
}
private solveSparse(SparseMatrix m, Vector x, Vector b) {
...
}
}
Which many would consider a "code smell". You can get around this by using a double-dispatch / visitor style in your Matrix class, but that is a bit more pain to set up - and in many cases is not really much more readable/maintainable.
You should not create such a big class--it's a really bad idea.
You need to start evaluating how you can extract portions of your functionality into other small classes. The other classes need not be exposed to users, they can be package private if you like (this is what you get if you don't supply an access level)
You can easily have a single class that is a "Matrix", but that can just be a facade over a large number of other classes.
I'm not sure if it is the same kind of thing you are doing but I spent a while developing a matrix class with a replaceable number implementation that would work with special types like rational and complex types the matrix could manipulate.
Java is miserable at this kind of work (and I'm probably the strongest java proponent you'll run into, so that's saying an awful lot!) The main problem is that number types don't have a useful base type, but to do this kind of work it really helps to be able to overload operators (Something I generally don't consider to be anything more than an attractive nuisance)
If this is the kind of thing you are working on, I highly recommend looking into groovy for the topmost level (using the classes). If that's not the kind of thing you're working on then sorry about the rant but you probably stopped reading before here anyway :)
I have a function in which I have to send two states of an object:
void functionA(MyObject objStateOff, MyObject objStateOn){
}
And there would always be only two types states: on and off
But instead of having two parameters of the same type for this function, I was hoping to combine them. SO I was thinking of having a HashMap<Boolean, MyObject>.
But since this map would at most contain only two entries, it seems to be a waste of resources, as I am developing for Android.
So, is there a better way of passing these two objects, without having two either use a HashMap or having two parameters in the function signature?
Update: I want to see if any other method would basically improve the following:
Readability, performance(even though i think that won't change) and maintainability
Thanks.
I would create a custom class with two MyObject fields, and accessors for each. This has a couple big advantages based on your goals:
Readability: The accessor methods describe what each object does. states.get(true), what does that mean? states.getFooOnState(), that's pretty clearly getting me the state for when foo is on.
Maintainability: Adding new state is much easier, if you ever need to do that; you just add a new field to this class. Maybe you'll want a MyObject for when the foo's state is unknown/initializing, or maybe you want to add event handlers that get triggered when foo gets turned on or off. One disadvantage to your current approach is that these sorts of things will cascade through your signatures: functionA needs to add a new argument, which means functionB which calls functionA needs to now get that extra parameter (so it can pass it to functionA), which means functionC needs to get it, and so on.
One caveat to the readibility issue is that you'll be gaining readibility where you use these MyObjects, but not where you first set them up. There, you'll be creating a new MyObjectState (or whatever you name it), and the constructor will look just as generic as your functionA:
MyObjectState s = new MyObjectState(objStateOff, objStateOn);
You could address that by creating a builder for MyObjectState, but that'd probably be overkill.
Performance wise, you're not going to get better than what you already have. But a custom class is going to add fairly minimal overhead (in terms of extra memory, GC activity, etc) in the grand scheme of things.
There's always the Pair class (http://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/tuple/Pair.html). Or you could pass a MyObject[] with two elements.
I think this question doesn't have the only correct answer. Personally I would leave the function with two parameters, because that's not too much really and names of this parameters can help me to avoid confusion like "which element of map/array is for on state?".
You can always use composition.
Create a class that contains two objects of MyObject type.
It may look overkill at first, but it's safer than array.
Hope this helps.
You could use a simple ArrayList.
ArrayList<MyObject> a = new ArrayList<MyObject>();
a.add(objStateOff); a.add(objStateOn);
void functionA(ArrayList<MyObject>) {
...
}
functionA(a);
Or a simple argument logic:
void functionA(int x) {
MyObject state;
if (x == 0) {
MyObject state = objStateOff; // Supposing they were defined somewhere before.
} else if (x == 1) {
MyObject state = objStateOn;
}
if (state != null) {
// Use MyObject state.
}
}
In this way, you don't need to specify any convention, you just set the off or on right on the argument (You can use a string or a boolean instead of an int (I mean, you could use "ON" or "OFF", literally)).
if your requirement is to have two object states, then why you dont have a field in MyObject like boolean stateOfObject. Then in functionA, you can check the state and do the required logic. Why complicate by sending two objects when you have only two states? May be you have to mention the context where you are using it and why you need two objects to be passed to the functions when the object can be in only one state.
May be you could use enums:
public enum StateOfObject {
ON(10,2),
OFF(15,5);
private final int length;
private final int speed;
StateOfObject(int length, int speed) {
this.length = length;
this.speed = speed;
}
public MyObject getObject() {
MyObject myObj = new MyObject();
myObj.setLength(this.length);
myObj.setSpeed(this.speed);
return myObj;
}
}
Use it like this:
MyObject onObject = StateOfObject.ON.getObject();
System.out.print("Length: " + onObject.getLength() +
" Speed: " + onObject.getSpeed());
I am in the process of making an application which is meant to be a personal pet project of mine, designed around comparing two vehicles against 1 another from a computer game I play
the vehicles have a bunch of stats such as speed, healthpoints, turret traversal etc. and I want to create a small app that will highlight the differences between the vehicles, however i have come to a stumbling block where the arguments taken for the constructors for each vehicles are huge and difficult to read
Here is an example of object creation with the given constructor:
HeavyTank T110E5 = new HeavyTank("T110E5", 2200,54.56d, 875, 37, 30, 254,76,38, 203,127,70,300, 202, 6,32, 400,745,10);
I am sure you would guess that this application I am making, is a tank comparer based off World of tanks, where I am hard coding the tank stats, but as you can see, the arguments taken are difficult to read, making it difficult to create new objects without getting confused. Each tank has different stats so this means I would have to hard code close to 100+ tanks individually. If someone here has a solution of reducing the mess, or recommendations I am willing to listen.
I would also like to reinstate a point I made up at the top, this application is not for commercial purposes and is purely just a pet personal project of mine.
I would suggest storing your tank data in a simple file format, for example a CSV file with one line per tank. Then your tank object can take something like an InputStream as a parameter and stream in the tank details from the file.
And if you use a CSV file you can just use a typical spreadsheet program to edit your tank details quite easily.
This sounds like a perfect use case for the builder pattern.
There are lots of good examples on how to implement this. Here's how Google uses it in the CacheBuilder class of Guava:
LoadingCache<Key, Graph> graphs = CacheBuilder.newBuilder()
.maximumSize(10000)
.expireAfterWrite(10, TimeUnit.MINUTES)
.removalListener(MY_LISTENER)
.build(
new CacheLoader<Key, Graph>() {
public Graph load(Key key) throws AnyException {
return createExpensiveGraph(key);
}
});
This particular example even uses method chaining, but that's less important. The main feature is that newBuilder() sets some default parameters which you can then selectively adjust with one or more method calls. Finally, you call build() to actually create the instance (and calling the actual constructor with the long list of parameters).
JavaDoc + good IDE will help you figure out which arguments you need to provide.
Otherwise, you could wrap the arguments in a single object and pass that to the constructor. An overloaded constructor would work well, because you could unpack the arguments and pass it to the original.
If you know the arguments in advance, you would always put them in a Properties file and read them using java.util.Properties.
Use a fluent interface. Though generally used outside the ccnstructor, why not partly inside.
You might consider putting that information in a properties file that you could then easily edit. Your constructor would then take the name of the properties file and have the additional job of enforcing completeness and validation. While I still favor strongly-typed constructors, a property file approach might be easier to use in the long run.
If you have a mix of required and optional arguments (with sensible defaults), you can use the builder pattern. An example from Effective Java:
public class NutritionalFacts {
private int sodium;
private int fat;
private int carbo;
public static class Builder {
private int sodium;
private int fat;
private int carbo;
public Builder(int s) {
this.sodium = s;
}
public Builder fat(int f) {
this.fat = f;
return this;
}
public Builder carbo(int c) {
this.carbo = c;
return this;
}
public NutritionalFacts build() {
return new NutritionalFacts(this);
}
}
private NutritionalFacts(Builder b) {
this.sodium = b.sodium;
this.fat = b.fat;
this.carbo = b.carbo;
}
}
Then you can do things like:
NutritionFacts cocaCola = new NutritionFacts.Builder(240, 8). calories(100).sodium(35).carbohydrate(27).build();
The first two arguments are required (240 and 8). The other attributes are optional and can be supplied through aptly-named methods.
You can still use the builder pattern if you have a large number of required parameters; you can check that they have been set in the build() method.
I recommend implementing a Standard Constructor without any Parameters. Setters and Getters can be generated via eclipse. This helps keeping a look at all and adding or removing members.
The next thing you should do is to write all your vehicle stuff in a XML file. The tags help you with the vehicle names, values etc. Also adding and removing vehicles will be easier.
You can access XML files via JDOM. Just read the vehicle tags and call the setter methods with the values from the XML file. This can be done with a loop.
In the end, the only thing you have to take care of is your vehicle XML file.
Feel free to ask if there are any questions.
You have three reasonable options that I see:
1) Use the standard contructor("string", value, "string", value,...) format.
This is likely more effort than you will want to put into this program.
2) Use a constructor() method and then setPropertyName(value) methods for each property.
This will allow you to easily add them, but you still need to do it by hand.
3) Read the data in from a file.
Setup the file using columns with names (to avoid just moving the "I forgot what value comes next" problem to a different place) This should be the best.
My suggestion would be to create an object to hold these types with a specific parameter list upon initialization. You can divide up that object based on what types go together logically. Then you'll only need two or three constructors with five parameters each. For example:
HeavyTank T110E5 = new HeavyTank("T110E5", 2200,54.56d, 875, 37, 30, 254,76,38, 203,127,70,300, 202, 6,32, 400,745,10);
would become:
StatObject1 stat1 = new StatObject1(2200, 54.56d);
StatObject2 stat2 = new StatObject2(875, 37, 30);
StatObject3 stat3 = new StatObject3(254, 76, 38);
...
HeavyTank T110E5 = new HeavyTank("T110E5", stat1, stat2, stat3, ...);
or however that works out logically for your system. The benefit of this is that you can apply this to any other tank you create, and can create modifiers in every StatObject class specific to that data.
I've been developing a massive Role Playing Game. The problem is that I'm having trouble engineering how will I manage the Item and Inventory system. Currently I have something similar to this:
public abstract class Item has 5 Nested classes which all are abstract and static that represent the types of Items. Every Nested class has an unique use(), delete() (Which finalizes the class instance) and sell()(triggers delete) void. They also have optional getter and setter methods, like the setAll() method which fills all necesary fields.
Default: Has base price, tradeability boolean, String name, etc... Very flexible
Weapon: Else than the things that the Default type has, it has integers for stat bonus on being equipped(used in the equip() and unequip() voids). Interacts with public class Hero.
Equipment: Similar to Weapon, just that it has an Enum field called 'EquipSlot' that determines where it is equipped.
Consumable: Similar to default, just that has a consume() void that enables the player to apply certain effects to an Hero when using it. Consuming usually means triggering the delete() void.
Special: Usually quest related items where the 'Tradeable' boolean is static, final and always false.
Now, the way that I make customized items is this.
First, I make a new class (Not abstract)
Then, I make it extend Item.ItemType
Then, I make a constructor which has the setAll(info) void inside.
Then, I can use this class in other classes.
It all looks like this:
package com.ep1ccraft.Classes.Items.Defaults;
import com.ep1ccraft.apis.Item.*;
public class ItemExample extends Item.Default {
public ItemExample() { // Constructor
this.setAll(lots of arguments here);
}
}
then I can do:
ItemExample something = new ItemExample();
And I have a perfect ItemExample with all the properties that I want, So, I can make various instances of it, and use amazing methods like 'getName()' and that kind of stuff.
The problems come to Naming the instances, as I do not know how to make an automated form that will give the instance a Different name from the other instance so they don't collide. Also, I want to implement an inventory system that uses slots as containers and can keep stacks (Stackable items only), also the main feature of it is that you can drag and drop them into other slots (For example, to reorganize or to move to another inventory instance like a bank, or to place in an hero's weapon or equipment slots, if it is allowed) and that you can click on them to display a screen that shows the name, description and possible actions of the Item (Which trigger the previously mentioned delete() and use() voids).
Thank you for reading all that! I know that maybe I'm asking for too much, but I'll appreciate any answers anyway!
So basically, you're asking for a unique identifier for your object. There are probably countless approaches to this, but the three different approaches that immediately come to mind are:
1: A UUID; something like:
java.util.UUID.randomUUID()
Pros: A very, very simple solution...
Cons: It does generate a large amount of bytes (16 + the object itself), taking memory / disk storage, which might be an issue in a MMO
2: A global running number; something like:
class ID {
private static volatile long id = 0;
public synchronized long nextId() {
return id++;
}
}
Pros: Again, a simple solution...
Cons: Even though this is a very simple class, it does contain "volatile" and "synchronized", which might be an issue for an MMO, especially if it is used heavily. Also, What happens after X years of running time, if you run out of numbers. A 64 bit long does require quite a lot of named objects to be created, it may not be an issue after all... you'll have to do the math yourself.
3: Named global running numbers; something like:
class NamedID {
private static volatile Map<String, Long> idMap = new HashMap<String, Long>();
public synchronized long nextId(String name) {
Long id = idMap.get(name);
if (id == null) {
id = 0;
} else {
id++;
}
idMap.put(name, id);
return id;
}
}
Pros: You get id's "localized" to whatever name you're using for it.
Cons: A bit more complex solution, and worse than "2" in terms of speed, since the synchronzation lasts longer.
Note: I couldn't figure out how to make this last suggestion faster; i thought of using a ConcurrentHashMap, but that won't work since it works on a lower level; i.e. it will not guarantee that two thread does not interfere with each other between the idMap.get and the idMap.put statements.
The Situation is that I have to use Function pointers for so many functions in Java (so I did it this way) and saved each anonymous class to a static variable of the Interface, so that I could use them directly.
/** The Constant HARDLIM. */
public static final TransferePatternable HARDLIM =
new TransferePatternable() {
public DoubleMatrix transfere(DoubleMatrix netSum, double theta) {
return netSum.gt(theta);
}
public String getFuncName() {
return "HARDLIM";
}
};
But the problem is that sometimes I don't need to provide the Theta so if I remove it the polymorphism won't work, (2 Functions out of 10 don't need theta) so I had to put it (Function declaration conventions now ugly) so I thought of passing the whole Object which actually contains both netsum and theta.
But I'm starting to worry, cause it's also going to ruin what this function really is for. So at last I suggested I put these function separately (non anonymous) and then make anonymous functions use them but the argument would be the object. Like the following:
/** The Constant HARDLIM. */
public static final TransferePatternable HARDLIM =
new TransferePatternable() {
public DoubleMatrix transfere(MyObject obj) {
return MyObjectUtilFun.hardlim(obj.getNetsum,obj.getTheta);
}
public String getFuncName() {
return "HARDLIM";
}
};
So Am I taking the right steps ? or I'm messing around, Please guide me!
Do you really need the instance to be public static final? If you can instantiate the instance wherever you have a reference to theta, then your anonymous class can use that theta reference. For example:
final double theta = 123d;
class TransferePatternable {
public String transfere(String whatever) {
return whatever + theta;
}
}
TransferePatternable myInstance = new TransferePatternable();
myInstance.transfere("arg");
Alternatively you can specify the input as a generic type such that your MyObject need not be a superset of all possible inputs, but rather can differ by TransferePatternable type. Obviously the drawback here is that you need to know what type you're calling in order to provide the right input, but you sort of need to know this anyway if you don't want to provide theta in some situations.
Finally, another common solution to this problem is to replace ALL method parameters with just one Map. Then, you can pass in whatever you want! This has lots of obvious drawbacks, but lots of APIs do exactly this, and generally you'll see them refer to the map as the "context". Here are a few examples:
javax.servlet .ServletRequests store parameters in a Map
AOP has the javax.interceptor.InvocationContext class
Spring's IoC container basically is a big Map of named javabeans
The JSP Expression Language allows you to refer to Implicit Objects that basically are stored in several Maps
I myself have used this Map solution when implementing an Excel-like formula language in java years ago. Such a formula can be parsed into functions and variables, and when executing the function we provided a Map containing the variables keyed by variable name. Obviously you still need to know something about what you're invoking, and in fact we always did know enough about the formula that providing the right inputs in a Map was easy. But again I have to caution you: this sort of code is fairly hard to implement and maintain. Unless you anticipate growing a large set of functions over time, don't go down this route. It's not OO-friendly, and it should be a last resort.
If MyObject is a generally used interface or class and TransferePatternable is not expected to work with anything else, your second idea is best. It opens up the possibilities of a TransferePatternable being able to work with more than just netSum and theta and gets rid of the unneeded theta. My guess is that this is what you want to do, even if it means expanding the capabilities and scope and importance of the MyObject class/interface.
But you are restricting a TransferePatternable to working with a MyObject instance. The unused theta is a problem, but it's a small price to pay for the power of polymorphism (and its a lot simpler and neater than most other solutions). If the MyObject solution doesn't look perfect to you, stick with the unused theta. My guess is a good idea will come along sooner or later, with no harm done if it doesn't.
Is there any reason you can't have an overloaded "transfere" function in the HARDLIM?
/** The Constant HARDLIM. */
public static final TransferePatternable HARDLIM =
new TransferePatternable() {
public DoubleMatrix transfere(DoubleMatrix netSum, double theta) {
return netSum.gt(theta);
}
public DoubleMatrix transfere(DoubleMatrix netSum) {
return netSum.whateverYouNeedToDoWithoutTheta();
}
public String getFuncName() {
return "HARDLIM";
}
};
At the end I used The second choice but with some notes in mind:
To always have functions (i.e Hardlim) defined independently in utility classes.
To state in Javadocs what this variable really is and the utility function being used.
I also found the price of confusing users with unnecessary arguments to be high cause the application is already complex no need to be more complicated.
public static final TransferePatternable HARDLIM =
new TransferePatternable() {
public DoubleMatrix transfere(MyObject obj) {
return MyObjectUtilFun.hardlim(obj.getNetsum,obj.getTheta);
}
public String getFuncName() {
return "HARDLIM";
}
};