1. 메서드에서 객체를 생성하면 생기는 문제점
코드를 작성하다 보면 특정 메서드 안에서 객체를 생성하는 경우가 많다.
- 메서드가 호출될 때마다 객체가 매번 생성됨
- 같은 객체를 계속해서 새로 만들면 불필요한 메모리 사용이 증가할 수 있다.
- 객체를 생성하려면 반드시 해당 메서드를 호출해야 함
- 필요한 객체를 생성하려면 특정 메서드를 실행해야 하는데, 이는 불편함을 초래할 수 있다.
- 다른 메서드에서 생성된 객체를 사용할 수 없음
- 메서드 내부에서 생성된 객체는 해당 메서드 안에서만 사용할 수 있어, 클래스 내의 다른 메서드에서는 접근이 불가능하다.
2. 올바른 객체 생성 방식
이러한 문제를 해결하려면, 클래스의 필드(변수)로 객체를 선언하고 관리하는 것이 좋다.
- 클래스 변수로 선언하면 객체를 여러 메서드에서 공유할 수 있다.
- 필요한 경우에만 객체를 생성하면 불필요한 메모리 낭비를 줄일 수 있다.
- 공통 타입을 사용하여 여러 객체를 담을 수 있도록 설계하면 유지보수가 쉬워진다.
3. 객체를 효과적으로 관리하는 방법: 상위 클래스로 묶기
객체를 생성하고 관리하는 좋은 방법 중 하나는 상위 클래스를 정의하여 공통 부분을 묶는 것입니다. 이를 위해 일반 클래스, 추상 클래스, 인터페이스를 적절히 활용할 수 있다.
일반 클래스
- 자식 클래스 간 공통된 코드가 많을 때 사용한다.
- extends 키워드를 사용하여 상속을 구현한다.
- 객체로 직접 생성할 수 있다.
추상 클래스
- 공통된 기능(메서드)과 일부 강제해야 할 메서드(추상 메서드)를 함께 정의할 때 사용한다.
- extends를 사용하여 상속하며, 일부 메서드는 반드시 자식 클래스에서 구현해야 한다.
인터페이스
- 공통된 메서드의 형식(껍데기)만 정의하고, 실제 구현은 각 클래스에서 다르게 할 때 사용한다.
- implements 키워드를 사용하여 구현한다.
아래는 객체 관리에 대한 설명을 들으면서 참고한 코드입니다.
Person.java
package phone;
public class Person {
Phone phone;
public void buy(Phone phone) {
this.phone = phone;
}
public void turnOnPhone() {
// 폰을 켰어야 했어요.
// SamsungPhone samsungPhone = new SamsungPhone();
/**
* 메소드 안에서 객체를 생성하면 안되는 이유
* 1) 메소드가 호출될 때마다 객체가 매번 생성
* 2) 객체를 생성하려면.. 이 메소드를 호출해야해..흠..
* 3) 다른 메소드에서는 이 객체를 쓸 수가 없다.
*/
phone.turnOn();
}
public void turnOffPhone() {
phone.turnOff();
}
}
Phone.java
package phone;
public interface Phone {
public abstract void turnOn();
//{
//System.out.println("@@@"); //일반 클래스 사용 시
//}
public abstract void turnOff();
// {
// System.out.println("띠로리로");
// }
}
PhoneDemo.java
package phone;
public class PhoneDemo {
public static void main(String[] args) {
Person jini = new Person();
SamsungPhone samsungPhone = new SamsungPhone();
jini.buy(samsungPhone); // 삼성폰
jini.turnOnPhone();
jini.turnOffPhone();
iPhone iPhone = new iPhone();
jini.buy(iPhone); // 아이폰 삽니다!
jini.turnOnPhone();
jini.turnOffPhone();
}
}
SamsungPhone.java
package phone;
public class SamsungPhone implements Phone {
@Override
public void turnOn() {
System.out.println("삼성폰이 켜짐 ***");
}
@Override
public void turnOff() {
System.out.println("띠로리로");
}
}
iPhone.java
package phone;
public class iPhone implements Phone{
@Override
public void turnOn() {
System.out.println("아이폰이 켜짐 @@@");
}
@Override
public void turnOff() {
System.out.println("띠로리로");
}
}
4. 데이터베이스와 백엔드 개발에서의 중요성
백엔드 개발에서는 데이터를 효율적으로 관리하기 위해 데이터베이스를 적극적으로 활용한다.
백엔드가 데이터베이스를 사용하는 이유
- 프로젝트 개발 업무
- 데이터 처리 및 연산 (CRUD 작업, JOIN, SUBQUERY 등)
- 운영 업무
- 데이터 집계 및 분석 (예: 매출액 계산, 에러 횟수 카운트)
- 정기적인 집계 처리를 자동화 (예: PROCEDURE 활용)
5. SQL 코딩 테스트에서 자주 사용하는 문법
백엔드 개발을 위해 SQL 코딩 테스트 준비도 중요하다.
- 집계 함수(Aggregate Functions), 윈도우 함수(Window Functions)
- GROUP BY vs PARTITION BY
- GROUP BY: 특정 기준으로 데이터를 그룹화하여 집계할 때 사용
- PARTITION BY: 특정 범위 내에서 데이터를 분석할 때 사용
- 기본적인 SQL 문법
- LEFT JOIN: 두 개의 테이블을 연결할 때 사용
- UNION: 두 개의 결과를 하나의 결과로 합칠 때 사용