쓰기 전용 속성, 요점이 무엇입니까?
이 질문에 이미 답변이 있습니다.
다음 구문을 사용하여 읽기 전용 속성을 사용하려는 이유를 이해합니다.
private int _MyInt;
public int MyInt
{
get { return _MyInt; }
}
이 예제는 아마도 읽기 전용 속성이 readonly
변수 와 함께 빛을 발한다고 생각하기 때문에 최선의 방법이 아닐 것입니다 . 내가 이해하지 못하는 것은 다음 구문을 사용하여 쓰기 전용 속성을 사용하는 이유입니다.
private int _MyInt;
public int MyInt
{
set { _MyInt = value; }
}
이것은 다양한 책과 튜토리얼에서 읽기 전용 속성이 설명되는 방식입니다. 변수를 설정하면 개념적으로 는 적어도 클래스 내부적으로는 어느 시점에서 읽을 수 있지만 클래스 내에서도 내부적으로 읽으려면 _MyInt
속성이 적용하려는 캡슐화의 정신을 위반한다고 생각 되는 액세스 를 통해 그렇게 할 것입니다. . 대신 다른 액세스 권한을 가진 속성의 전체 기능을 사용하여 다음과 같이 액세스하는 수정 사항을 사용하지 않는 이유는 무엇입니까?
private int _MyInt;
public int MyInt
{
set { _MyInt = value; }
private get { return _MyInt; }
}
물론 그냥 쓸 수있는
public int MyInt { set; private get; }
여전히 캡슐화를 얻지 만 액세스에서 다른 클래스를 제한하므로 여전히 외부 클래스에 대한 쓰기 전용입니다.
정직하게 변수에 할당하고 싶지만 실제로는 액세스하지 않는 경우가 아니라면,이 경우 언제 이러한 필요성이 발생하는지 확실히 궁금 할 것입니다.
쓰기 전용 속성에 대한 유효한 사용 사례를 본 적이 없습니다. 솔직히, 쓰기 전용 속성에 대한 유효한 사용 사례가 있다면 솔루션이 잘못 설계되었다고 말하는 것이 안전하다고 생각합니다.
"쓰기 전용"의미 체계가 필요한 경우 메서드를 사용해야합니다. 예를 들어, 다른 사용자가 쓰기 전용 속성을 사용하여 암호를 설정하는 사용자 개체의 예를 찾았습니다. 이것은 잘못된 디자인입니다.
class User
{
public string Password
{
set { /* password encryption here */ }
}
}
으. 이것은 훨씬 낫습니다.
class User
{
public void SetPassword(string password)
{
/* password encryption here */
}
}
읽기 / 쓰기 속성은 필드로 가장하도록 설계된 메서드 집합입니다. 그들은 마치 들판처럼 보이고 느껴집니다. 읽기 전용 속성은 우리가 읽을 수는 있지만 변경할 수없는 필드와 변수를 갖는 데 익숙하기 때문에 의미가 있습니다. 그러나 쓰기 가능하지만 읽을 수없는 해당 필드 또는 변수 구성이 없습니다.
이것이 쓰기 전용 속성을 사용하는 API를 만드는 것이 나쁜 습관이라고 생각하는 이유입니다. C #에서 속성 구문의 주요 목표라고 생각하는 것에 반 직관적으로 실행됩니다.
편집 : 더 많은 철학 ... 저는 클래스가 기능적 목적을 제공한다고 믿습니다. 클래스는 관련 데이터를 보유하고 조작 할 수있는 컨테이너를 제공합니다. User
예를 들어 우리의 수업을 봅시다. 이 수업은 시스템의 사용자와 관련된 모든 정보를 담고 있습니다. 우리는 이러한 모든 데이터를 수집하고 하나의 이름 인 user를 부여합니다 . 이런 식으로 클래스를 사용하여 추상화 를 만듭니다 . User
사용자를 구성하는 모든 개별 데이터 (암호, 이름, 생일 등)에 대해 추론 할 수있는 추상화입니다.
이제 좋은 추상화가 있고 나쁜 추상화가 있습니다. 누군가가 데이터를 입력하고 읽지 못하도록 허용하기 때문에 쓰기 전용 속성은 잘못된 추상화 라고 생각 합니다. 왜 이것을 허용하지 않습니까? 전달 된 정보가 어떤 방식 으로든 변형되어 통행인이 읽을 수 없기 때문일 가능성이 높습니다.
따라서 이것은 정의에 따라 쓰기 전용 속성 이 호출자가 볼 수없는 부작용을 생성해야 함 을 의미 합니다 (그들이 볼 수 있다면 속성을 쓰기 전용으로 만들 이유가 없기 때문입니다). 부작용이있는 값을 설정하기위한 C # 언어에서 가장 좋은 구문은 method 입니다.
API 소비자가 혼란스럽고 실망 스럽기 때문에 쓰기 전용 속성을 사용하지 않는 것이 좋습니다. 이 구문에 대한 유효한 사용 사례를 찾았더라도 그 사용을 정당화하지 않습니다.
편집 : 다음은 클래스 라이브러리 개발을위한 .Net Framework 디자인 가이드 라인 -> 멤버 디자인 가이드 라인 -> 속성 디자인의 공식 권장 사항입니다.
설정 전용 속성을 제공하지 마십시오.
속성 getter를 제공 할 수없는 경우 대신 메서드를 사용하여 기능을 구현합니다. 메서드 이름은 Set로 시작하고 그 뒤에 속성 이름이되어야합니다.
흥미로운 질문입니다.
인터넷 검색 후 이것이 내가 찾을 수있는 전부입니다. 쓰기 전용 속성을 사용하여 User
개체 에 대한 암호를 설정할 수 있습니다 . 암호는 일반적으로 해시 된 형식으로 저장되기 때문에 암호를 설정 한 후에는 검색 할 수있는 방법이 없습니다.
쓰기 전용 속성의 한 가지 용도는 setter 종속성 주입을 지원하는 것입니다.
수업이 있다고 가정 해 보겠습니다.
public class WhizbangService {
public WhizbangProvider Provider { set; private get; }
}
WhizbangProvider는 외부 세계에서 액세스 할 수 없습니다. 과 상호 작용하고 싶지는 않습니다 service.Provider
. 너무 복잡합니다. Facade 역할을하려면 WhizbangService와 같은 클래스가 필요합니다. 그러나 setter를 사용하면 다음과 같이 할 수 있습니다.
service.Provider = new FireworksShow();
service.Start();
그리고 서비스는 불꽃 놀이를 시작합니다. 아니면 물과 빛의 쇼를보고 싶을 수도 있습니다.
service.Stop();
service.Provider = new FountainDisplay(new StringOfLights(), 20, UnitOfTime.Seconds);
service.Start();
등등....
A common case I can see is if you only wanted a caller to be able to obtain a transformed version of your property. For example:
public int MyInt { set; }
public string MyIntAsString
{
get { return this.MyInt.ToString(); }
}
Obviously, this isn't a real example, but you get the picture.
EDIT:
After reading Thomas' example use case, then a real "transformation" type scenario could be to retrieve an encrypted version of the write-only property:
private string password;
public string ClearPassword { set { this.password = value; }
public string EncryptedPassword
{
get { return Encrypt(password); }
}
Sources I've read have suggested that if you honestly have a situation where you just created a write-only property, you should probably consider turning it into a method. And I typically agree.
Any information that must flow one way is useful through a write-only property. Generally we write classes for information to flow out of or in and out. In the case of write-only you have to think of situations where information should only flow in and not out. Usually this involves security type of information because we don't want a consumer to have any access in retrieving a secure piece of information. Passwords, CC numbers, etc...
When the information is not secure, e.g., when we don't mind anyone accessing it then we get the common get/set pattern. 99.9% of the time this is how properties are used. Since there are other ways, just as easy that can be more robust to achieve this, this is more of a semantic construct that was left in for symmetry than anything. One of the rare cases where something wasn't taken out and your left with "Why the heck did they remove that!".
The reason I can think of off the top of my head is because _myInt shows up at the top of the intellisense context menu.
I don't think accessing _myInt violates the spirit of encapsulation at all; it's a private member field of a class. Any code within the class SHOULD use the _myInt. It's private, after all.
The only thing that matters to the outside world is the public contract of the class. _myInt is a concern of the class itself, not part of the public facing contract.
And like I said - it's easier to grab _myInt with intellisense when you're coding.
I'm sure the feature is there simply for symetry with a get-only variable. As Aphex sort of vaguely implies, some things have no point and are only there because it's easier to leave it in than to remove it.
I have had cause for a write-only property.
In a .NET web-service, I have had to create a legacy ASMX web-service, as the URI is hard coded in hardware.
I'm a big fan of using Ninject for dependency injection, using constructor injection to satisfy all dependencies a class may have. For the most part, these dependencies would be declared private readonly fieldName
and assigned to in the constructor. The reason for this is that the dependencies of the class are not part of the class' responsibilities; they are dependencies.
However, the problem is whatever factory mechanism ASP.NET uses to create the class instance for a web-service relies on there being a constructor with no arguments, that scuppered my constructor injection.
I could have used a call from the default constructor to re-direct to an overloaded constructor making use of a ServiceLocator (anti)pattern, but I didn't fancy that.
Using the Ninject web extension, I inherited my service class from Ninject.Web.WebServiceBase
and employed property injection, marking the properties that Ninject would satisfy with an [Inject]
attribute.
Getting back to the point about injected services being dependencies for the class, rather than responsibilities that the type has, I don't want these dependencies properties accessed by other classes, so I mark the get property as private.
ReferenceURL : https://stackoverflow.com/questions/4695551/write-only-properties-whats-the-point
'programing' 카테고리의 다른 글
JS / jQuery를 사용하여 브라우저에서 터치 스타트 지원을 확인하는 방법은 무엇입니까? (0) | 2021.01.19 |
---|---|
구조체를 초기화하는 방법? (0) | 2021.01.19 |
JavaScript 파일 또는 REPL에서 CoffeeScript 파일을 require () 'ing (0) | 2021.01.19 |
검사 스타일 : "숨겨진 필드"오류 해결 방법 (0) | 2021.01.19 |
gcc가 함수를 인라인하도록 어떻게 강제합니까? (0) | 2021.01.19 |