I need to get different code executed dependent on the object of my java class.
Further explanation: I am trying to create a "conversation" for a textadventure whith an NPC where the NPC tells you something and you have a few choices of what to say. Basically there are NPCs that have more to communicate with the player but there are of course NPCs that have more or less speechparts than others. So i can't really hardcode it with so many parts and just change the Strings from object to object like this:
public class NPC {
private String[] speech;
private String[] reply;
public conversation() {
speech[0];
getReply(reply);
speech[1];
getReply(reply);
speech[2];
getReply(reply);
...
}
}
And for example NPCone has 3 speech parts and NPCtwo has 7 and everyone of these parts does react in a certain way to different replys so i can't really use if or any loops either.
So i need a way to do this or work around it (hopefully without loosing the ability to put it all in one class), but maybe i'm just stupid here and can't see the wood for the trees.
You might use a finate state machine. FSM Theory and Implementation in game developmet
Sorry, but why can't you do:
public conversation() {
int i = 0;
...
while(hasSpeech()) {
speech(i);
getReply(reply);
}
Meaning: if you have repetitive tasks, then think up ways that allow you to use some sort of loop construct.
Related
Trying to understand the concept of encapsulation, I came across this definition "Combining the attributes and methods in the same entity in such a way as to hide what should be hidden and make visible what is intended to be visible".
But practicing the same, I am not sure which of the following code is more apt for OOP:
public class Square {
//private attribute
private int square;
//public interface
public int getSquare(int value) {
this.square = value * value;
return this.square;
}
}
or
public class Square {
//private attribute
private int square;
//public interface
public int getSquare(int value) {
this.square = calculateSquare(value);
return this.square;
}
//private implementation
private int calculateSquare(int value) {
return value * value;
}
}
Combining the attributes and methods in the same entity in such a way as to hide what should be hidden and make visible what is intended to be visible
This is a potentially misleading statement. You are NOT hiding anything from anyone. It is also not about methods or fields. Unfortunately this is the way things are worded in almost every place.
How
When writing any piece of program, (be it a function, class, module, or library) we think of the piece we are working on as my code, every other code as my client code. Now assume that all the client code is written by someone else, NOT you. You write just this code. Just assume this, even if you are the only one person working on the entire project.
Now the client code needs to interact with my code. So my code should be nice and decent to talk to. The concept of encapsulation says, that I partition my code in two parts, (1) that the client code should be bothered with, (2) that the client code should NOT be bothered with. The OO way of achieving encapsulation is by using keywords like public and private. The non OO way of achieving this is naming convention like leading underscores. Remember, you are not hiding, you are just marking it as none-of-your-business.
Why
So why should we encapsulate things? What should be organize my code into public and private regions? When someone uses my code, they are of-course using the whole thing, not just public thing, so how come private is something that is none-of-their-business? Note here words like someone and their could refer to yourself - but only while working on the other piece of code.
The answer is easy testability and maintainability. A complete project if tested exhaustively, can be quite a task. So at minimum, when you are done coding, you just test the public aspects of my code. You do not test any of the client code, you do not test any of the private aspects of my code. This reduces test effort while preserving sufficient coverage.
Another aspect is maintainability. My code will NEVER be perfect, it WILL need revisions. Either because of bugfix or enhancement, my code will need tinkering. So when a new version of my code is available, how much is client code impacted? None, if changes are in private regions. Also, while planning a change, we try to confine it as much as possible in private regions. So the change, from client's perspective becomes a no-impact. A change in public aspects of my code, will almost always require changes in client code, now that will need testing. While planning the big picture of my code, we try to maximize the area under private regions and minimize the area under public regions.
And more
The idea of encapsulating links with the idea of abstracting which in turn links with idea of polymorphism. None of these are strictly about OO. Even in non OO world like C or even Assembly, these apply. The way to achieve these differ. Even this applies to things beyond computers.
The process of sewage management, for example, is
encapsulated within the public interface of drains. The general public bothers only with the drains. The treatment, the disposal, the recycling are none of general public's business. Thus, the sewage management could be treated as an -
abstract entity - an interface with just the drains. Different government and companies implement this in their own way. Now an city may have a permanent system of sewage management, or it can periodically -
switch providers. In fifty years of government operation, the situation was bad, but once they contracted that BigCorp Inc, now people can breathe free. We just did polymorphism. We switched implementations, keeping the public interface same. Both government and the BigCorp Inc use the same drains, but their own processing facilities, which are encapsulated away and polymorphically switchable.
In your code
In both your codes you chose to encapsulate the storage, the field is made private. This is a nice approach and certainly OO way. In both of your codes, the algorithm is also encapsulated - i.e not visible to the client. Nice. In your second code, you went ahead and extracted the algorithm in a separate non-public method. This is commendable approach, although obviously an overkill for doing something trivial. Better OO none the less.
What you did in second code even has a name: the strategy pattern. Even though here it is useless (and overkill), it could be useful in a scenario when let say you are dealing with extremely large numbers, such that calculating their squares take very long time. In such a scenario, you could make your calculateSquare method protected, have a class FastButApproxSquare extends Square, and override the calculateSquare method with a different algo which calculates an approx value much faster. This way you could do Polymorphism. Whoever needs exact value will use the Square class. Whoever needs approx value will use FastButApproxSquare class.
Encapsulation is about hiding implementation and structure details from client code. In addition it is about coherence: keep things close together which are highly related to each other.
For example consider a class which manages players of a football team:
public class FootballTeam {
public final List<Player> players = new ArrayList<>();
}
Client code would have access to the list of players, to look them up, to add players and so on:
public class FootballManager {
private final FootballTeam team = new FootballTeam();
public void hirePlayer(Player player) {
team.players.add(player);
}
public void firePlayer(int jerseyNo) {
Optional<Player> player = team.players.stream()
.filter(p -> p.getJerseyNo() == jerseyNo)
.findFirst();
player.ifPresent(p -> team.players.remove(p));
}
}
Now, if someone decides to change the field FootballTeam.players into a Map<Integer, Player>, mapping the players jersey number to the player, the client code would break.
In addition the client code deals with aspects / features closely related to a player. To protect the client code and to ensure changeability of the FootballTeam implementation hide all implementation details, keep player related functionality close to the structure, representing the team and reduce the public interface surface:
public class FootballTeam {
private final Map<Integer, Player> players = new HashMap<>();
public void addPlayer(Player player) {
players.put(player.getJerseyNo(), player);
}
public Optional<Player> lookupPlayer(int jerseyNo) {
return Optional.ofNullable(players.get(jerseyNo));
}
public void remove(Player player) {
players.remove(player.getJerseyNo());
}
}
public class FootballManager {
private final FootballTeam team = new FootballTeam();
public void hirePlayer(Player player) {
team.addPlayer(player);
}
public void firePlayer(int jerseyNo) {
team.lookupPlayer(jerseyNo)
.ifPresent(player -> team.remove(player));
}
}
If any code serves the purpose of encapsulation then that code is correct. The purpose of encapsulation is to provide a process of hiding the variables from other classes (i.e. by making the variable as private) and also to provide a way for other classes to access and modify the variables. Both of your code serves this purpose correctly.
If you would have used "calculateSquare(int value)" method as "public" then there would have been a problem. Other class could call this method directly without using set/get method. So as far as your this method is "private" I think both the codes are all right.
This is a pretty elementary general question, but it's pretty simple. I understand that you create a class to create objects, but I'm wondering if that is the ONLY reason why you would need to create a separate class? The reason I ask is because in a course I'm taking, all the students presented on the design of a program that we all had to build individually. Many students had 5-10 classes, while I only had 2. Both options seem to work just fine.
If this is a subjective question, then what is the most accepted way to write programs. What do industry leaders say about adding extra classes that might not exactly be 100% necessary?
Here are some guidelines:
Single Responsibility Principle
The single responsibility principle basically says that each class should only do one thing. If there is a class that handles two or more things, split that into multiple classes.
So check your classes now, is there any class that does a lot of things, like getting user input, doing caluclations, and printing the result? If that's the case you probably want to split that into multiple classes.
Abstraction
Abstraction in OOP is very important. It's basically the process of making real world things into classes or interfaces. For example, if you were doing a calculation app, you would have a Calculator class that does the actual calculation. You would also have a CalculatorWindow class that manages the window of the calculator, like listening for button events. This class can then give the user input to a Calculator object and have it calculate the result.
Design Patterns
There are a lot of design patterns out there. By looking at these design patterns, you can see how classes interact and hopefully you'll get when to create a new class.
There is no one-size-fits-all answer to this.
If this is a subjective question, then what is the most accepted way to write programs.
Obviously, that question is subjective too. (You don't expect us to do a survey for you do you?)
What do industry leaders say about adding extra classes that might not exactly be 100% necessary?
You mean like, Bill Gates, Larry Ellison?
They probably don't say anything.
Sure, there are some people who will get up on their soap box and tell you with great authority that X Y Z is "best practice" or some such. But most of the time these pronouncements are based on (at best) anecdotal evidence / personal experience. In other words, they are really opinions dressed up as facts.
Bottom line: there is no single correct answer, so you learn:
what works best for you (and your team), and
it is not really worth worrying too much about it ... provided what you are doing "works for you".
(The two extremes that don't "work" are when the classes are so fine-grained that you spend all of your time writing and reading boilerplate, OR the classes are so large and complex that you can no longer understand them.)
Different class are used to do different tasks. This reduces code duplication and increases code reuse. And this helps you to follow design pattern to solve some critical problem easily. This is good practice.
Here is a simple example.
To sort data.
//Without using multiple class
public class A{
public static void main(String[] args){
int array[] = {1,6,1,8,34,5};
for(int i=0; i< array.length; i++){
//your procedure to sort the array
}
//other operations;
//Now you need to sort another new array (new_array[])
int new_array[] = {1,6,1,8,34,5};
for(int i=0; i< new_array.length; i++){
//your procedure to sort the new_array
}
}
}
Here in this example we used two for loop to sort two different array. Now see a example with multiple classes
public class A{
public static void main(String[] args){
int array[] = {1,6,1,8,34,5};
int my_array[] = Opertaion.sortArray(array);
//other operations;
//Now you need to sort another new array (new_array[])
int new_array[] = {1,6,1,8,34,5};
int my_new_array[] = Opertaion.sortArray(new_array);
}
}
public class Opertaion{
public static int[] sortArray(int[] array){
for(int i=0; i< array.length; i++){
//your procedure to sort the array
}
return array;
}
}
The above example is very simple example but when you need to do big projects using multiple class will reduce your time to code.
Suppose when you are in a big project
you will write a class to control database queries, a Service class to handle other operation with that database class, a controller class to control everything etc.
I have a situation where my 'agent' objects contain a vast amount of data, including graphics, physics, and now also ai.
I was previously coding components of these 'agents' in separate objects, that were parallel. Now I realize, since the agents are contained in a re-sizable ArrayList, that if one of the agents is destroyed, the indices will no longer be parallel to the ai components.
Truth be told, the agent class is already 10 pages long, and it is very sensible to contain the ai methods and data in a separate object. One issue with this, of course, is that the methods will be 'reproduced' in a way, because instead of having one ai object that will accept and process the data from the many agents, I need one ai object per every agent object.
I asked about this once before and was told that having multiple instances of methods has no effect on performance or memory bloat, so that shouldn't be an issue.
I am not sure how I can solve this problem, except by possibly storing an agent_id in the agent object as well as the ai object and then running a search on each list whenever I need to call them. Needless to say, that is terrible way of doing things performance wise.
In C++, the simple solution to this problem would be a pointer, where the pointer to the proper ai instance would be contained in the agent data. I don't know how to do this, so my best solution is to just cram more data into the agent object and have it passed as an argument to the ai object.
Is there any better way to solve this 'parallel mismatching' problem.
Edit>>>
I know I can stuff all of the data into the agent class. What I was taught, is having a 30 page class is an example of bad oop structure.
My question is, how can I create a /reference/ to store in the agent class, while keeping all of the ai data encapsulated in the ai module.
Edit>> Example
public class Agent{
//pseudo code that represents what I need (yes the class declaration order is wrong)
AI_ref = new Reference(ai_module);
Graphics_ref = new Reference(graphics_module);
int[][] physics_data; //Like I said, 10 pages of this
void method1(){}
void method2(){}
//....
}
public class graphics_module{
int[][] graphics_data; //this is also about 10 pages
void method1(){}
void method2(){}
//....
}
public class ai_module{
int[][] ai_data; //this will likely span 5ish pages
void method1(){}
void method2(){}
//....
}
}
Parallel arrays are a 1960's construct developed when Basic and Fortran were modern languages. These languages had no other data structures.
Since the 1990s with OO development, if you have several different types of data that belong together, you create an object to hold references to those bits of data such that you don't need to worry about parallel anything.
I strongly suggest you refactor your code to modern best practices and use objects. Since you've provided no explicit details, this is about the most explicit answer that can be given.
To create your references, try
public class Agent{
//pseudo code that represents what I need (yes the class declaration order is wrong)
ai_module AI_ref = new ai_module();
graphics_module Graphics_ref = new graphics_module();
int[][] physics_data; //Like I said, 10 pages of this
void method1(){}
void method2(){}
//....
}
As for your parallel arrays, your example doesn't really provide enough detail to demonstrate what you are trying to do.
//pseudo code that represents what I need (yes the class declaration order is wrong)
Do you mean defining Agent before defining ai_module and graphics_module is wrong? It's not. The java compiler will have no issue with that.
You should probably work through a basic java tutorial. I think it will address many of your issues.
I am developing a game in which the user can turn on / off certain effects. These effects cause a drain on the users' energy and various parts of the program must be able to check if an affect is active. Currently, I'm using an enum type to store and check the effects:
public static enum Effects { SUPER_FIRE, FIRE_SHIELD }
if (someEffect == Effects.SUPER_FIRE) {
// Breath fire etc..
}
Saying this, I have to store other variables for each effect - such as the level required to use it or the rate at which it drains energy. So, the other method I thought of was to use a class:
public class SuperFire extends Effect {
public static int levelRequired = 10;
public static int drainRate = 5;
public boolean active() {
// Check if it's active
}
public boolean activate() {
}
public boolean deactivate() {
}
}
SuperFireEffect sfe = new SuperFire();
sfe.activate();
if (sfe.active()) {
energyLevel -= sfe.drainRate;
}
sfe.deactivate();
Which implementation (or any other) is the best for this situation?
I hesitate to say "best" in any case, but it would appear that your second example is "better" in the "more flexible" meaning of the word.
Of course, from your very small code snippets, you are not encapsulating the functionality very well, so it would appear you may wish to do some more design work first.
In the end, you want to have the game code think in terms of the Effect base class and what it can do, and not have to know anything about the implementation of things like SuperFireEffect.
I would probably choose the second one as it is more "object-oriented" in my opinion. Plus if you start to add a lot of effects it will be more easily maintainable, and you can benefit from inheritance for super-effects.
The 2nd implementation is better since you mention about the effects which are specified with their own set of features / properties / fields / attributes like "levelRequired, drainRate". So following this approach, you should well define your classes / entities and their features and common characteristics. Object Oriented Programming principles should be conveyed.
Let me start by saying, I am new to Java programming. I have coded something out that performs in the manner that I want it to. However, it is not very well written.
Here is my code:
import java.lang.Math;
public class Advisor_Score {
public static void main(String[] args){
double p1_1[] = {101,1,1,1.5,.5};
double p1_2[] = {101,2,2.5,2,4};
double p2_1[] = {102,1,5,5,5,5,5,5,5};
double p2_2[] = {102,2,2,5,3,4,5,1.5,2.5,5};
//These arrays represent individual users. The first value in the array is their customer number and the second is domain.
double All_users[][]={p1_1,p1_2,p2_1,p2_2};
//This is a 2-dimensional array takes into account all users.
double[] sum = new double[All_users.length];
double[] raw_advisor = new double[All_users.length];
double[] advisor_score = new double[All_users.length];
for (int i=0;i<All_users.length;i++){
for(int j=2;j<All_users[i].length;j++){
sum[i]+=All_users[i][j];
}
raw_advisor[i]=((sum[i]-(3*(All_users[i].length-2)))/4);
advisor_score[i]= 2.5+(2.5*(1-Math.pow(Math.E, -.5*raw_advisor[i])));
System.out.print("Customer ID "+All_users[i][0]);
System.out.print(", Domain "+All_users[i][1]);
System.out.println(": "+advisor_score[i]);
}
}
}
However I clearly over rely on the main method. I was wondering if anyone could help me integrate more methods and streamline the whole process. Thanks in advance, I am sorry again. I am new to Java and programming.
Although it may be small, it could be good practice taking a crack at making this more object oriented - here's a possible start.
The first thing suggested is from your comment
// These arrays represent individual users.
// The first value in the array is their customer number and the second is domain.
You don't say what the remaining numbers are, but from other comments I gather they are some kind of score. This suggests something like
public class CustomerDomain
{
private int customerNumber;
private int customerDomainID;
private List<Double> scores = new ArrayList<Double>();
public CustomerDomain(int number, int domainID)
{
this.customerNumber = number;
this.customerDomainID = domainID;
}
public void addScore(double score)
{
this.scores.add(score);
}
public List<Double> getScores()
{
return this.scores;
}
}
Although in real life I'd probably not have the scores embedded in the customer class.
This particular program, given it's small size, I would not refactor. Making an OO 'hello world' is trying to make a limousine out of a tricycle, IMO. In general, though, when I start a larger project I want to design with OO concepts in mind.
At a high level, I try to picture the 'entities' I will be building i.e. concrete 'employees,' abstract 'actions,' and their relationships. These real-world 'entities' typically become classes - which OO lends itself to modeling very well via inheritance and other related concepts. Their relationships are then described by the interfaces they expose - being careful to hide the 'internals' of each object to keep everything de-coupled.
Going more into detail, I identify the 'utility' code which multiple parts of my application might use - this may become a static/global helper class.
More detailed still, within a class, I try to restrict functions/methods to accomplishing one goal only, to reduce side effects.
Of course, I don't always get it right the first time. However, building larger and larger projects helps you recognize when certain design patterns work and when they will not. Time, budget, technologies, and so on, all play a part in this decision-making.
This is a really small amount of code, and if it works, why break it? That being said, read up a little on the Object Oriented paradigm, and then look at your problem the code is solving, and think about how it would work in that context. Good object oriented design generally tends to start out on paper, for me anyways.