Java Class Misuse - Best Practices [closed] - java

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
I'm fairly certain that I am not doing something class related correctly.
I am using a class to create a set of variables (like a javascript object sort of maybe but not really).
I am using it as shown bellow (a basic example)
public class myScript {
public static void main(String[] args) {
Client warehouse = new Client();
Contacts warehouseContactsA = new Contacts();
Contacts warehouseContactsB = new Contacts();
warehouse.idno = 1;
warehouse.name = "warehouse";
warehouse.desc = "I don't exist";
warehouseContactsA.client_idno = 1;
warehouseContactsA.email = "emailAAA#place.com"
warehouseContactsB.client_idno = 1;
warehouseContactsB.email = "emailBBB#place.com"
insertIntoDB(warehouse,
warehouseContactsA,
warehouseContactsB);
}
public static void insertIntoDB(Client warehouse,
Contacts warehouseContactsA,
Contacts warehouseContactsB) {
// code to insert into database here
}
private class Client {
int idno;
String name;
String desc;
}
private class Contacts {
int client_idno;
String email;
}
}
Is there any reason to not use classes this way and if so is there a simpler way to store/manage data that doesn't require a class?

Creating inner classes is probably going to create pitfalls for you. When you don't define them as static then they require an implicit reference back to the outer class, which your code doesn't need, it will only get in the way and cause obscure errors. Maybe you're doing this so you can compile only one class and avoid having a build script? Simple build scripts that use gradle are trivial (not like the bad old days when we used ant), so that shouldn't be an issue. It would be better to move your persistent entities out into separate files.
What you're doing with database connections and transactions is not clear. Generally it's bad to try to do each insert in its own transaction, if only because each transaction has overhead and it increases the time the inserts need to run. Typically you'd want to process the inserts in batches.
Mainly, though, if you're writing a script, use a scripting language. Groovy could be a good choice here:
you wouldn't need an outer class for the procedural script part
you can define multiple public classes in one file
Groovy includes a groovy.sql api for simplifying JDBC code.

import java.util.Arrays;
import java.util.List;
public final class WarehouseRepository {
public static void main(String[] args) {
WarehouseRepository repository = new WarehouseRepository();
Client warehouse = new Client(1, "warehouse", "I don't exist");
Contacts warehouseContactsA = new Contacts(1, "emailAAA#place.com");
Contacts warehouseContactsB = new Contacts(1, "emailBBB#place.com");
repository.insertIntoDB(warehouse, Arrays.asList(warehouseContactsA, warehouseContactsB));
}
public void insertIntoDB(Client warehouse, List<Contacts> contacts) {
// code to insert into database here
}
}
final class Client {
private final int id;
private final String name;
private final String desc;
public Client(int id, String name, String desc) {
this.id = id;
this.name = name;
this.desc = desc;
}
public int getId() {
return id;
}
public String getName() {
return name;
}
public String getDesc() {
return desc;
}
}
final class Contacts {
private final int clientName;
private final String email;
public Contacts(int clientName, String email) {
this.clientName = clientName;
this.email = email;
}
public int getClientName() {
return clientName;
}
public String getEmail() {
return email;
}
}
Some things to notice:
Try to name the classes with their intentions and some Java conventions. For example, a class doing database operations are usually referred as repository
Unless required, make classes and variables final.
Make fields private, and if they are must have, then make them constructor parameters, instead of public or getter/setters.
If there can be multiple contacts associated with client, then it would be great idea to make List<Contact> as field in client.

I would use Map<String,String> for storing attributes.
Where I would store String and ints as Strings and parse them back when they needed.
hope it helps

Yes, that is a good-enough representation.
No, it's not ideal. There are a couple things you can change to improve the situation:
Visibility option 1: make things private with accessors
You can make things more OO-idiomatic by having your "bean" classes (i.e. objects with data storage purpose only, no logic) fields private, and then having public accessors to mask the inner representation:
public class Client {
private int id;
public int getId() { return this.id; }
public void setId(int id) { this.id = id; }
}
Visibility option 2: make your beans immutable
Another option is to make it so that your beans are immutable (so that you can pass them around in a multi-threaded environment nonchalantly) and also guarantee that they are properly initialized and no one writes to them in an illegal state (for example deleting/zeroing the id but not the rest of the data):
public class Client {
public final int id;
public Client(int id) { this.id = id; }
}
Finally, if you have things that may or may not be there (such as description "I don't exist"), I recommend using Optional types, rather than just String types.

