Skip to content
107 changes: 107 additions & 0 deletions me/day05/practice/Electronic.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package me.day05.practice;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.Objects;

public class Electronic {

enum CompanyName { SAMSUNG, LG, APPLE }
enum AuthMethod { FINGERPRINT, PIN, PATTERN, FACE }

private static int registrationNo;

private String productNo;
private String modelName;
private CompanyName companyName;
private String dateOfMade;
private AuthMethod[] authMethod;

Electronic () {
registrationNo++;
setDateOfMade();
setProductNo();
}

Electronic (String modelName, CompanyName companyName, AuthMethod[] authMethod) {
this();
this.modelName = modelName;
this.companyName = companyName;
this.authMethod = authMethod;
}

private void setDateOfMade(){
DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("yyMMdd");
dateOfMade = timeFormatter.format(LocalDate.now());
}

private void setProductNo(){
if (registrationNo >= 10000) setRegistrationNo();
productNo = dateOfMade + String.format("%4d", registrationNo).replace(" ", "0");
}

private void setRegistrationNo(){
registrationNo %= 10000;
}

public boolean isContainAuthMethod(AuthMethod authMethod){
for (AuthMethod auth : this.authMethod)
if (authMethod.equals(auth)) return true;
return false;
}
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 부분은 요구사항에는 없었지만
Electronics클래스의 groupByAuthMethod()를 구현하다가
있었으면 좋겠다는 느낌이 들어 추가했습니다.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

굳굳!!
근데 is contain이 문법적으로 맞나요?

꼭 단어나 문법이 정확하진 않아도 되지만 가급적이면 지켜주는게 좋아요.
map의 containsKey가 있으니 저라면 'contains~'로 지었을거 같네요.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

헉! 지금까지 계속 contain으로 사용하고 있었네요 맙소사,, 감사합니다


public String getProductNo() {
return productNo;
}

public String getModelName() {
return modelName;
}

public void setModelName(String modelName) {
this.modelName = modelName;
}

public CompanyName getCompanyName() {
return companyName;
}

public void setCompanyName(CompanyName companyName) {
this.companyName = companyName;
}

public String getDateOfMade() {
return dateOfMade;
}

public AuthMethod[] getAuthMethod() {
return authMethod;
}

public void setAuthMethod(AuthMethod[] authMethod) {
this.authMethod = authMethod;
}

@Override
public int hashCode() {
return Objects.hash(productNo, modelName, companyName, dateOfMade, Arrays.hashCode(authMethod));
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

꼭 모든 프로퍼티가 아니라 특정 몇개의 프로퍼티로 hashCode를 만들기도 하죠. 좋은 아이디어네요.
다만 hashCode는 속도 비교가 아니라 registrationNo가 Electoronic의 해시값이 될 수 있도록 골고루 분산되어 있을까를 더 고민해야합니다.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 부분은 한번 찾아보고, 고민해 보겠습니다


@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
return Objects.equals(productNo, ((Electronic)obj).productNo);
}

@Override
public String toString() {
return "Electronic { " +
"productNo=" + productNo +
", modelName=" + modelName +
", companyName= " + companyName +
", dateOfMade=" + dateOfMade +
", authMethod=" + Arrays.toString(authMethod) + " }";
}
}
148 changes: 148 additions & 0 deletions me/day05/practice/Electronics.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
package me.day05.practice;

import me.day05.practice.Electronic.AuthMethod;
import me.day05.practice.Electronic.CompanyName;

import java.util.*;

