균일접근원리
Uniform access principle컴퓨터 프로그래밍의 통일된 접근 원리는 베르트랑 마이어(원래는 객체 지향 소프트웨어 건설)에 의해 제시되었다.그것은 "모듈이 제공하는 모든 서비스는 저장 또는 연산을 통해 구현되는지 여부를 배반하지 않는 통일된 표기법을 통해 이용 가능해야 한다"[1]고 명시하고 있다.이 원칙은 일반적으로 객체 지향 프로그래밍 언어의 구문에 적용된다.더 간단한 형태로, 그것은 어떤 물체의 속성, 사전 계산된 속성 또는 메서드/쿼리 간에 구문론적 차이가 없어야 한다고 명시한다.
대부분의 예시가 원칙의 "읽기" 측면(즉, 값을 검색하는 것)에 초점을 맞추고 있지만, 마이어는 원칙의 "쓰기" 의미(즉, 값을 수정하는 것)가 에펠 프로그래밍 언어 공식 웹사이트의 월간 칼럼에서 다루기 더 어렵다는 것을 보여준다.[2]
설명
마이어가 다루고 있는 문제는 대형 소프트웨어 프로젝트나 소프트웨어 라이브러리의 유지보수를 포함한다.때로는 소프트웨어를 개발하거나 유지할 때, 많은 코드가 배치된 후에 단순히 속성 액세스였던 것을 메서드 호출로 변환하는 방식으로 클래스나 객체를 변경할 필요가 있다.프로그래밍 언어는 속성 액세스 및 메서드 호출에 대해 다른 구문을 사용하는 경우가 많다(예:object.something
대object.something()
구문 변경은 당대의 인기 프로그래밍 언어에서 속성이 사용된 모든 장소에서 소스 코드를 변경해야 한다.이를 위해서는 매우 많은 양의 소스 코드 전체에 걸쳐 다양한 위치에서 소스 코드를 변경해야 할 수 있다.더 나쁜 것은, 수백 명의 고객이 사용하는 객체 라이브러리에 변경 사항이 있는 경우, 각 고객은 자신의 코드에서 속성이 사용된 모든 장소를 찾아서 변경하고 프로그램을 다시 컴파일해야 한다는 것이다.
역방향(방법에서 단순속성으로)으로 가는 것은 실제로 문제가 되지 않았다. 왜냐하면 사람은 항상 기능을 유지하고 그것이 단순히 속성 값을 반환하게 할 수 있기 때문이다.
Meyer는 객체 속성을 메서드 호출로 변환하거나 그 반대로 변환하는 변경으로 인해 발생하는 코드의 계단식 변경을 최소화하거나 제거하는 방식으로 소프트웨어 개발자가 코드를 작성할 필요성을 인식했다.이를 위해 그는 통일 접근 원칙을 개발했다.
많은 프로그래밍 언어는 UAP를 엄격하게 지원하지 않고 UAP의 형식을 지원한다.여러 프로그래밍 언어로 제공되는 속성들은 마이어가 UAP와 다른 방식으로 해결하고 있던 문제를 해결한다.단일 통일 표기법을 제공하는 대신에, 속성은 속성 접근에 사용되는 것과 동일한 표기법을 사용하면서 개체의 메소드를 호출하는 방법을 제공한다.별도의 메서드 호출 구문은 여전히 사용할 수 있다.
UAP 예제
만약 언어가 메서드 호출 구문을 사용한다면 이와 같은 것으로 보일 수 있다.
// 인쇄에 전달된 변수가 있다고 가정하고 // Foo의 속성 'bar'를 값 5로 설정하십시오.Foo.bar(5) print Foo.barprograde Foo.bar
실행 시 다음을 표시해야 한다.
5
유무Foo.bar(5)
함수를 호출하거나 단순히 호출자에게 속성이 숨겨지도록 설정한다.마찬가지로Foo.bar()
단순히 속성의 값을 검색하거나 함수를 호출하여 반환된 값을 계산하는 것은 발신자로부터 숨겨진 구현 세부사항이다.
언어가 속성 구문을 사용하는 경우 구문은 다음과 같이 보일 수 있다.
Foo.bar = 5 print Foo.bar
다시 말하지만, 메서드가 호출되는지, 아니면 단순히 속성에 값을 할당하는지 여부는 호출 메서드에서 가려진다.
문제
그러나, 반환된 값이 계산에 비싸거나 캐시 운용을 유발하는 경우와 같이 액세스 방법의 차이를 무시할 수 없는 장소에서 사용할 경우 UAP 자체는 문제를 초래할 수 있다.[1]
언어 예제
루비
다음 사항을 고려하십시오.
y = 달걀.새로운("녹색") y.색을 칠하다 = "흰색" 놓다 y.색을 칠하다
이제 알류 클래스는 다음과 같이 정의될 수 있다.
계급 달걀 attr_accessor :색깔 반항하다 초기화하다(색을 칠하다) @color = 색을 칠하다 종지부를 찍다 종지부를 찍다
위의 초기 코드 세그먼트는 알이 그렇게 정의될 때 잘 작동할 것이다.알류 클래스는 또한 아래와 같이 정의될 수 있으며, 여기서 색은 그 대신 하나의 방법이다.에그(Egg)를 다음과 같이 정의한다면 호출 코드는 변경되지 않고 계속 작동될 것이다.
계급 달걀 반항하다 초기화하다(색을 칠하다) @rgb_color = to_rgb(색을 칠하다) 종지부를 찍다 반항하다 색을 칠하다 to_color_name(@rgb_color) 종지부를 찍다 반항하다 색을 칠하다(색을 칠하다) @rgb_color = to_rgb(색을 칠하다) 종지부를 찍다 사유의 반항하다 to_rgb(color_name) ..... 종지부를 찍다 반항하다 to_color_name(색을 칠하다) .... 종지부를 찍다 종지부를 찍다
다음에도 불구하고 어떻게 해야 하는지 주의하십시오.color
한 경우에는 속성처럼 보이고 다음 경우에는 한 쌍의 메서드처럼 보이지만, 클래스에 대한 인터페이스는 그대로 유지된다.에그 클래스를 유지하는 사람은 발신자 코드를 어길 염려 없이 한 형태에서 다른 형태로 전환할 수 있다.루비는 개정된 UAP를 따른다.attr_accessor :color
단지 접속자/설정자 방법을 생성하는 통사설 설탕의 역할을 한다.color
. 루비에서는 어떤 물체에서 인스턴스(instance) 변수를 메서드를 호출하지 않고 검색할 방법이 없다.
엄밀히 말하면 루비는 속성에 접근하는 구문이 메이어의 원래 UAP를 따르지 않는다.그러나 여기서 속성에 대한 접근은 실제로 자주 자동으로 생성되는 기능을 통해 이루어진다.그래서 본질적으로, 어떤 종류의 접근은 기능을 불러 일으키고 언어는 마이어의 수정된 균일 접근 원칙을 따른다.
파이톤
속성 액세스와 동일한 구문으로 메서드를 호출할 수 있도록 Python 속성을 사용할 수 있다.마이어의 UAP는 속성 액세스와 메서드 호출(방법 호출 구문)에 대한 단일 표기법을 가지고 있는 반면에, 속성에 대한 지원을 받는 언어는 속성과 메서드 액세스에 대한 별도의 표기법을 여전히 지원한다.속성은 속성 표기법을 사용할 수 있게 하지만 단순히 값을 검색하거나 설정하는 대신 메서드가 호출되고 있다는 사실을 숨긴다.
이와 같이 파이썬은 UAP 준수 옵션을 개인 프로그래머에게 맡긴다.빌트인@property
함수는 속성 액세스 구문에서 주어진 방법을 꾸미는 간단한 방법을 제공하므로, 메서드 호출과 속성 액세스 사이의 구문론적 차이를 추상화한다.[3]
Python에서, 우리는 code를 가지고 있다.Egg
중량 및 색상이 다음과 같은 단순한 속성으로 정의될 수 있는 객체
''' >>>> 달걀 = 달걀(4.0, "흰색") >>>> 달걀.색 = "녹색" >>>>인쇄(인쇄) 달걀(4.0, 녹색) ''' 계급 달걀: 반항하다 __init___(자아의, 중량을 재다, 색을 칠하다) -> 없음: 자아의.중량을 재다 = 중량을 재다 자아의.색을 칠하다 = 색을 칠하다 반항하다 __str___(자아의) -> 발을 동동 구르다: 돌아오다 f'{__class___.__name__}({자아의.중량을 재다},{자아의.색을 칠하다})'
또는 에그 오브젝트가 속성을 사용할 수 있으며, 대신 게터 및 세터 메서드를 호출할 수 있음
# ...(스냅)... 계급 달걀: 반항하다 __init___(자아의, 중량_oz: 둥둥 뜨다, color_name: 둥둥 뜨다) -> 없음: 자아의.중량을 재다 = 중량_oz 자아의.색을 칠하다 = color_name @property 반항하다 색을 칠하다(자아의) -> 발을 동동 구르다: ''알의 색''' 돌아오다 to_color_str(자아의._color_rgb) @color.세터 반항하다 색을 칠하다(자아의, color_name: 발을 동동 구르다) -> 없음: 자아의._color_rgb = to_rgb(color_name) @property 반항하다 중량을 재다(자아의) -> 둥둥 뜨다: ''온스 단위의 무게''' 돌아오다 자아의._weight_gram / 29.3 @weight.세터 반항하다 중량을 재다(자아의, 중량_oz: 둥둥 뜨다) -> 없음: 자아의._weight_gram = 29.3 * 중량_oz # ...(스냅)...
수입하다 웹컬러 # 클래스 에그: 반항하다 to_color_str(rgb: 웹컬러.정수RGB) -> 발을 동동 구르다: 해보다: 돌아오다 웹컬러.rgb_to_name(rgb) 빼고는 ValueError: 돌아오다 웹컬러.rgb_to_message(rgb) 반항하다 to_rgb(color_name: 발을 동동 구르다) -> 웹컬러.정수RGB: 해보다: 돌아오다 웹컬러.name_to_rgb(color_name) 빼고는 ValueError: 돌아오다 웹컬러.헥스_to_rgb(color_name) 만일 __name__ == "__main__": 수입하다 교활하게 하다 교활하게 하다.시험 기법() |
어느 쪽이든Egg
규정되어 있고, 호출 코드는 그대로 유지될 수 있다.의 구현Egg
에그 클래스를 사용하는 코드에 영향을 주지 않고 한 형태에서 다른 형태로 전환할 수 있다.UAP를 구현하는 언어도 이 속성을 가지고 있다.
C#
C# 언어는 클래스 속성을 지원하며, 클래스 속성을 정의하기 위한 수단을 제공한다.get
그리고set
멤버 변수의 연산(게터 및 설정자)속성에 접근하거나 수정하기 위한 구문은 다른 클래스 멤버 변수에 접근하는 것과 동일하지만, 실제 구현은 단순한 읽기/쓰기 액세스 또는 기능 코드로 정의할 수 있다.
공중의 계급 푸 { 사유의 끈을 매다 _이름; // 속성 공중의 인트로 크기 { 얻다; // 게터 세트; // 세터 } // 속성 공중의 끈을 매다 이름 { 얻다 { 돌아오다 _이름; } // 게터 세트 { _이름 = 가치를 매기다; } // 세터 } }
위의 예에서 classFoo
두 가지 속성을 포함하며,Size
그리고Name
. TheSize
속성은 읽고 쓸 수 있는 정수다.마찬가지로, 더Name
속성은 읽고 수정할 수 있는 문자열이지만, 그 값은 별도의 (개인) 클래스 변수에 저장된다._name
.
생략하는 방법set
속성 정의에서 작업을 수행하면 속성이 읽기 전용인 반면get
조작으로 쓰기 전용이 된다.
아래 코드와 같이 속성 사용은 UAP를 사용한다.
공중의 푸 CreateFoo(인트로 치수를 매기다, 끈을 매다 이름을 붙이다) { 시합을 하다 foo = 새로운 푸(); foo.크기 = 치수를 매기다; // 속성 설정자 foo.이름 = 이름을 붙이다; // 속성 설정자 돌아오다 foo; }
C++
C++는 UAP도 속성도 속성도 속성(색상)이 함수의 쌍(색상)이 되도록 개체가 변경될 때 속성도 속성도 없다.getA, setA).객체의 인스턴스를 사용하고 속성 값을 설정하거나 가져오는 장소(x = obj.color
또는obj.color = x
)는 반드시 기능 중 하나를 호출하도록 변경해야 한다.(x = obj.getColor()
또는obj.setColor(x)
. 템플릿과 연산자 과부하 사용으로 속성이 가능하지만 속성이 직접 지원되는 언어보다 복잡하다.이것은 C++ 프로그램의 유지관리를 복잡하게 한다.C++ 개체의 분산 라이브러리는 구성원 데이터에 대한 액세스를 제공하는 방법에 주의해야 한다.
자바스크립트
자바스크립트는 2009년부터 계산된 속성에 대한 지원을 해왔다.[4]
차세대 쉘
차세대 셸에서 객체 필드 액세스는 다음을 통해 수행된다..
다른 프로그래밍 언어와 유사한 구문.나머지 언어와 일치하는 구문은 방법을 호출하는 지름길이다. myobj.myfield
방법에 대한 요구로 해석된다..
논쟁하여myobj
그리고myfield
.
의 기본 제공 구현.
특정 개체 인스턴스의 지정된 필드 전용 메모리 위치에서 필드 값을 반환한다.의 동작을 사용자 지정하려면 다음과 같이 하십시오..
특정 유형에 대해서는 명명된 방법을 정의해야 한다..
그런 타입의
마찬가지로.=
방법이 요구되다myobj.myfield = myval
구문.
다음 예제는 의 기본 동작을 보여준다..
그리고.=
방법들
Egg F init(e:Egg, 색상:Str) { e.color = } e = 달걀("녹색") e.color = "흰색" 에코(e.color)
다음 예제는 사용자 정의 행동을 나타낸다..
그리고.=
방법들코드는 에 대한 접근자를 구현한다.color
밭을 갈다
Egg F init(e:Egg, 색상:Str) { e.rgb_color = RGBColor(color) } F .(e:Egg, 필드:Str) { guard field == 'color' e.rgb_color.name() } F .=(e:Egg, 필드:Str, 값:Str) { 가드 필드 == '컬러' e.rgb_color = RGBColor(값) } e = 에그("녹색") e.컬러 = "흰색" 에코(예.컬러)
참조
- ^ a b "The UniformAccessPrinciple". c2 wiki. Retrieved 6 August 2013.
- ^ Meyer, Bertrand. "EiffelWorld Column: Business plus pleasure". Retrieved 6 August 2013.
- ^ 공식 Python 문서, 내장 기능
- ^ w3schools.com, Javascript Accessors