자체 참조 메소드 체인에 대한 실제 단점이 있습니까?


14

최근에 특정 프로젝트의 특정 클래스에 대해 체인 방법을 구현하여 코드의 가독성을 향상시킬 수 있다고 제안했습니다. 나는 "편의를 위해서가 아니라 의미론을 위해 유창한 인터페이스를 구현해야한다"라는 대답을 얻었고 제 제안은 거절되었습니다. 나는 유창한 인터페이스를 제안하는 것이 아니라 가독성과 코딩 편의성을 향상시키기 위해 메서드 체인 자체 ( 서로 혼란 스러울 수 있음) 에 대답했다 .

어쨌든, 이것은 아마도 아무것도 반환하지 않는 메소드 (예 : setter)에서 항상 "this"를 반환함으로써 나쁜 습관을 겪을 수 있다고 생각하게했습니다.

내 질문은 : 이전 관습을 적용하는 것이 나쁜 습관이나 학대로 간주 될 수 있습니까?, 왜?. 성능 저하가 있다고 생각하지 않습니까?



내가 같은 클래스의 메서드 체인의 경우에 더 많은 관심으로 감사 @KeesDijk, 나는 조금이 아니 그와 비슷한에 그래서 내 질문에 편집
dukeofgaming

1
- SO에서, 그들은 체인은 C ++에 대한 아니라고, 나에게 말했다 stackoverflow.com/questions/5760551/... - 당신에 대해 어떻게 생각하십니까?
kagali-san

1
@mhambra 메소드 체인을 구현할 때 조심해야하고 명확한 표준을 정의 해야하는 것처럼 보입니다.
dukeofgaming

답변:


10

아니

켄트 벡이 지적, 코드는 훨씬 더 자주 기록보다 읽습니다.

메소드 체인으로 코드를 더 읽기 쉽게하려면 메소드 체인을 사용하십시오.


1
위대한 책 .. +1
Rein Henrichs

5
그러나 더 읽기 쉬운 체인을 찾는 유일한 방법이라면? 이것이 sytilistic 문제의 문제라면, 일관성을 위해 기존 코드와 같은 방식으로 작성하는 일련의 코딩 규칙을 고수하게 될 것입니다.
coredump

영업 이익이 이미 그렇게 말했 것처럼 그것은 소리 @coredump,하지만 난 스티븐 그냥이 말을했다 생각 하면 방법 체인이 쉽게 읽을 수 있습니다.
Panzercrisis

1
@Panzercrisis OP는 편의성 대 의미론으로 인해 메소드 체인 사용을 자제하라는 지시를 받았습니다. Steven의 대답은 기본적으로 "어쨌든 그것을"하고 팀의 의견이나 일관성을 고려하지 않고 OP 코드 자체의 가독성 만 고려합니다. OP가 코드 가독성과 관련하여 취향에 맞게 프로젝트의 모든 기존 클래스를 다시 작성하려면 어떻게해야합니까? 나는 편의 / 의미 인수를 이해하는 방법 그의는 : 메소드 체인이 할 수있는 "기술"이유가 있어야한다 (다른 사람이 그 / 그녀의 자신의 환경에 대한 변명을 만드는 것처럼 BTW, 즉 인수는 소리)
코어 덤프

9

예, 단점이 있습니다

읽기 쉬운 코드는 좋지만 코드가 통신 하는 내용도주의하십시오 . 객체의 메소드가 항상 객체를 반환하면 몇 가지 사항을 전달합니다.

  1. 어떤 순서로 설정하거나 구성해야하는지 확실하지 않은 고급 구성이 필요합니다.
  2. 각 후속 메소드 호출은 마지막에 빌드됩니다.

유효한 사용 사례 : Ad Hoc 데이터베이스 쿼리

클래스 라이브러리는 대부분의 모든 언어로 존재하므로 하드 코딩 된 SQL에 의존하지 않고 데이터베이스를 쿼리 할 수 ​​있습니다. Entity Framework for .NET을 예로 들어 보겠습니다.

DBContext db = new DBContext();
List<Post> posts = db.Posts
    .Where(post => post.Title.Contains("Test"))
    .OrderBy(post => post.DateCreated)
    .ToList();

이것은 각 후속 메소드 호출이 이전 메소드 호출을 빌드하는 유연한 인터페이스입니다. 이러한 호출을 읽는 것은 데이터베이스 쿼리 컨텍스트에서 논리적으로 의미가 있습니다.

잘못된 사용 사례 : 속성 설정을위한 구문 설탕

이제 Post클래스 와 동일한 패턴을 사용합시다 :

public class Post
{
    public string Title { get; set; }
    public DateTime DateCreated { get; set; }
    public string Body { get; set; }

    public Post SetTitle(string title)
    {
        Title = title;

        return this;
    }

