일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 블록체인
- 그라파나
- play 강좌
- Play2 로 웹 개발
- 이더리움
- CORDA
- Adapter 패턴
- 파이썬 머신러닝
- 스위프트
- 스칼라
- hyperledger fabric
- 안드로이드 웹뷰
- 스칼라 강좌
- Golang
- 하이브리드앱
- 파이썬 데이터분석
- Actor
- Hyperledger fabric gossip protocol
- 주키퍼
- 플레이프레임워크
- 엔터프라이즈 블록체인
- akka 강좌
- 파이썬 동시성
- 파이썬
- 하이퍼레저 패브릭
- Play2
- Akka
- 파이썬 강좌
- 스칼라 동시성
- play2 강좌
- Today
- Total
HAMA 블로그
스칼라 강좌 (15) - Getter / Setter 본문
Getter 와 Setter
객체지향 프로그래밍에서 게터와 세터는 의도치 않게 이제 기본이 된 내용들 중 하나이지만 ( getter / setter 자체를 그냥 public 으로 변수 선언하는것과 마찬가지로 나쁘게 보는 시각도 있습니다. 객체지향은 외부 노출을 줄여야 한다고 보는데 게터,세터는 절차지향 마인드의 산물 ) 때로는 쓰기 귀찮아질 때 도 있긴합니다. 대부분의 게터와 세터는 매우 비슷하기 때문에 같은 기능을 하는 더 나은 방법이 있을거란 생각은 매우 타당 할 것이며 C# 에서는 그것을 위해 특별히 "프로퍼티"라는 것을 만들어서 아래와 같이 사용됩니다.
private String strName;
public String StrName
{
get { return this.strName; }
set
{
... 제어 ..
this.strName = value;
}
}
자바에서는 언어차원에서 편하게 쓰게 하기위한 장치는 없고(Java 1.7 에 @property 같은거 만들거란 말은 있었는데 안한듯?) IDE 차원이나 Lombok 같은 툴의 도움을 받습니다.
관련 읽을 거리:
* 왜 자바에서 getter / setter 는 악마인가 (영어)
* 왜 getter / setter 를 사용하는가 (영어)
* 정보은닉과 캡슐화의 차이 (한글)
* 홀럽 아저씨의 실용주의 디자인패턴 책에 왜 getter/setter 가 안 좋은지 나온다. ( 위 블로그의 한글버전)
게터,세터는 객체지향과 거리가 있으며 데이터의 흐름이 적을 수록 유지보수에 좋다라고 말 하고 있습니다. 즉 pull 해서 쓰지 말고 push 해서 쓰라는 지침. 즉 가져와서 하지 말고 맡겨라! 데이터베이스와 접점 부분등 몇몇 예외상황에 대해서도 말 합니다.
스칼라에서의 Getter / Setter
다음 첫번째 예를 보면 :
class Person() {
var name = ""
var age = 0
}
첫눈에 보기에 이 클래스가 단지 사람 객체를 만들고 그 이상 아무것도 없어 보이겠지만
사실 인스턴스화 되면 다음과 같이 get / set 을 할 수 있게 됩니다.
GET
//person 객체 만들고
person = new Person()
// age 과 name 속성을 출력한다.
println(person.age)
println(person.name)
SET
// Set the properties to different values
person.age = 34
person.name = "Dustin Martin"
매우 간단한데 이 예를 보면 이렇게 생각 하실 듯 합니다. 이것은 getters 와 setters 가 아니잖아!
자동으로 생성되는 Getter / Setter
스칼라에서는 어떤 객체의 멤버 중 비공개가 아닌 모든 var 멤버에 게터와 세터 메소드를 자동으로 정의해 줍니다. 이때 자동으로 정의해 주는 이름은 자바의 관례와 다르며 age 의 게터는 그냥 age 이고 세터는 age_= 입니다. 이때 필드에는 자동적으로 private[this] 가 붙는데 그 필드를 포함하는 객체에서만 접근할 수 있다는 의미이고 자동으로 만들어진 게터와 세터는 원래의 age 와 같은 가시성이됩니다. 즉 age 가 공개이기 때문에 공개가 된다는 뜻
자신만의 Getter / Setter 정의 하기 - (1)
여기서 만약 age 속성에 0살~200살까지의 범위를 확인하는 절차가 필요할때 어떤 일이 발생 할까?
name 에 특정한 방식으로 포맷을 정하고 싶을때 어떻게 할까?
스칼라에서 다루는 방법을 알아보겠습니다.
class Person() {
// age 속성을 private 로 바꾸고 , _age 으로 이름을 바꾸자.
private var _age = 0
var name = ""
// Getter
def age = _age
// Setter
def age_= (value:Int):Unit = _age = value
}
매우 간단한 코드인데. 첫번째로 "age" 를 "_age" 로 이름을 바꾸고 private 를 적용하였습니다.
GET
def age = _age
변수를 리턴하는 age 메소드를 정의하였습니다. 스칼라는 return 키워드를 요구하지 않습니다.
또한 Scala 는 메소드의 몸체에 괄호를 사용하는것이 의무가 아닙니다.
SET다음엔 setter 를 살펴보죠.
def age_= (value:Int):Unit = _age = value
- 메소드 이름은 "age_=" 입니다.
- :Unit 는 void 를 리턴하다는 것과 동등하며 생략가능합니다.
- priavate 변수인 _age 에 새 값인 value 를 대입한다는 뜻입니다.
아직까지 먼가 제한을 두는 코드가 들어 있지는 않았습니다. 이제 제한을 넣어 보죠.
자신만의 Getter / Setter 정의 하기 - (2)
class Time {
private [this] var h = 12
private [this] var m = 0
def hour : Int = h // getter
def hour_= (x : Int) { //setter
require (0 <= x && x < 24)
h = x
}
def minute = m // getter
def minute_= (x: Int) { // setter
require(0 <= x && x < 60)
m=x
}
}
자신만의 Getter / Setter 정의 하기 - (3)
class Termometer {
var celsius : Float = _ // celsius 의 getter/setter 는 디폴트구현을 사용
def fahrenheit = celsius * 9 / 5 + 32 //fahrenheit 는 메소드만 존재해도 됨
def fahrenheit_= (f : Float) {
celsius = ( f - 32 ) * 5 / 9
}
}
--------------------------------------------
var t = new Termometer
t.celsius = 100
t.fahrenheit = -40
fahrenheit 같이 변수를 명시적으로 선언하지 않고도 getter / setter 로 사용할 수 있습니다.
celsius 를 var 로 정의하며 초기화 값으로 _ 를 주었는데 이것은 디폴트값으로 영을 할당합니다.
영은 숫자에서는 0 이고 불리언에서는 false 이며 레퍼런스에서는 null 입니다. 자바에서 초기화 하지 않았을때 할당되는 동일한 규칙 이며 스칼라에서는 초기화를 생략할 수 없습니다. 만약 초기화 하지 않는다면 그건 추상변수를 선언해버립니다. 추상변수는 다음에 알아보시죠.
Getter / Setter 애노테이션
위에 보다시피 보통 스칼라 코드에서는 명시적인 필드 get,set 메소드가 필요 없습니다. 그냥 디폴트 구현을 사용하다가 제한이 필요하거나 할때 재정의해서 사용할 수 가 있게 되죠. 그때 모든 코드들을 찾아다니며 변경할 필요가 없게 됩니다. 하지만 플랫폼에 따라 몇몇 프레임워크는 get,set 메소드를 꼭 필요로 하는 경우가 있기때문에 이를 위해 스칼라는 @scala.reflect.BeanProperty 애노테이션을 제공합니다.
필드에 이 애노데이션을 추가하면, 컴파일러가 자동으로 get,set 메소드를 만들어 줍니다. 예를 들어 crazy 필드를 애노테이션하면, 자바처럼 get메소드는 getCrazy가, set 메소드는 setCrazy 가 됩니다.
'Scala' 카테고리의 다른 글
스칼라 강좌 (17) - case class (0) | 2016.08.06 |
---|---|
스칼라 강좌 (16) - Enumerations (열거) (0) | 2016.08.06 |
스칼라 강좌 (14) - 함수 와 메소드 (0) | 2016.07.23 |
스칼라 강좌 (13) - 클래스와 객체 (0) | 2016.07.16 |
스칼라 강좌 (12) - 객체의 동일성 (0) | 2016.07.08 |