我正在用Java做一个教程,我总是读到我必须尽量不要重复,我注意到这是非常重复的;因此,如果有人能给我一些提示,以减少重复性或某种程度上更好,它是非常适合的。谢谢;)(这不是教程的一部分,我只是为了好玩,因为我在学校的科学学习)
Run.java 文件:
package scientificFormula;
public class Run {
public static void main(String[] args) {
Formula formula = new Formula();
formula.compound1 = args[0];
formula.compound2 = args[1];
String theFormula = formula.createFormula();
System.out.println("Molecule: " + args[0] + " " + args[1] + " = "
+ theFormula);
}
}
Formula.java 文件:
package scientificFormula;
import java.util.HashMap;
import java.util.Map;
public class Formula {
String compound1;
String compound2;
static private Map<String, String> map = new HashMap<String, String>();
static private void initiateIons() {
// 1+
map.put("Hydrogen", "H^1+");
map.put("Lithium", "Li^1+");
map.put("Sodium", "Na^1+");
map.put("Potassium", "K^1+");
map.put("Rubidium", "Rb^1+");
// 2+
map.put("Magnesium", "Mg^2+");
map.put("Calcium", "Ca^2+");
map.put("Strontium", "Sr^2+");
// 3+
map.put("Aluminium", "Al^3+");
// 3-
map.put("Nitrogem", "N^-3");
map.put("Phosphorus", "P^-3");
// 2-
map.put("Oxygen", "O^-2");
map.put("Sulfur", "S^-2");
map.put("Selenium", "Se^-2");
// 1-
map.put("Fluorine", "F^-1");
map.put("Chlorine", "Cl^-1");
map.put("Bromine", "Br^-1");
map.put("Iodine", "I^-1");
}
String createFormula() {
initiateIons();
// Example1: Input = Calcium Iodine:
// 2x + -1y = 0
// x = 1 and y = 2
// Output = CaI2
//
// Example2: Input = Sulfur Iodine
// Output = Molecule: Sulfur Iodine = SI2
String symbol1 = map.get(compound1);
String symbol2 = map.get(compound2);
int charge1 = Integer.parseInt(symbol1.replace("+", "").substring(
symbol1.length() - 2));
int charge2 = Integer.parseInt(symbol2.replace("+", "").substring(
symbol2.length() - 2));
String letter1 = null;
String letter2 = null;
if (symbol1.length() == 5) {
letter1 = symbol1.substring(0, 2);
} else if (symbol1.length() == 4) {
letter1 = symbol1.substring(0, 1);
}
if (symbol2.length() == 5) {
letter2 = symbol2.substring(0, 2);
} else if (symbol2.length() == 4) {
letter2 = symbol2.substring(0, 1);
}
int possitive1 = (int) Math.sqrt(charge1 * charge1);
int possitive2 = (int) Math.sqrt(charge2 * charge2);
if ((possitive1 == 1) & (possitive2 == 1)) {
return letter1 + letter2;
} else if (possitive1 == 1) {
return letter1 + possitive2 + letter2;
} else if (possitive2 == 1) {
return letter1 + letter2 + possitive1;
}
if (possitive1 == 0) {
possitive1 = -(charge1);
}
if (possitive2 == 0) {
possitive2 = -(charge2);
}
return letter1 + possitive2 + letter2 + possitive1;
}
}
答案 0 :(得分:3)
我强烈建议您阅读主要涉及重构的书clean code。
当您开始重构时,复制代码只是一个(重要)问题(也称为 DRY - 不要重复自己)。还有许多其他原则,我将尝试描述一些我认为最重要的原则:
一个重要的经验法则&#34;是 SRP :单一责任原则,它说每个类应该只有一个责任,如果我们将相同的想法应用于方法 - 每个方法应该只做一件事!听起来可能非常严格,但是当您开始应用它时 - 您的代码将变得更清晰,更易于维护。
另一个是使用有意义的名称(类/方法/变量):
return letter1 + possitive2 + letter2; // you probably meant positive with one 's' (typo!)
对你来说可能意味着什么 - 但对另一位读者来说并不意味着什么 - 现在,当然你可以通过添加代码注释来解决它,但是修补问题而不是解决问题。此外,代码注释变得陈旧 - 要么变得无关紧要,要么变得更糟 - 当代码发生变化并且注释没有时,可能会误导读者。
最后(现在),保持明确的执行顺序,让我们采取你发布的一段代码并改进它:
String symbol1 = map.get(compound1);
String symbol2 = map.get(compound2);
int charge1 = Integer.parseInt(symbol1.replace("+", "").substring(
symbol1.length() - 2));
int charge2 = Integer.parseInt(symbol2.replace("+", "").substring(
symbol2.length() - 2));
String letter1 = null;
String letter2 = null;
if (symbol1.length() == 5) {
letter1 = symbol1.substring(0, 2);
} else if (symbol1.length() == 4) {
letter1 = symbol1.substring(0, 1);
}
if (symbol2.length() == 5) {
letter2 = symbol2.substring(0, 2);
} else if (symbol2.length() == 4) {
letter2 = symbol2.substring(0, 1);
}
int possitive1 = (int) Math.sqrt(charge1 * charge1);
int possitive2 = (int) Math.sqrt(charge2 * charge2);
我们可以看到:正面取决于取决于依赖于化合物的符号的电荷。与它无关:字母取决于依赖于化合物的符号。
让我们将其拆分为单独的方法:
int getPositive(String compound) { // I have no idea what "positive", "symbol" and compound represent, consider better names please
String symbol = map.get(compound);
int charge = Integer.parseInt(symbol.replace("+", "").substring(
symbol.length() - 2));
return (int) Math.sqrt(charge2 * charge2);
}
现在我们可以将其应用于getLetter(String compound) {...}
等。
答案 1 :(得分:2)
我会把一些解析放到自己的类中,也许你甚至可以在构建更多功能时将更多内容卸载到那里。
public class Symbol {
final int charge;
final String letter;
public Symbol(String str) {
int sepIndex = str.indexOf('^');
if(sepIndex != -1) {
letter = str.substring(0, sepIndex);
charge = Integer.parseInt(str.substring(sepIndex+1).replace("+", ""));
} else {
throw new IllegalArgumentException(str + " isnt a valid Symbol, no ^ found");
}
}
}
public class Formula {
String compound1;
String compound2;
static private Map<String, String> map = new HashMap<String, String>();
// make this a static block so its only called once.
static {
// 1+
map.put("Hydrogen", "H^1+");
map.put("Lithium", "Li^1+");
map.put("Sodium", "Na^1+");
map.put("Potassium", "K^1+");
map.put("Rubidium", "Rb^1+");
// 2+
map.put("Magnesium", "Mg^2+");
map.put("Calcium", "Ca^2+");
map.put("Strontium", "Sr^2+");
// 3+
map.put("Aluminium", "Al^3+");
// 3-
map.put("Nitrogem", "N^-3");
map.put("Phosphorus", "P^-3");
// 2-
map.put("Oxygen", "O^-2");
map.put("Sulfur", "S^-2");
map.put("Selenium", "Se^-2");
// 1-
map.put("Fluorine", "F^-1");
map.put("Chlorine", "Cl^-1");
map.put("Bromine", "Br^-1");
map.put("Iodine", "I^-1");
}
String createFormula() {
// Example1: Input = Calcium Iodine:
// 2x + -1y = 0
// x = 1 and y = 2
// Output = CaI2
//
// Example2: Input = Sulfur Iodine
// Output = Molecule: Sulfur Iodine = SI2
Symbol symbol1 = new Symbol(map.get(compound1));
Symbol symbol2 = new Symbol(map.get(compound2));
int possitive1 = Math.abs(symbol1.charge); // sqrt(a*a) == abs(a)
int possitive2 = Math.abs(symbol1.charge);
if ((possitive1 == 1) & (possitive2 == 1)) {
return symbol1.letter + symbol1.letter;
} else if (possitive1 == 1) {
return symbol1.letter + possitive2 + symbol2.letter;
} else if (possitive2 == 1) {
return symbol1.letter + symbol2.letter + possitive1;
}
// dead code, if positive1 is 0 then setting it to -0 does nothing
/*if (possitive1 == 0) {
possitive1 = -(symbol1.charge);
}
if (possitive2 == 0) {
possitive2 = -(symbol2.charge);
}*/
return symbol1.letter + possitive2 + symbol2.letter + possitive1;
}
}
答案 2 :(得分:1)
第一种方法:
getCharge(String symbol){
return Integer.parseInt(symbol.replace("+", "").substring(symbol.length() - 2));
}
第二种方法:
getLetter(String symbol){
if (symbol.length() == 5) {
return symbol.substring(0, 2);
} else if (symbol.length() == 4) {
return symbol.substring(0, 1);
}
}
答案 3 :(得分:1)
我相信这相当于您发布的代码 -
private static String checkCompound(String symbol) {
if (symbol.length() == 5) {
return symbol.substring(0, 2);
} else if (symbol.length() == 4) {
return symbol.substring(0, 1);
}
return "";
}
然后
String letter1 = checkCompound(symbol1);
String letter2 = checkCompound(symbol2);
if (charge1 > 0) {
if (charge2 > 0) {
return letter1 + letter2;
}
return letter1 + charge2 + letter2;
} else if (charge2 > 0) {
return letter1 + letter2 + charge1;
}
return letter1 + charge2 + letter2 + charge1;
最后,这个
if (possitive1 == 0) {
possitive1 = -(charge1);
}
已删除,因为它是-0
0
。
答案 4 :(得分:1)
好吧,首先让我们重新安排您的代码,以便所有的...... 1变量在一起。根据您的命名约定,您使用letter1来计算symbol1,使用symbol1来计算charge1等等......我只关注createFormula(),因为那是你要减小的部分。
String createFormula() {
initiateIons();
//Calculate symbol1, charge1, letter1, possitive1
String symbol1 = map.get(compound1);
int charge1 = Integer.parseInt(symbol1.replace("+", "").substring(
symbol1.length() - 2));
String letter1 = null;
if (symbol1.length() == 5) {
letter1 = symbol1.substring(0, 2);
} else if (symbol1.length() == 4) {
letter1 = symbol1.substring(0, 1);
}
int possitive1 = (int) Math.sqrt(charge1 * charge1);
//calculate symbol2, charge2, letter2, possitive2
String symbol2 = map.get(compound2);
int charge2 = Integer.parseInt(symbol2.replace("+", "").substring(
symbol2.length() - 2));
String letter2 = null;
if (symbol2.length() == 5) {
letter2 = symbol2.substring(0, 2);
} else if (symbol2.length() == 4) {
letter2 = symbol2.substring(0, 1);
}
int possitive2 = (int) Math.sqrt(charge2 * charge2);
//Returns
if ((possitive1 == 1) & (possitive2 == 1)) {
return letter1 + letter2;
} else if (possitive1 == 1) {
return letter1 + possitive2 + letter2;
} else if (possitive2 == 1) {
return letter1 + letter2 + possitive1;
}
if (possitive1 == 0) {
possitive1 = -(charge1);
}
if (possitive2 == 0) {
possitive2 = -(charge2);
}
return letter1 + possitive2 + letter2 + possitive1;
}
我同意,计算步骤似乎是多余的。拥有一个计算它们的函数并返回它们的元组会很奇妙,但是(据我所知)Java还没有元组。我们可以做一个字符串数组,然后从字符串中解析出来。这是一个不太冗余的代码修订版。
String[] calculatePieces(String compound){
String symbol = map.get(compound);
int charge = Integer.parseInt(symbol.replace("+", "").substring(
symbol.length() - 2));
String letter = null;
if (symbol.length() == 5) {
letter = symbol1.substring(0, 2);
} else if (symbol1.length() == 4) {
letter = symbol1.substring(0, 1);
}
int possitive = (int) Math.sqrt(charge * charge);
pieces = new String[4];
pieces[0] = symbol;
pieces[1] = charge + "";
pieces[2] = letter;
pieces[3] = possitive + "";
return pieces;
}
String createFormula() {
initiateIons();
String[] pieces1 = calculatePieces(compound1);
int charge1 = Integer.parseInt(pieces1[1]);
int possitive1 = Integer.parseInt(pieces1[3]);
String[] pieces2 = calculatePieces(compound2);
int charge2 = Integer.parseInt(pieces2[1]);
int possitive2 = Integer.parseInt(pieces2[3]);
//Returns
if ((possitive1 == 1) & (possitive2 == 1)) {
return pieces1[2] + pieces2[2];
} else if (possitive1 == 1) {
return pieces1[2] + possitive2 + pieces2[2];
} else if (possitive2 == 1) {
return pieces1[2] + pieces2[2] + possitive1;
}
if (possitive1 == 0) {
possitive1 = -(charge1);
}
if (possitive2 == 0) {
possitive2 = -(charge2);
}
return pieces1[2] + possitive2 + pieces2[2] + possitive1;
}
它好一点,但Java对返回单个对象的限制限制了它可以获得的清洁程度。使它变得更干净的方法是创建一个基本上充当(string,int,string,int)元组的包装器对象,但是如果你需要快速的话,那就不可能了。< / p>