public class MainActivity extends AppCompatActivity {
// 해당 클래스에만 사용하는 변수들이므로 private을 사용.
// 변수의 이름들을 뭘하는지 알기쉬운 이름들로 바꾸세요. 이렇게 애매모호한 이름을 사용하면,
// 한참 지나서 님이 짠 소스를 봐도 이해가 바로 가지 않아요. 몇개만 변경해서 사용합니다.
private EditText rpmEdit, num2, num3, horsePowerEdit, num5, num6, sum, sum1, sum2;
private Button pls, mia, gop, nau;
private Spinner correctionFactorSpinner;
private double a, b, a1, b1, a2, a3, velocity = 0, d = 0, e = 0, f = 0, f1 = 0, g = 0, h = 0, i = 0; // d=유효장력 e=긴장측장력 f=지수 g=초장력
// h=접촉각 => h대신에 접촉각을 의미하는 변수명을 사용하세요.
private String[] correctionFactors;
@Override
protected void onCreate( Bundle savedInstanceState ) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
correctionFactors = getResources().getStringArray(R.array.correction_factors);
rpmEdit = (EditText) findViewById(R.id.rpmEdit);
num2 = (EditText) findViewById(R.id.num2); // 풀리경
num3 = (EditText) findViewById(R.id.num3); // 축간거리
horsePowerEdit = (EditText) findViewById(R.id.horsePowerEdit);
num5 = (EditText) findViewById(R.id.num5); // 큰풀리경
correctionFactorSpinner = (Spinner) findViewById(R.id.correctionFactorSpinner); // 보정계수
sum = (EditText) findViewById(R.id.sum); // 첫째칸 출력물
sum1 = (EditText) findViewById(R.id.sum1); // 둘째칸 출력물
sum2 = (EditText) findViewById(R.id.sum2); // 둘째칸 출력물
pls = (Button) findViewById(R.id.pls);
pls.setOnClickListener(view ->
calculateClicked()
);
}
private void calculateClicked() {
Float cf = getCorrectionFactor();
if (cf == null) {
// TODO : 에러메세지를 보여주는 등의 적절한 에러처리를 할 것
return;
}
CalcuationResult result = calculate(cf);
bindCalcuationResult(result);
}
@Nullable
private Float getCorrectionFactor() {
int position = correctionFactorSpinner.getSelectedItemPosition();
return strToFloatOrNull(correctionFactors[position]);
}
private CalcuationResult calulate(float correctionFactor) {
...
// 입력값들을 파라미터로 받을 수 있다면, 이 로직을 별도의 클래스로 분리하기가 쉬워질 겁니다.
// 고정된 숫자들은 상수를 사용하세요. 코드를 읽기가 훨씬 수월해 집니다. eg. private static final String PI = 3.1416
d = (1000 * b1 * correctionFactor) / c; // 원래는 좌측 1.4 항목이 Spinner 선택값으로 치환되어야 함.
h = (180 - (60 * (a2 - b) / a1)) * 3.1416 / 180; // 접촉각 계산
f1 = 0.512 * h;
f = Math.pow(2.7183, f1);
e = d * (f / (f - 1));
g = (d / 2) * ((f + 1) / (f - 1)) * 1.5;
i = 2 * a1 + 1.57 * (b + a2) + Math.pow(a2 - b, 2) / (4 * a1);
return CalcuationResult(d, g, i);
}
private void bindCalcuationResult(CalculationResult result) {
sum1.setText(String.format("%.2f", result.getD()));
sum.setText(String.format("%.2f", result.getG()));
sum2.setText(String.format("%.2f", result.getI()));
}
@Nullable
private Float strToFloatOrNull(String s) {
try {
return Float.valueOf(s);
} catch (NumberFormatException e) {
return null;
}
}
}
public class CalcuationResult {
private final float d;
private final float g;
private final float i;
public CalcuationResult(float d, float g, float i) {
this.d = d;
this.g = g;
this.i = i;
}
public float getD() {
return d;
}
public float getG() {
return g;
}
public float getI() {
return i;
}
}
위처럼 하면 될 것 같은데, 제가 님이 작업하시는 분야의 용어는 잘 몰라서 클래스명, 메소드명, 변수명을 제맘대로 적절하지 않은 이름을 사용했기 때문에, 읽기쉬운 명확한 이름들로 변경하시기 바랍니다. 제가 일부 변경한 변수명 중 바뀌지 않은 부분이 있는데, 그 부분을 금방 아실 수 있으니, 고치시기 바랍니다.
그리고 계산 로직은 가능하면 별도로 클래스로 분리하시면 좋을 듯 합니다. 뷰와는 전혀 상관이 없는 코드이므로 계산로직이 변경되거나 하면 뷰를 건드릴 필요가 없습니다. 계산로직을 백그라운드 쓰레드에서 처리하는 것이 정석이지만, 위의 계산로직은 무겁지 않아 보이므로 우선은 메인쓰레드에서 처리하셔도 될 것같아 보입니다. 나중에 필요가 생기면 그 때 처리하시면 되겠네요.
계산로직 검증을 위해서 유닛테스트를 만드는 법을 공부하셔서 테스트를 짜시기를 강력하게 권장합니다. 이것만으로도 많은 버그를 방지하실 수 있어요.