    public Post SetDateCreated(DateTime created)
    {
        DateCreated = created;

        return this;
    }

    public Post SetBody(string body)
    {
        Body = body;

        return this;
    }
}

이제이 클래스를 어떻게 사용할지 봅시다 :

Post post = new Post()
    .SetTitle("Test")
    .SetDateCreated(DateTime.Now)
    .SetBody("Just a test");

이 코드가 표시되면 즉시 다음과 같은 질문을합니다. "호출 한 후 SetBody데이터베이스를 쿼리합니까? '완료되었습니다'라는 다른 방법을 호출해야합니까?"

체인 메소드 호출 은 클래스를 사용하여 코드와 통신 하는 것은 무엇입니까 Post?

  1. 복잡한 설정이 있습니다
  2. 각 메소드 호출은 이전 메소드에서 빌드됩니다.

입니다 실제로 사실? 아니요. Post수업 에 복잡한 설정 이 없습니다 . 제목, 생성 날짜 및 본문을 설정해도 더 복잡한 최종 목표를 향해 구축 되지 않습니다 . 당신은 둥근 구멍에 사각형 못을 으깬다.

자체 참조 메소드 체인의 단점은 무언가를 수행하기 위해 여러 메소드 호출이 필요하며 각 호출이 마지막에 생성된다는 것을 전달한다는 것입니다. 이것이 사실이 아닌 경우, 메소드 체인은 잘못된 것을 다른 프로그래머에게 전달할 수 있습니다.

동료가 말했을 때 :

유창한 인터페이스는 편의를 위해서가 아니라 의미를 위해 구현되어야합니다

그들은 절대적으로 정확했습니다. 유창한 인터페이스 또는 메소드 체인은 사실이 아닐 수도있는 무언가를 전달합니다.


이것은 메소드 체인과 복잡한 구성이 항상 함께 진행된다고 가정합니다. 그것들은 별개의 엔티티이며 하나의 존재가 다른 것을 가정해서는 안됩니다.
Jack

"복잡한 구성"일뿐만 아니라 "이전의 메소드 호출이 이전의 메소드 호출을 빌드합니다"입니다. 메소드 체인에는 클래스의 목적에 맞지 않는 메타 통신이 있습니다.
Greg Burghardt

1
이전 메소드 호출을 빌드하는 후속 메소드 호출도 메소드 체인과 구별되며 메소드 체인 구문을 순서 종속적 인 일련의 부작용 작업의 의미에 대한 강력한 통신으로 취급하는 것이 신뢰할 만하거나 유용하다고 생각하지 않습니다. 그것은 문법적인 속기입니다. 더 짧고 읽기 쉬운 곳에 사용하십시오.
Jack

1
난 당신이 방법 체인은 별도의 생각을 이해하지만, 나는 말하고 당신의 머리 속되지 않은 다른 클래스 라이브러리를 사용하는 다른 프로그래머 않는 사실입니다 코드에 대한 가정을 끝낼 수 있었다 이러한 이유로 메소드 체인을 구현합니다. 메소드 체인은 코드 작성자가 의도하지 않은 것을 암시 할 수 있습니다. 명확하게 의사 소통하는 코드는 읽기 쉬운 코드만큼이나 중요합니다. 다른 사람을 위해 희생하지 마십시오.
Greg Burghardt

1
When an object's methods always return the object, it communicates a couple of things-나는 이것이 개인적인 의견이라고 생각한다. 체인 방식을 보는 모든 사람이 같은 것을 가정한다고 주장하기는 어렵습니다.
Sam Dufel

1

주요 단점은 선명도의 손실입니다. 예를 들어 :

x.foo();
x.bar();
x.baz();

이 문장들 중 어느 것도 값을 반환하지 않기 때문에 (혹은 무시된다면) 부작용을 일으키는 경우에만 유용 할 수 있습니다. 다음과 대조하십시오 :

x.foo()
 .bar()
 .baz();

첫째, 클래스가 해당 메소드를 가진 유일한 클래스 라는 사실을 알지 못하면 명확하지 않으며 barbaz같은 유형의 객체에서 작동 합니다. 이 경우에도 메소드가 새 객체 에서 작동 하는지 명확하지 않습니다 .xxx

부작용이있는 코드 부분을 강조 표시하면 프로그램에 대한 추론을 위해 해당 부작용을 추적해야하므로 유용합니다. 코드 작성이 쉬워지면 잠재적 인 선명도 손실 가능성을 고려해야합니다. 또한 코드를 작성하는 것보다 더 많이 읽습니다.


0

프로그래밍 언어의 모든 문체 요소 (수동 코딩 기계 언어와 반대)를 고려하면 "편의성이 아니라 의미 론적"주장이 약화됩니다.

엔지니어로서 우리가하는 많은 일들이 시맨틱에 편리함을 제공하고 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.