Object
객체 선언 (Object declaration)
Singleton 패턴
✔ 클래스에 대해서 앱 전체에서 한 개의 인스턴스만 갖도록 하고, 전역 범위에서 해당 인스턴스에 접근할 수 있도록 만든 디자인 패턴
✔ 한 번의 객체 생성으로 모든 클래스가 공유할 수 있기 때문에 메모리 낭비를 줄일 수 있으며, 객체 로딩 시간이 줄어들어 성능이 향상된다.
✔ 자바의 싱글톤 패턴 구현 코드
public class SingleTon {
private static SingleTon instance;
private SingleTon() {
}
public static synchronized SingleTon getInstance() {
if (instance == null) {
instance = new SingleTon();
}
return instance;
}
}
특징
✔ 클래스 선언과 동시에 단일 인스턴스를 만들어 메모리에 저장해주기 때문에 Singleton 패턴으로 작동된다.
✔ 초기화는 obejct 객체 최초 접근 시점에 진행된다.
✔ 객체 생성과 동시에 생성자 호출없이 바로 만들어지기 때문에 생성자를 사용할 수 없다.
✔ 클래스나 인터페이스를 상속받을 수 있다.
✔ 프로퍼티, 메소드, init을 선언할 수 있다.
✔ 클래스 내부에서 선언할 수 있으나(여러 개 선언 가능), 한 개의 인스턴스만 생성된다.
✔ 자바에서 호출 시, INSTANCE를 사용해야 한다.
동반 객체 (Companion object)
특징
✔ 클래스 내부에만, 한 개의 companion object 생성이 가능하다.
✔ 클래스가 메모리에 로드되는 시점에 단 하나의 인스턴스만 생성되기 때문에 싱글톤 패턴이 적용된다.
✔ Static으로 컴파일되는 하나의 객체로써, 외부 클래스의 인스턴스 없이 companion object에 접근이 가능하다.
✔ 객체 선언처럼 상속, 함수, 프로퍼티가 가능하다.
✔ 클래스의 여러 인스턴스들이 공통으로 사용할 수 있는 프로퍼티, 함수들을 구현한다.
✔ 그러나, companion object는 오버라이드 할 수 없기 때문에 오버라이드가 필요한 경우에는 여러 생성자를 생성해서 상속을 하는 편이 좋다.
open class User {
val name: String
contructor(email: String) {
this.name = email.substringBefore("@")
}
constructor(id: Int) {
this.name = "$id"
}
}
class UserTest : User {
constructor(email: String) : super(email)
constructor(id: Int) : super(id)
}
✔ 코틀린에서 클래스 내부에 선언된 클래스는 기본적으로 static으로 컴파일 되는 중첩 클래스이며, 클래스 선언 앞에 inner와 object를 동시에 사용할 수 없기 때문에 외부 클래스의 멤버에 접근 가능한 inner와 다르게 object를 사용하면 바깥쪽 클래스의 멤버에 접근할 수 없다.
✔ 단, 객체를 생성하면서 접근하는 것은 가능한데, 이 때문에 private 생성자를 object 내에서 호출할 수 있게 되어서 팩토리 메서드 패턴을 구현하기에 적합하다. 또한, 외부에서는 할 수 없지만, companion object 내부에서는 외부 클래스의 private 프로퍼티, 함수에 대한 접근이 가능하다.
class User private constructor(private val name: String) {
private var age = 0
private fun printHello() {
LogUtil.d(TAG, "Hello $name $age")
}
companion object {
private const val TAG = "User"
fun createUser(email: String) = User(email.substringBefore('@'))
fun printUser(user: User) { // 외부 클래스에서는 접근이 불가능
user.age = 27
user.printHello()
}
}
}
>>> printUser(createUser("Ryong@tistory.com"))
Hello Ryong 27
팩토리 메서드 패턴
✔ 객체를 생성하기 위해 인터페이스, 추상클래스를 정의하지만 실제로 어떤 클래스의 인스턴스를 생성할지 결정하는 것은 서브 클래스에 맡기는 디자인 패턴
class User private constructor(val name: String) {
companion object {
fun emailUser(email: String) =
User(email.substringBefore('@'))
}
}
>>> val user = emailUser("ryong@tistory.com")
>>> println(user.name)
ryong
▫ User는 private constructor를 가지기 때문에 외부에서 생성할 수 없다.
▫ companion object는 외부 클래스(User)의 private property(name)에 접근할 수 있다.
▫ 외부에서는 companion object로 제공되는 팩토리 메서드(emailUser)를 이용해서만 객체를 생성할 수 있도록 제한할 수 있다.
▫ 이미 존재하는 인스턴스에 해당하는 데이터를 전달받으면 새 인스턴스를 만들지 않고, 캐시에 있는 기존 인스턴스를 반환한다.
무명 객체 (Anonymous object)
특징
✔ 이름 없이 쓰는 객체 식으로써, 한 번만 사용하는 객체라서 클래스를 정의하기 부담스러운 경우에 사용한다.
✔ 싱글톤 패턴이 아니며, 객체 식이 쓰일 때마다 새로운 인스턴스를 생성한다.
// case 1 : 무명 객체 사용
btn.setOnClickListener(object: OnClickListener {
override fun onCLick(v: View?) {
}
})
// case 2 : 변수에 대입
val listener = object: OnClickListener {
override fun onClick(v: View?) {
}
}
'Android > Concept' 카테고리의 다른 글
[Android] [Kotlin] Context (0) | 2021.11.05 |
---|---|
[Android] [Kotlin] 파일 입출력 (0) | 2021.09.26 |
[Android] [Kotlin] Retrofit (0) | 2021.09.25 |
[Android] [Kotlin] 네트워크 (0) | 2021.09.25 |
[Android] [Kotlin] 콘텐트 리졸버 (0) | 2021.09.23 |