public class Electronics {

private static final int DEFAULT_CAPACITY = 10; // Default initial capacity
private static final Electronic[] EMPTY_ELECTRONIC_LIST = {};

private static Electronic[] electronicList;
private static Electronics electronicsInstance;

private int size;
private int capacity;

Electronics(){
electronicList = EMPTY_ELECTRONIC_LIST;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

싱글톤으로 사용하고자 한다면 생성자는 private으로 막아주는 것이 일반적입니다.
ELECTRONIC_LIST가 비어있기 때문에 상관없다고 생각할 수 있으나 당장 생성에는 문제가 없어서 이 코드를 사용하는 다른 개발자에게 혼란을 주기 쉽거든요.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

헉 너무 기본적인 실수,, 열번 백번 더 확인하겠습니다,,!


// TODO: 1. Electronics 클래스의 객체를 싱글톤으로 생성하는 함수를 작성하시오.
public static Electronics getInstance() {
if (electronicsInstance == null) electronicsInstance = new Electronics();
return electronicsInstance;
}

// TODO: 2. 전자제품 일련번호 productNo를 통해 인자로 주어진 일련번호에 해당하는 전자제품을 반환하는 함수를 작성하시오.
public Optional<Electronic> findByProductNo(String productNo){
for (Electronic electronic : electronicList)
if (productNo.equals(electronic.getProductNo()))
return Optional.of(electronic);

return Optional.empty();
}
Comment on lines +29 to +35
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

equals() 메소드를 사용할 때 모종의 상황 발생으로
electronicNull일 경우 NPE가 발생할 수 있다고 생각하였습니다.

다시 생각해보니 productNo도 인자 값을 Null으로 넘기는 경우에 NPE가 발생하는데
널 참조 방지 코드를 추가하는 게 좋을까요?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이정도면 충분할 것 같습니다. (사실 해도 됩니다. null 체크야 해서 나쁠건 없지만, 지금 코드가 보편적이긴 합니다.)
Electronic쪽에서 productNo는 null이 안되도록 강제하면 더 좋겠네요.


// TODO: 3. 전자제품들 중 인자로 주어진 제조 회사를 찾아서 하나의 배열에 반환하는 함수를 작성하시오.
public Optional<Electronic[]> groupByCompanyName(CompanyName company){
Electronic[] companyNameGroup = null;

List<Electronic> temp = new ArrayList<>();

for (Electronic electronic : electronicList)
// 테스트용 임시 조건 ( electronic != null )
if (electronic != null && electronic.getCompanyName().equals(company))
temp.add(electronic);
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 부분은 electronic에 대한 Null 체크가 진행되어서
electronic의 companyName에 대한 equals()를 호출하였습니다.


if (!temp.isEmpty()) {
companyNameGroup = new Electronic[temp.size()];
for (int i = 0; i < companyNameGroup.length; i++)
companyNameGroup[i] = temp.get(i);
}

return Optional.ofNullable(companyNameGroup);
}

public Optional<Electronic> findByCompanyName(CompanyName company){
for (Electronic electronic : electronicList)
if (company.equals(electronic.getCompanyName()))
return Optional.of(electronic);

return Optional.empty();
}

// TODO: 4. 전자제품들 중 인자로 주어진 인증 방법을 찾아서 하나의 배열에 반환하는 함수를 작성하시오.
public Optional<Electronic[]> groupByAuthMethod(AuthMethod authMethod){
Electronic[] authMethodNameGroup = null;

List<Electronic> temp = new ArrayList<>();

for (Electronic electronic : electronicList)
// 테스트용 임시 조건 ( electronic != null )
if (electronic != null && electronic.isContainAuthMethod(authMethod))
temp.add(electronic);

if (!temp.isEmpty()) {
authMethodNameGroup = new Electronic[temp.size()];
for (int i = 0; i < authMethodNameGroup.length; i++)
authMethodNameGroup[i] = temp.get(i);
}

return Optional.ofNullable(authMethodNameGroup);
}

public int getSize() {
return size;
}

public void setSize(int size) {
this.size = size;
}

public int getCapacity() {
return capacity;
}

public void setCapacity(int capacity) {
this.capacity = capacity;
}

@Override
public int hashCode() {
return Objects.hash(Arrays.hashCode(electronicList), size, capacity);
}

@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
return Objects.equals(hashCode(), ((Electronics)obj).hashCode());
}

@Override
public String toString() {
return "Users { " +
"size=" + size +
", capacity=" + capacity +
", electronicList= " + Arrays.toString(electronicList) + " }";
}

//==================================== TEST CODE ====================================//
public void add (Electronic electronic) {
if (electronicList == EMPTY_ELECTRONIC_LIST)
electronicList = new Electronic[DEFAULT_CAPACITY];
/* 배열 크기 체크하고 늘리는 로직 구현 할 것 */
electronicList[size++] = electronic;
}

public static void main(String[] args) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오잉? 이건 지우는게 좋을 것 같아요.
혼자 테스트 하는 용도라도 진짜 프로젝트 main문에서 해보실까요?

Electronics class에서 하시면 안될 것 같아요!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ㅎㅎ,, 이번 과제는 구현과제라서 저 혼자 테스트 해보고
멘토님도 테스트 해보실 줄 알고 놔뒀습니다.

다음부턴 지우거나
테스트코드를 JUnit을 사용해서 따로 작성하던가 하겠습니다!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

좋습니다!

Electronic iPhone13 = new Electronic("아이폰13", CompanyName.APPLE, new AuthMethod[]{AuthMethod.FACE, AuthMethod.PIN, AuthMethod.PATTERN});
Electronic iPhone12 = new Electronic("아이폰12", CompanyName.APPLE, new AuthMethod[]{AuthMethod.FACE, AuthMethod.PIN, AuthMethod.PATTERN});
Electronic galaxyS22 = new Electronic("갤럭시S22", CompanyName.SAMSUNG, new AuthMethod[]{AuthMethod.FINGERPRINT, AuthMethod.PIN, AuthMethod.PATTERN});

Electronics electronics = getInstance();
electronics.add(iPhone13);
electronics.add(iPhone12);
electronics.add(galaxyS22);

// System.out.println(electronics);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

의미 없는 코드는 제거해주세요.


Optional<Electronic[]> authMethodGroupPIN = electronics.groupByAuthMethod(AuthMethod.FACE);
authMethodGroupPIN.ifPresent(value -> System.out.println(Arrays.toString(value)));

Optional<Electronic[]> companyNameGroupAPPLE = electronics.groupByCompanyName(CompanyName.SAMSUNG);
companyNameGroupAPPLE.ifPresent(value -> System.out.println(Arrays.toString(value)));
}
}
136 changes: 136 additions & 0 deletions me/day05/practice/User.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
package me.day05.practice;

