Here's a snippet of code:
//Game board is made up of Squares. A player can place GamePieces on a Square.
public class CheckersBoard
{
public boolean PlaceGamePiece(GamePiece gamePiece, int nRow, int nColumn) {
return m_theGameBoard[nRow][nColumn].PlaceGamePiece(gamePiece);
}
private Square[][] m_theGameBoard;
}
Let say I'm testing the PlaceGamePiece method (using junit) and I need to access the m_theGameBoard so I can look at it and verify the GamePiece was placed on the correct Square and has the correct data.
In C++ I'd either make the test class a friend so it can access the private member m_theGameBoard, or I'd have a function that returns a const GameBoard that cannot be modified (because it's const):
const GameBoard& GetGameBoard() const { return m_theGameBoard; }
Now I can do what ever checking I want to do on the game board, but I can't modify the game board because it's const.
Java doesn't support returning const references or friend classes. So my question is what is the standard Java way of doing this?? Do I have to just provide a bunch of get accessors that allow me check the data on the Square?
UPDATE:
I ended up writing a GetPiece method as Kaleb Brasee suggested.
public GamePiece GetGamePiece(Point pt) {
return new GamePiece(m_theGameBoard[pt.GetRow()][pt.GetColumn()]);
}
Notice I create a new GamePiece object and return that. I'm not returning the GameBoards internal reference, therefore no one can modify the gameboard because they only have a copy! Nice! Thanks for the help guys, some really good advice.
FYI: I keep changing the names of the objects when I post them on here, sorry if that confused anyone.
Define the variable as protected, so that if the unit test is in the same package, it can access it.
However, I would just add a public method getPiece(int row, int col) that returns the piece on that square (or null if there's no piece there). It's likely you'll need a method like that anyway, and you could use it in your tests.
The default access modifier for a method or property is "package-protected", which means "visible only within my package". Therefore, you can emulate the semantics of "friendship", while maintaining a separate code base for tests, by having two distinct source folders, but with the same package structure.
src
|--com
|
--cchampion
|
--MyClass.java
tests
|--com
|
--cchampion
|
--TestMyClass.java
Then, within MyClass.java
public class MyClass {
private int nonTestedThing;
int[][] testedThing; // this is visible to TestMyClass
// or
// protected int[][] testedThing;
// if you want it visible to kids
}
This is not ideal in any respect, but it's one way to go about it.
Yes. Your choices basically boil down to either having:
Square getSquareAtLocation(int row, int col) { ... };
or using one of the Java collections which you could then pass through Collections.unmodifiableList(...)
(note that if you used a multidimensional List, you'd have to be careful to wrap the inner Lists as well to make sure they're not modifiable either)
If this is only ever going to be used for testing, you could also create a function that returns a deep copy of the array.
Related
I'm trying to program a board for a game. The board has 25 fields, and each field can either contain a base or 4 different sizes of rings.
public class Field {
private Base base;
private Ring[] rings;
public Object getPieces() {
if (base == null) {
return rings;
} else {
return base;
}
}
}
I programmed the setter methods so that a Base only can be set if rings is null, and that a Ring only can be set if base is null.
The problem is that in order to paint the board, my view needs the contents of Field, which is either a Base or a Ring[]. I find it hard, however, to allow the method to return both types. Right now, I'm returning the contents as Object, but this is bad practice.
Is there any way in which I can allow my method to return both types?
If not, is there a way in which I can store my pieces more efficiently that allows me to return them as one type?
Also, Base and Ring both extends the same superclass Piece, so I could return them as pieces instead, but then I would still have the problem that one of the two return types is an array where the other is not.
You could return an array of pieces. If you need to return only the base, then you just put it inside an array of pieces which will be the only element. Otherwise you return the array or rings.
So, your method will be like this:
public Piece[] getPieces() {
Piece [] toReturn;
if (base == null) {
toReturn = rings;
} else {
toReturn = new Piece[]{base};
}
return toReturn;
}
Consider that if you implemented new methods in the Base or Ring classes, then those methods canĀ“t be called because you defined that the objets inside the array are from the Piece class, unless you make a cast - if the array has only one element it is a Base, otherwise is a Ring. This is like an implicit instanceOf, so be very carefull. The use of instanceOf should make you check if there is a better way of solving the problem!
You need to work out what you want to do with the things that this method returns and then create a superclass for them. This may be the Piece class, but it could be a Drawable or something else. Without knowing what you are doing it is hard to give a real answer.
As to your array or object you have two options. Again what is right for you is hard to give based on the information given. Either the getPieces can a collection of some sort regardless (array, List, Set etc) even if it is a collection of one, or your Piece (or Drawable or what ever) could work regardless of if what backs it is a single Piece or a collection of Pieces.
You should be attempting to encapsulate the logic rather than just handing things out willy-nilly. Again I don't know your application, but say in the case of a Bank rather than have a getBalance and setBalance you have a deposit, withdraw and display(onThis).
In the class where you are calling your getter, you could try using the instanceOf
Field field = new Field();
Object returnObject = field.getPieces();
if(returnObject instanceOf Base){
// add to Base
} else if(returnObject instanceOf Rings){
// add to rings
}
Unless you have a strict programming guidelines, in the long run the code can end extremely long and ugly, and after some point of time you might not be able to debug the code as well. So be careful.
I would say setting null is even a more "badder" practice than methods returning Object instances. As long as you can help it, don't set anything as null.
Your architecture propably violates the Tell, Dont Ask principle: The Board asks Field for it-s internal state getPieces().
If you reformulate this to: The Board tells Field to draw itself you find out that the drawing logic should belong to Field and not to board. This way there is no more need for the board to know the implementations detail that a field may contain a base or rings.
This might be a trivial question, but I need some clarification...
There is a book called Clean Code that says that our methods should be small, preferably up to 5-10 lines long. In order to achieve that we need to split our methods into smaller ones.
For instance, we may have someMethod() shown below. Let's say, modification of 'Example' takes 5 lines and I decide to move it into a separate method, modify 'Example' there and return it back to someMethod(). By doing this, someMethod() becomes smaller and easier to read. That's good, but there is a thing called "side effects" which says that we shouldn't pass an object to another method and modify it there. At least, I was told that it's a bad idea ) But I haven't seen anything prohibiting me from doing so in Clean Code.
public Example someMethod() {
// ... different lines here
Example example = new Example();
example = doSomethingHere(example, param1, param2, ...);
// ... different lines here
return example;
}
private Example doSomethingHere(Example example, 'some additional params here') {
// ... modify example's fields here ...
return example;
}
So, am I allowed to split the methods this way or such a side effect is prohibited and instead I should deal with a rather long-line method that definitely breaks Clean Code's rules talking about short methods?
UPDATED (more specific name for the sub-method)
public Example someMethod() {
// ... different lines here
Example example = new Example();
example = setExampleFields(example, param1, param2, ...);
// ... different lines here
return example;
}
private Example setExampleFields(Example example, 'some additional params here') {
// ... modify example's fields here ...
return example;
}
As JB Nizet commented, it's not actually a side effect if it's the only effect, so any blanket statement that "all side effects are bad" doesn't apply here.
Still, the main question stands: Is this (side) effect okay?
Talking about the principles first, side effects are, in general, dangerous for two reasons:
they make concurrency more difficult
they obscure/hide information
In your example, there is some information that is hidden. You could call this a potential side effect, and it can be exposed with a question: "Does this doSomethingHere method create a new object or modify the one I pass in?"
The answer is important, and even more so if it's a public method.
The answer should be trivial to find by reading the doSomethingHere method, especially if you're keeping your methods 'clean', but the information is nonetheless hidden/obscured.
In this specific case, I would make doSomethingHere return void. That way there's no potential for people to think that you've created a new object.
This is just a personal approach - I'm sure that plenty of developers say you should return the object you modify.
Alternatively, you can pick a 'good' method name. "modifyExampleInPlace" or "changeSomeFieldsInPlace" are pretty safe names for your specific example, imo.
we shouldn't pass an object to another method and modify it there.
Who says that? That is actually a good practice in order to split your function in a way that forms a "recipe" and have specific functions that know exactly how to populate your object properly.
What is not recommended (and probably the source where you got your recommendation misunderstood this rule) is defining a public API and modify the arguments. Users appreciate not having their arguments modified as it leads to less surprises. An example of that is passing arrays as arguments to methods.
When you define an object and pass it to an other method, method itself can modify the content of the object therein which may be unwanted in some cases. This is because you pass the reference(shallow copy) of the object to that method and method can modify that object.For example when you pass an Array, Arrays are objects, to a method, method can change the content of the Array which may not be what the caller method expects.
public static void main(String[] args){
int[] arr= {1,2,3,4};
y(arr);
//After the method arr is changed
}
public void y(int[] comingArray){
comingArray[0] = 10;
}
To make sure the values of Array cannot be changed, deep copy of the Array should be sent to method which is another story
However this is not the case when you use primite types(int, float etc.)
public static void main(String[] args){
int a= 1
y(a);
//After the method a is not changed
}
public void y(int comingInt){
comingInt = 5;
}
Due to the nature of the Objects, you should be carefulTo learn more about shallow copy and deep copy https://www.cs.utexas.edu/~scottm/cs307/handouts/deepCopying.htm
Does it differ from methods? Like arrays have a property - length and so array.length gives the length of array whereas array.length() gives an error
A better term to use for properties is a field. Basically, a field is a variable, while a method is where you have the "meat" of your code. For these examples, I'll be using the object "Book".
Fields can be classified as "instance" variables meaning that they are different for each object, or they can be classified as "static" variables, which means that they are universal for the project.
private int pages;
private static int amountOfBooksInTheWorld;
The number of pages is specific to a certain book, a specific "instance" of the book object. The amount of books in the world is obviously not specific to one book; therefore, it is "static", universal, for all books. Instance variables are called by stating objectname.variablename, while static variables are called by classname.variablename.
javahandbook.pages
Book.amountOfBooksInTheWorld
Now for your second question, methods, those things with the parentheses, are usually classified into these groups: constructor, accessor, mutator, and static methods. All methods have "parameters" and "return types". The parameters are basically inputs. The return types are the outputs (if there are any). Methods are called by objectname.method(), unless they are static, where they are called by classname.method().
Constructors are what you use to create your object. They usually are the ones which "initialize" all the instance variables for the object, that is to say, they basically tell them what they start as. These methods have no return type. Constructors are probably the most different method type from the rest, but are very important.
public Book(int p) {
pages = p; //We use "=" to initialize our variables (left becomes the right)
}
In action...
Book javahandbook = new Book(100); //A new book has been created!
Accessor methods are what other classes use to find out what are the instance variables of a particular object. These specify a return type of either boolean (a fancy name for true or false), floating point numbers (double-precise return types that include double and float), regular numbers (integer return types such as byte, short, int, or long), or even other objects. The return type is what you get "back" when the method is done doing its thing. Keep in mind that the object being referred to in the method call is the "implicit parameter", meaning that it can be referred to using "this". It sounds wierd. I'll show you an example.
public int getPages() {
return (this.pages);
}
In action...
int test = javahandbook.getPages();
System.out.println(test); //This will return the amount of pages
//Note that what I did with the 2nd line was bad coding practice, but it works in this scenario
Mutator methods change the instance variables. Their return type is "void".
public void ripPages(int rippedpages) {
this.pages = this.pages - rippedpages;
System.out.println("HULK SMASH");
}
In action...
javahandbook.ripPages(300);
Static methods are the ones that are universal, not on a per object basis. They can have any return type.
public static int countBooks(List<Book> books) {
return (books.size);
}
In action...
public int howmanybooksinthislist = Book.countBooks;
Put all of them together and you get...
public class Book {
private int pages;
private static int amountOfBooksInTheWorld;
public Book(int p) {
pages = p;
}
public int getPages() {
return (this.pages);
}
public void ripPages(int rippedpages) {
this.pages = this.pages - rippedpages;
System.out.println("HULK SMASH");
}
public static int countBooks(List<Book> books) {
return (books.size);
}
I know this was a bit too lengthy, but I hope it helps!
Properties/Fields are variables in a class. For example:
public class Employee {
private String name;
private int salary;
public getName(){return this.name};
}
In the class above, name and salary are properties of an instance of the class (object of the class) while getName() is a method.
Properties are the adjectives describing an object, in this example "how many elements it has". Properties are set to define variable aspects of instance of the object, either directly (if allowed) or as the result of some action, and then they may be examined when using the object.
Methods are the verbs provided to do something with the object, for example "add a new element". These actions may utilize properties, and may alter them, as well as doing other things (whatever purpose the creator defines). Methods may also accept adverbs in the parenthesis that further effect how they operate, thus the different syntax with "()"; for example information to "add in the new element".
While methods are more complex and versatile mechanisms, a complex object might not have pre-calculated (cached) "x.length" type properties always already available to examine and thus the object might provide a method "x.length()" to get the information. That method might have to evaluate complex aspects of an object to figure out "length", and either set it and or give it back, blurring the line between a property and that more simple use of a method.
Tangent on "field", "property" and "properties": while the technical term "field" very specifically identifies a data storage element attached to an object, the term "property" is acknowledged by the core group at http://docs.oracle.com/javase/tutorial/information/glossary.html. A property is more abstract, but logically synonymous to field when considered in comparison to a method. Logically different than field/property in this comparison, though related, is a "properties" set which is a static gathering of initial settings of property values for an application (a collection of code presented for a designated use), most often placed in a file ".properties" named and stored at a location agreed upon by the application - though these might also be gathered in any other storage location like a database.
array.length is accessing a field inside the object, while array.length() is attempting call a method call length(), and since the method does not exist, it gives an error
To understand properties and methods, think of an apple. An apple can be different colours, like red, yellow, etc. An apple can also have varying sizes. Both of these traits, colour and size, are properties of an individual apple; they describe the apple.
A method is different. It describes something an apple can do, like grow and ripen. Some methods, however, can also represent properties, and simplify reading those properties.
For example, an object representing a pen might have a certain amount of ink left. When requesting how much ink is left, the pen object would need to verify that there is any, and refill the pen if not, before returning how much ink there is.
To directly answer your question, properties and methods are very different. Properties hold data about an object, but methods hold data about what an object can do. Something like the length of an array is a property because it describes the array itself, not what the array can do.
This and other definitions of some useful terms are given here.
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.
When I want to speedup part of codes, I use a lookup table instead of a function. In other languages I use global arrays to do this job. I pre-calculated all return values and put them in an array.
Here is an example of a function :
public static int Box(int c) { /* c value range is 0-80 */
return ((c / 9) / 3) * 3 + ((c % 9) / 3);
}
I could instead use an array like this :
int Box[] = {0,0,0,1,1,1,2,2,2,0,0,0,1,1,1,2,2,2,0,0,0,1,1,1,2,2,2,3,3,3,4,4,4,5,5,5,3,3,3,4,4,4,5,5,5,3,3,3,4,4,4,5,5,5,6,6,6,7,7,7,8,8,8,6,6,6,7,7,7,8,8,8,6,6,6,7,7,7,8,8,8}
Java doesn't have global arrays!
What would be the best way way to do this so I can access these values?
You can still use global variables. You just need to put them in a class.
public class PrecalculatedValues{
public static final int BOX[]={0,0,0,1,1,1,...};
}
You can access BOX later in your code like so:
public static void main(String[] args) {
System.out.println(PrecalculatedValues.BOX[0]);
}
In Java, the equivalent of globals are public static variables. If you want to make the static variable immutable, then it should also be declared as final.
Also, the naming convention in Java for static variables is to capitalize the entire name, and separate words with underscores (ex: SOME_BOX).
Using your example above, you can do:
public static final int[] BOX = {0,0,0....};
Though it is possible to use a lookup table it is completly unnecessary in this case, since the equation can be calculated without branches in a couple of cycles.
When using arrays as a lookup table branches will become necessary because of the ArrayIndexOutOfBounds checks.
I would recommend to put a static array inside a class where that method is located and still call the method from outside code and just use the array from within the function. Yes, you will have some overhead for a funcall but I suppose you're not trying to gain like 0.001% of performance? Also JIT will probably simplify it. Most importantly your interface will be consistent and it will look like a normal function not like some hack. If you're trying to get some performance from a costly function by precalculation you can also consider memoization. The thing with hiding this array behind the funcall is that you can use any technique of caching or precalculation later without disturbing public interface.
E.g.
class A {
private final static int values[] = {0, 1, 2 ... };
public int myFun(int x){
return values[x];
}
}
for one you could just simplify your function (the /9/3*3 and the parens are very unnecessary. I know this is an example but just always look for ways of simplifying)
secondly if you function is simple enough, the "spedup" methods are not necessarily faster. Generally your lookup table method is not exactly scalable
third if you still want a lookup table method, just create an object that holds the values.