In the interest of not creating more variables than necessary and cluttering up within the scope of a method that could otherwise have been very slim, I've, instead, created a temporary to hold all of the files I'm going to be referencing throughout the rest of the method.
I dislike this solution because it creates an array object every time it is run when an array object is not necessary to be created.
I could also not use the array or wall of variables, and instead reference the get methods directly, but that creates a lot of redundancy as I am performing the same methods repeatedly, and I dislike that even more.
public void savePrices() {
MFilePrices file[] = {AutoEcon.files().getPrices(), AutoEcon.files().getIntangibles(), AutoEcon.files().getGroups()};
for (String price : sellPrices.keySet()) {
if (EconItem.fromString(price) != null) {
file[0].setPrice(price, sellPrices.get(price).getExpression());
file[0].setBuyRate(price, sellPrices.get(price).getBuyRate());
} else if (file[1].getLabels().contains(price)) {
file[1].setPrice(price, sellPrices.get(price).getExpression());
file[1].setBuyRate(price, sellPrices.get(price).getBuyRate());
} else if (file[2].getLabels().contains(price)) {
file[2].setPrice(price, sellPrices.get(price).getExpression());
file[2].setBuyRate(price, sellPrices.get(price).getBuyRate());
}
}
}
public Double setExpression(String id, String expr) {
savePrices();
MFilePrices file[] = {AutoEcon.files().getPrices(), AutoEcon.files().getIntangibles(), AutoEcon.files().getGroups()};
if (EconItem.fromString(id) != null)
file[0].setPrice(id, expr);
else if (file[1].getLabels().contains(id))
file[1].setPrice(id, expr);
else if (file[2].getLabels().contains(id))
file[2].setPrice(id, expr);
else return null;
sellPrices.clear();
total=0;
loadPrices(AutoEcon.plugin());
return sellPrices.get(id).getPrice();
}
Another solution could be to create an array within the FilePool class where I'm getting the files from, which contains those three configuration files, or a method which puts them into an array and sends over the array. However, the latter just moves the problem over to another class, and the former is still creating a single array that is not totally necessary. Both of these solutions just moves the problem from one class to another.
public class FilePool {
private Config config;
private Prices prices;
private Intangibles i;
private Groups groups;
private Logs econLogs;
private ItemAliases a;
public FilePool(AutoEcon pl) {
config = new Config(pl);
prices = new Prices(pl);
i = new Intangibles(pl);
econLogs = new Logs(pl);
a = new ItemAliases(pl);
new ReadMe(pl);
}
public Config getConfig() {
return config;
}
public Prices getPrices() {
return prices;
}
public Groups getGroups() {
return groups;
}
public Intangibles getIntangibles() {
return i;
}
public Logs getLogs() {
return econLogs;
}
public ItemAliases getAliases() {
return a;
}
}
(Ignore the dumb variable names in the FilePool class, I just loved the fact that they all line up so perfectly. Will be naming appropriately before publishing) I know I'm being a bit over-anal about this tiny thing that won't affect the running program at all, but after being constantly harassed for every minor detail of my code by my colleagues in the past, I've grown to be a bit of a perfectionist.
Thanks to anyone who spent their time reading this. <3
The creation of the array is not a problem. Resources to create an array are meaningless. What is more of a problem is that anyone reading your code will struggle to understand what the magic indices represent without referring back to the array. Which means that you should turn them into named constants which will complicate your code even further.
Much better is to have clear variable names that represent what each element represents. Also a good idea to iterate through the map so you can avoid getting the value for each item:
FilePool files = AutoEcon.files();
final MFilePrices prices = files.getPrices();
final MFilePrices intangibles = files.getIntangibles();
final MFilePrices groups = files.getGroups();
sellPrices.forEach((price, value) -> {
if (EconItem.fromString(price) != null) {
setPriceAndBuyRate(prices, price, value);
} else if (intangibles.getLabels().contains(price)) {
setPriceAndBuyRate(intangibles, price, value);
} else if (groups.getLabels().contains(price)) {
setPriceAndBuyRate(groups, price, value);
}
});
private void setPriceAndBuyRate(MFilePrices filePrices, Price price, Value value) {
filePrices.setPrice(price, value.getExpression());
filePrices.setBuyRate(price, value.getBuyRate());
}
If you're concerned that the number of variables make the method difficult to read then move the logic for comparing the price to the labels and setting the price and buy rate into a separate class. That's a good practice in any case as it gives the class a single reason to change.