import java.time.LocalDate;
import java.util.Arrays;
import java.util.Objects;

public class User {

private String userId;
private String userPassword;
private String userPhoneNumber;
private String userEmail;
private String userBirthDate;
private Electronic[] electronicDevice;
private LocalDate registerTime;

User() {

setRegisterTime();
}

User(String userId, String userPassword, String userPhoneNumber, String userEmail, String userBirthDate, Electronic[] electronicDevice) {
this();
this.userId = userId;
this.userPassword = userPassword;
this.userPhoneNumber = userPhoneNumber;
this.userEmail = userEmail;
this.userBirthDate = userBirthDate;
this.electronicDevice = electronicDevice;
}

private User(String userId, String userPassword, String userPhoneNumber, String userEmail, String userBirthDate, Electronic[] electronicDevice, LocalDate registerTime){
this.userId = userId;
this.userPassword = userPassword;
this.userPhoneNumber = userPhoneNumber;
this.userEmail = userEmail;
this.userBirthDate = userBirthDate;
this.electronicDevice = electronicDevice;
this.registerTime = registerTime;
}

private void setRegisterTime() {
registerTime = LocalDate.now();
}

public String getUserId() {
return userId;
}

public void setUserId(String userId) {
this.userId = userId;
}

public String getUserPassword() {
return userPassword;
}

public void setUserPassword(String userPassword) {
this.userPassword = userPassword;
}

public String getUserPhoneNumber() {
return userPhoneNumber;
}

public void setUserPhoneNumber(String userPhoneNumber) {
this.userPhoneNumber = userPhoneNumber;
}

public String getUserEmail() {
return userEmail;
}

public void setUserEmail(String userEmail) {
this.userEmail = userEmail;
}

public String getUserBirthDate() {
return userBirthDate;
}

public void setUserBirthDate(String userBirthDate) {
this.userBirthDate = userBirthDate;
}

public Electronic[] getElectronicDevice() {
return electronicDevice;
}

public void setElectronicDevice(Electronic[] electronicDevice) {
this.electronicDevice = electronicDevice;
}

public LocalDate getRegisterTime() {
return registerTime;
}

// private void validatePhoneNumberFormat(String userPhoneNumber){}
// private String formatPhoneNumber(String userPhoneNumber){ validatePhoneNumberFormat(userPhoneNumber) }
//
// private void validateUserEmailFormat(String userPhoneNumber){}
// private String formatUserEmail(String userPhoneNumber){ validateUserEmailFormat(String userPhoneNumber) }
//
// private void validateUserBirthDateFormat(String userBirthDate){}
// private String formatUserBirthDate(String userBirthDate){ validateUserBirthDateFormat(String userBirthDate) }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

사용되지 않는 코드는 지워주세요.


@Override
public int hashCode() {
return Objects.hash(userId, userPassword, userEmail, userBirthDate, Arrays.hashCode(electronicDevice), registerTime);
}

@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
return Objects.equals(hashCode(), ((User)obj).hashCode());
}

@Override
public String toString() {
return "User { " +
"userId=" + userId +
", userPassword=" + userPassword +
", userPhoneNumber= " + userPhoneNumber +
", userEmail=" + userEmail +
", userBirthDate=" + userBirthDate +
", electronicDevice=" + Arrays.toString(electronicDevice) +
", registerTime=" + registerTime + " }";
}

@Override
protected User clone() {
return new User(userId, userPassword, userPhoneNumber, userEmail, userBirthDate, electronicDevice, registerTime);
}
}

Loading