I'm working on a java based game with a friend and I've noticed he's taking an approach that concerns me, in terms of maintainability.
For a class representing a playable Character, instead of just creating 1 method which sets an object's property, he's creating separate methods which set the property to a specific value.
Which of these 2 options would be the best to follow going forward?
Option 1
public void runFast() {
this.character.speed = 5.0f
}
public void walk() {
this.character.speed = 2.0f
}
public void stop() {
this.character.speed = 0.0f;
}
Option 2
public void setSpeed(float speedTemp) {
this.character.speed = speedTemp;
}
Why not use an enum to set the speed - then you can still have
void setSpeed(Speed speed) {
this.character.speed = speed.getAmount();
}
with:
enum Speed {
FAST(5.0f), WALK(2.0f), STOP(0.0f);
private final float amount;
private Speed(flaot a) { this.amount = a; }
public float getAmount() {
return amount;
}
}
That way, you can quickly update the values, but still have a predefined amount. Its flexible and easy to maintain. You might want to save the enum instead of the float.
My Solution would be to use Enums instead,
it is cleaner and has more context and easily extensible if you have more to do with your speed maxHeartRate in the future.
public class Character {
private Speed speed;
public Speed getSpeed() {
return speed;
}
public void setSpeed(Speed speed) {
this.speed = speed;
}
};
public enum Speed {
STOP(0),
RUN(5.5),
WALK(2.5);
double value;
Speed(double value) {
this.value = value;
}
public double getValue() {
return value;
}
};
IMHO the best option would be to declare constants/enums, and use the option 2.
Example (constants) :
public static final float STOP = 0.0f;
public static final float WALK = 2.0f;
public static final float FAST = 5.0f;
setSpeed(STOP|WALK|FAST);
Example (enums) :
public enum Speed
{
FAST(5.5f),
STOP(0),
WALK(2.5f);
float value;
Speed(float pValue)
{
this.value = pValue;
}
public float getValue()
{
return this.value;
}
}
setSpeed(Speed.FAST);
It depends. For example
Are speeds limited to a few predefined values? In that case using an enum would be a good solution.
Is walking / running / stopping going have side effects other than just setting the speed? As a contrived example, starting to run might cause the character to drop an item it's holding, or stopping might cause the character to skid a little. In this case having separate methods might make sense.
Or maybe there are only a few predefined states, but depending on the environment running speed might be different.
What it comes down to is: Which way of conceptually modeling the properties of your character works best for your game logic / physics? Work this out and then base the interface of your classes on that. Don't get too hung up on the exact API early on, this sort of stuff is pretty easy to refactor.
getter and setters are useful when you want that your code is readble and for avoiding that public class fields can be used in the wrong way from another classes.
This example show how is important.
CLASS A:
public class ClassA{
// in the body class
private String fieldClass1;
//classic setter
public void setfieldClass1(String f1)
{
fieldClass1 = f1;
}
}
CLASS B:
public class ClassB{
// in the bodyclass
public String fieldClass2;
//classic setter
public void setfieldClass2(String f2)
{
setfieldClass2 = f2;
}
CLASS C:
public class ClassC{
//in the body of the class this method use class a and class b
public void calc()
{
ClassA aObject = new ClassA();
ClassB bObject = new ClassB();
ClassA.fieldClass1 = 5 + 5; // illegal expression for the compiler and costrain the developer to use setters
ClassB.fieldClass2 = 8 + 8; // legal expression
}
}
This mean that you must define a "modifiers logic" (protected, private, public) before make setters and getters. Define before the modifiers and after define the setters and getters.
Related
I'm from the php world. Could you explain what getters and setters are and could give you some examples?
Tutorial is not really required for this. Read up on encapsulation
private String myField; //"private" means access to this is restricted to the class.
public String getMyField()
{
//include validation, logic, logging or whatever you like here
return this.myField;
}
public void setMyField(String value)
{
//include more logic
this.myField = value;
}
In Java getters and setters are completely ordinary functions. The only thing that makes them getters or setters is convention. A getter for foo is called getFoo and the setter is called setFoo. In the case of a boolean, the getter is called isFoo. They also must have a specific declaration as shown in this example of a getter and setter for 'name':
class Dummy
{
private String name;
public Dummy() {}
public Dummy(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
}
The reason for using getters and setters instead of making your members public is that it makes it possible to change the implementation without changing the interface. Also, many tools and toolkits that use reflection to examine objects only accept objects that have getters and setters. JavaBeans for example must have getters and setters as well as some other requirements.
class Clock {
String time;
void setTime (String t) {
time = t;
}
String getTime() {
return time;
}
}
class ClockTestDrive {
public static void main (String [] args) {
Clock c = new Clock;
c.setTime("12345")
String tod = c.getTime();
System.out.println(time: " + tod);
}
}
When you run the program, program starts in mains,
object c is created
function setTime() is called by the object c
the variable time is set to the value passed by
function getTime() is called by object c
the time is returned
It will passe to tod and tod get printed out
You may also want to read "Why getter and setter methods are evil":
Though getter/setter methods are commonplace in Java, they are not particularly object oriented (OO). In fact, they can damage your code's maintainability. Moreover, the presence of numerous getter and setter methods is a red flag that the program isn't necessarily well designed from an OO perspective.
This article explains why you shouldn't use getters and setters (and when you can use them) and suggests a design methodology that will help you break out of the getter/setter mentality.
1. The best getters / setters are smart.
Here's a javascript example from mozilla:
var o = { a:0 } // `o` is now a basic object
Object.defineProperty(o, "b", {
get: function () {
return this.a + 1;
}
});
console.log(o.b) // Runs the getter, which yields a + 1 (which is 1)
I've used these A LOT because they are awesome. I would use it when getting fancy with my coding + animation. For example, make a setter that deals with an Number which displays that number on your webpage. When the setter is used it animates the old number to the new number using a tweener. If the initial number is 0 and you set it to 10 then you would see the numbers flip quickly from 0 to 10 over, let's say, half a second. Users love this stuff and it's fun to create.
2. Getters / setters in php
Example from sof
<?php
class MyClass {
private $firstField;
private $secondField;
public function __get($property) {
if (property_exists($this, $property)) {
return $this->$property;
}
}
public function __set($property, $value) {
if (property_exists($this, $property)) {
$this->$property = $value;
}
return $this;
}
}
?>
citings:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get
http://tweener.ivank.net/
Getter and Setter?
Here is an example to explain the most simple way of using getter and setter in java. One can do this in a more straightforward way but getter and setter have something special that is when using private member of parent class in child class in inheritance. You can make it possible through using getter and setter.
package stackoverflow;
public class StackoverFlow
{
private int x;
public int getX()
{
return x;
}
public int setX(int x)
{
return this.x = x;
}
public void showX()
{
System.out.println("value of x "+x);
}
public static void main(String[] args) {
StackoverFlow sto = new StackoverFlow();
sto.setX(10);
sto.getX();
sto.showX();
}
}
This is a bit difficult to explain so I wrote up and example to illustrate the concept. In the following example I have a stock class which models the figures that affect a stock simulation program. I also have a MarketModifier class which represents events which would affect the stocks in different ways.
public class ExampleArea
{
public static void main(String cvhfg[])
{
Stock test = new Stock(1f,1f,1f,1f);
MarketModifier worldEvent =
new MarketModifier("Bad publicity",-2.5f,"publicOpinion");
}
}
class MarketModifier
{
public MarketModifier(String name, float modifier, String variable) {
super();
this.name = name;
Modifier = modifier;
this.variable = variable;
}
String name;
float Modifier;
String variable;
}
class Stock
{
public Stock(float value, float integrity, float publicPresence, float publicOpinion) {
super();
this.value = value;
this.integrity = integrity;
this.publicPresence = publicPresence;
this.publicOpinion = publicOpinion;
}
float value;
float integrity;
float publicPresence;
float publicOpinion;
//...other variables...
}
My question is how would I link the marketModifer to the variable in the Stock model (in the example above it is "publicOpinion" set in the "variable" String) without using a string. Strings have the problem of possibly mistyping them, and I would need a switch to identify which variable the modifier was affecting.
I thought of using an enum but I would still need a switch table to check them and I would also have to update the enum values every time a stock has a different variable which could be affected (there could be additional variables in the subclasses of Stock). The other option I thought of was reflection but this solution, though I think it would work, seems overly complicated, and adds more difficulty in reading than it solves.
So again, is there a better way to link the an object to the variable(s) that it affects in another object (maybe some kind of observer/watcher pattern?).
Since you want to avoid reflective approaches, what I can suggest is to use an event listener approach.
So what you basically want to do is to listen for the event when market action is performed and then modify the values in your Stock object.
So you would need an interface like this that your MarketModifier would invoke when it is processed.
Modifier.java
public interface Modifier {
public void modify(Stock taget, float modifier);
}
And this interface's implementations would be able to modify any value(s) in the stock object.
An implementation would look like this:
PublicOpinionModifier.java
public class PublicOpinionModifier implements Modifier {
public void modify(Stock target, float modifier) {
target.setPublicOpinion(target.getPublicOpinion() + modifier);
}
}
After that, you can create your MarketManager class like this:
MarketManager.java
public class MarketManager {
// The name of the event.
private String name = "unkown";
// Modifier value of the event.
private float modifier = 0f;
// The listener to listen for the modifications.
private Modifier modificationListener;
// The target stock object towards which the action is directed.
private Stock target;
/**
* Executes the market event.
*/
public void executeAction() {
modificationListener.modify(target, modifier);
}
}
The MarketManager would have the target object (the Stock object to update) and an implementation of Modifer which would be acting as a listener which would be invoked when the market stuff is going on...
TestMarket.java
public class TestMarket {
public static void main(String[] args) {
Stock stock = new Stock(1f, 3f, 1f, 3f);
MarketManager manager = new MarketManager();
manager.setTarget(stock);
manager.setName("Bad Publicity");
manager.setModifier(-2f);
manager.setModificationListener(new PublicOpinionModifier());
manager.executeAction();
}
}
Neat!
I have uploaded a more clean and elaborated version in my public repo.
I was wondering if there was an easier way to increment another class's private variables. Here is how I generally would go about it:
If I only need to do this rarely in my code:
pc.setActionsCurrent(pc.getActionsCurrent()-1);
If I need to do lots of incrementing, I would just make a special setter:
//In the PC class
public void spendAction(){
this.actionsCurrent--;
}
//In the incrementing Class
pc.spendAction();
Is there a better way to go about this? If the variable were public
pc.actionsCurrent--;
would be enough, and I can't help but feel I'm over-complicating things.
No. The method abstraction is generally the way to go about it, you might also pass in the increment value (and you can leverage that in your implementation). Consider something like
private long increment = 1;
private long myVariable = 0;
public void setMyVariable(long myVariable) {
this.myVariable = myVariable;
}
public void setIncrement(long increment) {
this.increment = increment;
}
public long getMyVariable() {
return this.myVariable;
}
public void addToMyVariable(long val) {
this.myVariable += val;
}
public void incrementMyVariable() {
addToMyVariable(increment);
}
The above would allow the increment value to vary (and this is generally called encapsulation).
Just define an increment method. For generality you could supply the increment as a parameter, and it could be negative:
public void increment(int augend)
{
this.actionsCurrent += augend;
}
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Property and Encapsulation
NEWB Alert!!
I am starting with Android and Java and I am starting to understand it but I am wondering why I should use getters and setters and not just public variables?
I see many people make a private variable and create a get and set method.
What is the idea here?
Its called encapsulation and the concept is central to object oriented programming. The idea is that you hide the implementation of your class and expose only the contract i.e. hide the how and only expose the what. You hide the variables by making them private and provide public setters-getters and other public methods which the clients invoke to communicate with your class. They are not tied to the actual implementation of the methods or how you store your variables.
For example, suppose you had this class where you stored a phone number as a Long object:
public class ContactInfo {
private Long phoneNo;
public Long getPhoneNo() {
return phoneNo;
}
public void setPhoneNo(Long phoneNo) {
this.phoneNo = phoneNo;
}
}
Since the clients of the class only see the getter/setter, you can easily change the implementation of the class/methods by switching the phone number representation to a PhoneNumber object. Clients of ContactInfo wouldn't get affected at all:
public class ContactInfo {
private PhoneNumber phoneNo;
public Long getPhoneNo() {
return phoneNo.getNumber();
}
public void setPhoneNo(Long phoneNo) {
this.phoneNo = new PhoneNumber(phoneNo);
}
}
public class PhoneNumber {
private Long number;
public PhoneNumber(Long number) {
this.number = number;
}
public Long getNumber() {
return number;
}
}
The OOP concept involved is encapsulation (google it).
Some of the advantages are: you can specify different access level for setters (mutators) and getters (accessors), for example public getter and private setter. Another advantage is that you can add another code other than changing or retrieving the value. For example, you may want to check the validity of the set value, or you want to throw exceptions or raise some events in response to changing the variable to certain value. If you implement these inside an accessor or mutators, you can also change their implementations without changing any code outside of the class.
I believe the idea is "information hiding" http://en.wikipedia.org/wiki/Information_hiding
It also serves to control the access to variables (provides an interface). For example, you can provide a getter but not a setter, so that they may be read but not written. Whereas if everything was public any thing could read and write to the variables.
Also important is any checking/validation need to set a variable. For example you have a String name that is not allowed to be empty but if it is public it could easily be forgotten and set as name = "". If you have a setter such as public boolean setName(String newName) you can check newNames length and return true or false if it passes and is set or not
The concept is called encapsulation.
What it attempts to do is to separate the inner structure of a class from its behaviour.
For example, suppose a class like this
public class Point{
private float x;
private float y;
public float getX(){
return x;
}
public float getY(){
return y;
}
public float distanceToZero2(){
return x*x + y*y
}
public float getAngle(){
//havent considered the x = 0 case.
return atan(y/x);
}
public boolean isInFirstQuad(){
return x>0 && y>0;
}
}
In this case, encapsulation hides the inner structure of the class, and exposes only the operations available to a Point. If you dont like it, you can change its inner structure and mantain its behaviour (for example, changing carthesian coordinates to polar coordinates).
Anyoune who uses this class wont care about it, he /she will be happy that they have a Point class with this functionality.
Asides the encapsulation, you can also control the value get or set to your variable in some cases. For example, you want to validate the value of an age variable which should be >=1
class Person {
private int age = Integer.MIN_VALUE;
public void setAge(int age){
if(age>=1)
this.age = age;
}
public int getAge(){
return age;
}
}
I'm from the php world. Could you explain what getters and setters are and could give you some examples?
Tutorial is not really required for this. Read up on encapsulation
private String myField; //"private" means access to this is restricted to the class.
public String getMyField()
{
//include validation, logic, logging or whatever you like here
return this.myField;
}
public void setMyField(String value)
{
//include more logic
this.myField = value;
}
In Java getters and setters are completely ordinary functions. The only thing that makes them getters or setters is convention. A getter for foo is called getFoo and the setter is called setFoo. In the case of a boolean, the getter is called isFoo. They also must have a specific declaration as shown in this example of a getter and setter for 'name':
class Dummy
{
private String name;
public Dummy() {}
public Dummy(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
}
The reason for using getters and setters instead of making your members public is that it makes it possible to change the implementation without changing the interface. Also, many tools and toolkits that use reflection to examine objects only accept objects that have getters and setters. JavaBeans for example must have getters and setters as well as some other requirements.
class Clock {
String time;
void setTime (String t) {
time = t;
}
String getTime() {
return time;
}
}
class ClockTestDrive {
public static void main (String [] args) {
Clock c = new Clock;
c.setTime("12345")
String tod = c.getTime();
System.out.println(time: " + tod);
}
}
When you run the program, program starts in mains,
object c is created
function setTime() is called by the object c
the variable time is set to the value passed by
function getTime() is called by object c
the time is returned
It will passe to tod and tod get printed out
You may also want to read "Why getter and setter methods are evil":
Though getter/setter methods are commonplace in Java, they are not particularly object oriented (OO). In fact, they can damage your code's maintainability. Moreover, the presence of numerous getter and setter methods is a red flag that the program isn't necessarily well designed from an OO perspective.
This article explains why you shouldn't use getters and setters (and when you can use them) and suggests a design methodology that will help you break out of the getter/setter mentality.
1. The best getters / setters are smart.
Here's a javascript example from mozilla:
var o = { a:0 } // `o` is now a basic object
Object.defineProperty(o, "b", {
get: function () {
return this.a + 1;
}
});
console.log(o.b) // Runs the getter, which yields a + 1 (which is 1)
I've used these A LOT because they are awesome. I would use it when getting fancy with my coding + animation. For example, make a setter that deals with an Number which displays that number on your webpage. When the setter is used it animates the old number to the new number using a tweener. If the initial number is 0 and you set it to 10 then you would see the numbers flip quickly from 0 to 10 over, let's say, half a second. Users love this stuff and it's fun to create.
2. Getters / setters in php
Example from sof
<?php
class MyClass {
private $firstField;
private $secondField;
public function __get($property) {
if (property_exists($this, $property)) {
return $this->$property;
}
}
public function __set($property, $value) {
if (property_exists($this, $property)) {
$this->$property = $value;
}
return $this;
}
}
?>
citings:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get
http://tweener.ivank.net/
Getter and Setter?
Here is an example to explain the most simple way of using getter and setter in java. One can do this in a more straightforward way but getter and setter have something special that is when using private member of parent class in child class in inheritance. You can make it possible through using getter and setter.
package stackoverflow;
public class StackoverFlow
{
private int x;
public int getX()
{
return x;
}
public int setX(int x)
{
return this.x = x;
}
public void showX()
{
System.out.println("value of x "+x);
}
public static void main(String[] args) {
StackoverFlow sto = new StackoverFlow();
sto.setX(10);
sto.getX();
sto.showX();
}
}