Related

Mutiny Quarkus : Can you use Mutiny reactive programming in ArrayLists?

I'm trying to learn Reactive programming in quarkus and run into a problem. I want to make a simple employee system without any database, just the ArrayList with the Employees but in every article and video tutorial i watched and read , there were all using Databases.Is there a way to use Mutli and Uni in just an ArrayList and Is it worth it at all?
Thanks for your time
You can easily do something like:
public class Fruit {
public final String name;
public final String description;
public Fruit(String name, String description) {
this.name = name;
this.description = description;
}
}
#Path("/fruits")
public class FruitResource {
private final Set<Fruit> fruits = Set.of(new Fruit("Apple", "Winter fruit"), new Fruit("Pineapple", "Tropical fruit"));
#GET
public Uni<Set<Fruit>> list() {
return Uni.createFrom().item(fruits);
}
}
where all you are doing is returning a Set of Fruit objects via a Uni - no database or anything

What is good practice to create pojo as having Class fields or simple

What is good practice to create pojo as having Class fields or simple fields.
I am creating pojo like this.
public class StatusDTO {
private String id;
private int totalNodes;
private int totalServlets;
private boolean status;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public int getTotalNodes() {
return totalNodes;
}
public void setTotalNodes(int totalNodes) {
this.totalNodes = totalNodes;
}
public int getTotalServlets() {
return totalServlets;
}
public void setTotalServlets(int totalServlets) {
this.totalServlets = totalServlets;
}
public boolean isStatus() {
return status;
}
public void setStatus(boolean status) {
this.status = status;
}
}
someone recommanded me to do like this as below
public class StatusDTO {
private String id;
private boolean status;
private Total total;
public Total getTotal() {
return total;
}
public void setTotal(Total total) {
this.total = total;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public boolean isStatus() {
return status;
}
public void setStatus(boolean status) {
this.status = status;
}
public static class Total {
private int nodes;
private int servlets;
public int getNodes() {
return nodes;
}
public void setNodes(int nodes) {
this.nodes = nodes;
}
public int getServlets() {
return servlets;
}
public void setServlets(int servlets) {
this.servlets = servlets;
}
}
}
what difference does it make? what is good practice among those two?
I am using this class to set db info and send info to web socket client(stomp)
The answer, as always in such questions, is: It depends.
Simple classes like the first one have the advantage that they are simpler and smaller. The advantage on the second attempt is that if your class, maybe now, maybe later, gets extended, it might be easier if you create a separate Total class.
Good Objectoriented Programming, and Java is strongly OO, almost always requires you to put everything into it's own class.
As a rule of thumb, I create a separate class if:
there is some functionality you to your fields.
you have more then two, mabye three fields related to each other (e.g. connectionHost, connectionPort)
it's just a model class (e.g. Customer, Article)
I can use the field in multiple other classes
Of course there are more but those are some of the most important ones (comment if you think there is another important one I forgot to mention).
Well, one important thing in a good Java application is separation of concerns, for example in an airport application a service that give the last flight of a customer should not require as parameter an object with the first name, the last name, the social security number, the marital status, the gender or whatever other information about the customer that are completely useless (or should be) in retrieving the customer last flight, such that you need to have an object Customer (with all customer information) and another object CustomerId (with only the necessary bits to get the flights).
Another example is for a online shop application, a service that calculate the total price of the basket should not require all the information about all articles (photos, description, specifications, ...) in the basket but only the prices and the discounts which should be enclosed in another object.
Here you have to decide if the concerns of your Total (you need a better name) object could be taken separately of the concerns of your StatusDTO object, such that a method could require only the Total object without the associated StatusDTO object. If you can take them separately then you should have separate objects, if you can't then it's unnecessary.

javafx , rules of OO programming and choosing the write variable types

I'm trying to make an application in javafx but i'm having trouble with choosing the right variable types. I'm rather new to Object oriented programming and the application would have to display a bunch of variables of personnes in a tableView. Afterwards i will do alot of calculations with these variables.
The problem is that i started with normal variables like strings, int's and arrays. It worked fine but now that i'm trying to display them in a table view it gets very complicated and i'm not sure if i used the right types. I've seen some other people use Stringproperties and other funky stuff but then i would have to change all my code.
Are these types better to use and why? And is there a general rule to follow when your building your main data class so that you can avoid these problems? Are there important things you should take into account when building your main structure?
Here is some code of how i did it right now:
//this class would be used to store the choices of every leader.
//It then can be used to make the best possible distribution for next year.
public class Leiding { //leiding => scouts leader in dutch ;)
private static final AtomicInteger count = new AtomicInteger(0);
private int id = 0;
private String naam;
private Leiding[] voorkeurleiding = new Leiding[3]; //3 prefeerd other leaders (from 1 till 3)
private Leiding[] afkeurleiding = new Leiding[3]; //3 disliked leaders
private Tak[] voorkeurTak = new Tak[3];
private Leiding relatie;
private int score;
public Leiding(String naam, Leiding relatie){
this.naam = naam;
this.relatie= relatie;
this.id = count.incrementAndGet();
}
public Leiding(String naam){
this.naam = naam;
this.id = count.incrementAndGet();
}
public String getNaam(){return naam;}
public void setNaam(String naam){this.naam = naam;}
public boolean checkNaam(String naam){ return this.naam == naam;}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getScore() {
return score;
}
...
}
Sorry if this question is too broad but i found it hard to find a cleary answer to this and i have a feeling that these things are related.

How to use encapsulation?

After I read online E-book.They said the benefit of encapsulation is "A class can change the data type of a field and users of the class do not need to change any of their code.". I don't understand what they say in the point. What is the main meaning of the point? Can you give an example,please?
Let's take a simple class Vehicles, which maintains a list:
public class Vehicles {
private ArrayList<String> vehicleNames;
Vehicles() {
vehicleNames = new ArrayList<String>();
}
public void add(String vehicleName) {
vehicleNames.add(vehicleName);
}
}
This will be used by a client in the following way:
public class Client {
Public static void main(String []args) {
Vehicles vehicles = new Vehicles();
vehicles.add("Toyota");
vehicles.add("Mazda");
}
}
Now if Vehicles changes its internal private vehicleNames field to be a LinkedList instead, Client would be unaffected. That is what the book is talking about, that the user/client does not need to make any changes to account for the changes in the class due to encapsulation.
Encapsulation is really important in Object-Oriented Programming. Using encapsulation, you can hide information from users who use your class library/API.
"And why do I need to hide stuff from the users?", you ask. There are a lot of reason. One main reason is that some users who are naughty or just don't know what the API is doing may mess with your classes and stuff. Let me give you an example.
Suppose you have a class here:
public class Computer {
public int coreCount;
}
As you can see here, coreCount is declared public. That means all other classes can access it. Now imagine a naughty person do this:
Computer myPC = new Computer ();
myPC.coreCount = 0;
Even fools can tell that this doesn't make any sense. It might also affect your program's other stuff. Imagine you want to divide by the core count. An Exception would occur. So to prevent this, we should create setters and getters and mark the field private.
C# Version:
public class Computer {
private int coreCount;
public int CoreCount {
get {return coreCount;}
set {
if (value > 0)
coreCount = value;
}
}
}
Java version
public class Computer {
private int coreCount;
public int getCoreCount () {return coreCount;}
public void setCoreCount (int value) {
if (value > 0)
coreCount = value;
}
Now no one can set the core count to non-positive values!
Here's an example of encapsulation. Say we have a Person class, like so
class Person {
private String name;
private String email;
public String getName() { return this.name; }
public String getEmail() { return this.email; }
public void setName(String name) { this.name = name; }
public void setEmail(String email) { this.email = email; }
}
And at some point, we decide we need to store these values not as a couple strings, but as a HashMap (for some reason or another).
We can change our internal representation without modifying the public interface of our Person class like so
class Person {
HashMap<String, String> data;
public Person() {
this.data= new HashMap<String, String>();
}
public String getName() { return this.data.get("name"); }
public String getEmail() { return this.data.get("email"); }
public void setName(String name) { this.data.put("name", name); }
public void setEmail(String email) { this.data.put("email", email); }
}
And from the client code perspective, we can still get and set Strings name and email without worrying about anything else.

What's the most object-oriented way to design an address book?

I am asking myself how to design an object-oriented address book in Java.
Let's say a contact can have several contact details, like addresses, phone numbers and e-mail addresses.
One way to implement this would be to give every contact an ArrayList for every type. But there must be a better and more object-oriented solution. What is it?
The most OOP suggestion I can give you is to create a class for every item/piece of information. For example:
public abstract class ContactInfo { /* ... */ }
public class Address extends ContactInfo { /* ... */ }
public class PhoneNumber extends ContactInfo { /* ... */ }
public class EmailAddress extends ContactInfo { /* ... */ }
public class Contact {
private String name;
private Set<ContactInfo> info;
// ...
}
and finally,
public class AddressBook {
List<Contact> contacts;
// ...
}
This may or may not be overkill for your specific case, but as a thought experiment, it's the way to go. It obviously takes care of the literal part of OOP — using objects — but also lays groundwork for encapsulation, abstraction and inheritance, which are closely related principles.
You're on the right track. The only thing I would do differently would be to use a List interface instead of an ArrayList collection to reference the contacts' attribute collections. This is advice based on the code-to-interfaces rule-of-thumb as described in this article and many others.
I don't think that's particularly un-object oriented. If your domain is such that a Person can have zero or more EmailAddresses, then you've almost exactly described the situation to use a list.
The only alternative approach I can think of would be to have fields such as
WorkEmail
PersonalEmail
OtherEmail1
OtherEmail2
OtherEmail3
but in my opinion that's worse, because:
You simply cannot support more than five email addresses (well, you could add more fields, but that increases the pain of the latter points and still imposes some finite limit.)
You're implying some extra semantics than may be present (what if the same address is used for work and personal? What if neither applies, can you just fill the Other ones? What if you don't know the purpose?)
You now have to test each field manually to see which is null, which is going to involve a non-trivial amount of duplication in Java. You can't use nice features like the enhanced-for loop to apply the same block to every email address, and you can't trivially count how many addresses there are
The list of properties that a Person has is now much less clean. I suppose you could package these properties into an EmailContactDetails class or something, but now you've got an extra level of indirection (more conceptual complexity) for no real gain.
So, if a person has a possibly-empty, unbounded list of email addresses, what's wrong with representing that as a list?
You can also use a Map, and then get specific values e.g. via myMap.get("emailAdress1") or iterate over the whole map like you would do with a list via myMap.entrySet().
One simple way to handle most of the use cases can be like this
public class AddressBook {
private Map<String, Contact> contacts;
AddressBook(){
contacts = new HashMap<String, Contact>();
}
public boolean addContact(Contact contact) {
if(contacts.containsKey(contact.getName())) {
System.out.println("Already exists");
return false;
}
contacts.put(contact.getName(), contact);
return true;
}
public boolean updateContact(Contact contact) {
contacts.put(contact.getName(), contact);
return true;
}
}
class Contact{
private String name;
private String email;
private String phone;
private Address address;
public Contact(String name) {
this.name = name;
}
public Contact(String name, String email, String phone, Address address) {
this.name = name;
this.email = email;
this.phone = phone;
this.address = address;
}
// getters and setters
#Override
public String toString() {
return "name is "+name+" and address is "+address;
}
}
class Address{
private String street1;
private String street2;
private String city;
private int zipcode;
public Address() {}
// getters and setters
#Override
public String toString() {
return "street1 is "+street1+" and zipcode is "+zipcode;
}
}

Categories