bookSeat메소드는 가장 간단하게는 View.tag 속성을 이용하여 아래처럼 처리할 수는 있습니다.
private void bookSeat(Integer colNo, Integer rowNo) {
Button seat = Objects.requireNonNull(board[colNo - 1][rowNo - 1]);
Object bookedStatusValue = seat.getTag(R.string.booked_status_key);
Boolean isBooked = bookedStatusValue == null ? Boolean.FALSE : (Boolean) bookedStatusValue;
if (isBooked) {
Toast.makeText(getApplicationContext(), "예약이 완료된 자리입니다. 다시 예약하세요.", Toast.LENGTH_LONG).show();
return;
}
seat.setBackgroundColor(Color.parseColor("#FF0000"));
seat.setTag(R.string.booked_status_key, Boolean.TRUE);
}
하지만 이 방법은 상태의 관리를 위해 불필요하게 뷰를 건드리기 때문에 코드의 관점에서는 좋은 않은 코드입니다. 이런 코드는 데이터를 저장거나 단위테스트 하기에 좋지 않고, 유지보수 할 때도 금방 엉망이 되기 쉬운 bad practice에 해당하는 코드입니다. Seat와 Board라는 클래스를 만들고 예약상태를 좌석에 따라 관리하고 이걸 기반으로 뷰만 업데이트 방식이 더 좋은 코드입니다.
데이터를 중심으로 해서 뷰를 단지 데이터를 화면에 보여주는 멍청한 뷰(더 좋은 코드임)로 만드는 에제롤 적어봅니다. 제 코드가 최선은 아닙니다. 다만 개념을 보여주는 용도이므로 참고만 하시고 제가 말씀드리는 포인트를 이해하시고 코드를 작성하시기 바랍니다.
public class Seat {
private final int id;
private final String label;
private boolean booked;
private int xPos;
private int yPos;
public Seat(int id, String label, int xPos, int yPos) {
this.id = id;
this.label = label;
this.xPos = xPos;
this.yPos = yPos;
}
public int getId() {
return id;
}
public String getLabel() {
return label;
}
public boolean isBooked() {
return booked;
}
public void setBooked(boolean booked) {
this.booked = booked;
}
public int getxPos() {
return xPos;
}
public void setxPos(int xPos) {
this.xPos = xPos;
}
public int getyPos() {
return yPos;
}
public void setyPos(int yPos) {
this.yPos = yPos;
}
@Override
public String toString() {
return "Seat{" +
"id=" + id +
", label='" + label + '\'' +
", booked=" + booked +
", xPos=" + xPos +
", yPos=" + yPos +
'}';
}
}
import java.util.Objects;
public class Board {
private Seat[][] seats;
public void createSeats(int[][] boardIds) {
int colCount = boardIds.length;
int rowCount = boardIds[0].length;
seats = new Seat[colCount][rowCount];
for (int i = 0; i < colCount; i++) {
for (int j = 0; j < rowCount; j++) {
int seatId = boardIds[i][j];
String label = "" + ((i % rowCount) * rowCount + j + 1);
seats[i][j] = new Seat(seatId, label, i, j);
}
}
}
public Seat[][] getSeats() {
return seats;
}
public BookResult bookSeat(String colText, String rowText) {
BookResult validationResult = validate(colText, rowText);
if (!validationResult.isSuccess()) return validationResult;
Seat seat = validationResult.getSeat();
seat.setBooked(true);
return BookResult.success(seat);
}
private BookResult validate(String colText, String rowText) {
Integer colNo = strToInt(colText);
Integer rowNo = strToInt(rowText);
if (colNo == null || rowNo == null) {
return BookResult.error("잘못된 입력입니다. 다시 입력하세요.");
}
if ((colNo > 5 || colNo < 1) || (rowNo > 5 || rowNo < 1)) {
return BookResult.error("잘못된 입력입니다. 다시 입력하세요.");
}
Seat seat = Objects.requireNonNull(seats[colNo - 1][rowNo - 1]);
if (seat.isBooked()) {
return BookResult.error("예약이 완료된 자리입니다. 다시 예약하세요.");
}
return BookResult.success(seat);
}
private Integer strToInt(String s) {
try {
return Integer.parseInt(s);
} catch (NumberFormatException e) {
return null;
}
}
}
public class BookResult {
private final boolean success;
private final String message;
private Seat seat;
private BookResult(boolean success, String message, Seat seat) {
this.success = success;
this.message = message;
this.seat = seat;
}
public static BookResult success(Seat seat) {
return new BookResult(true, null, seat);
}
public static BookResult error(String message) {
return new BookResult(false, message, null);
}
public boolean isSuccess() {
return success;
}
public String getMessage() {
return message;
}
public Seat getSeat() {
return seat;
}
}
public class MainActivity extends AppCompatActivity {
private static final String BOOKED_COLOR = "#FF0000";
private EditText row, col;
private Button btn1;
private TextView textResult;
//private int pax; //용도를 알 수없어 주석처리
private Button[][] seatViews = new Button[5][5];
private static final int[][] boardIds = {{R.id.seat11, R.id.seat12, R.id.seat13, R.id.seat14, R.id.seat15},
{R.id.seat21, R.id.seat22, R.id.seat23, R.id.seat24, R.id.seat25},
{R.id.seat31, R.id.seat32, R.id.seat33, R.id.seat34, R.id.seat35},
{R.id.seat41, R.id.seat42, R.id.seat43, R.id.seat44, R.id.seat45},
{R.id.seat51, R.id.seat52, R.id.seat53, R.id.seat54, R.id.seat55}};
private final Board board = new Board();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_acivity);
row = findViewById(R.id.row);
col = findViewById(R.id.col);
btn1 = findViewById(R.id.btn1);
textResult = findViewById(R.id.textResult);
//pax = 25;
for (int i = 0; i < boardIds.length; i++) {
for (int j = 0; j < boardis[i].length; j++) {
seatViews[i][j] = findViewById(boardIds[i][j]);
}
}
board.createSeats(boardIds);
updateSeats();
btn1.setOnClickListener(v -> bookSeat());
}
private void bookSeat() {
BookResult bookResult = board.bookSeat(col.getText().toString(), row.getText().toString());
if (!bookResult.isSuccess()) {
Toast.makeText(this, bookResult.getMessage(), Toast.LENGTH_SHORT).show();
return;
}
updateSeats();
}
private void updateSeats() {
Seat[][] seats = board.getSeats();
for (Seat[] seat : seats) {
for (Seat value : seat) {
Button seatView = seatViews[value.getxPos()][value.getyPos()];
seatView.setText(value.getLabel());
if (value.isBooked()) {
seatView.setBackgroundColor(Color.parseColor(BOOKED_COLOR));
}
}
}
}
}