OOP 원칙 및 방법 이름


22
class Boxer:

    def punch(self, punching_bag, strength):
        punching_bag.punch(strength)


class PunchingBag:

    def punch(self, strength):
        print "Punching bag punched with strength", strength

boxer = Boxer()
punching_bag = PunchingBag()

boxer.punch(punching_bag, 2)

의심 할 여지없이 그것은 punch권투 선수의 경우 좋은 방법 이름입니다. 그러나 이름 punch은 펀치 백 방법에도 좋습니다? 두 경우 모두 펀치를 명령으로 의미합니다 (예 : 펀치).

답변:


23

경험상 가장 좋은 방법은 메소드 이름이 동사 또는 술어 여야한다는 것입니다. 따라서 호출하는 객체 ( self표준 파이썬 규칙에서는 this대부분의 다른 언어)가 주제가됩니다.

이 규칙에 file.close따르면 파일 자체가 닫히거나 file객체가 파일 자체를 나타내지 않고 오히려 파일 핸들이나 일종의 프록시 객체 라는 정신 모델을 사용하지 않는 한 일종의 잘못 입니다.

펀치 백은 결코 구멍을 뚫지 않으므로 punchingBag.punch()어느 쪽이든 잘못되었습니다. be_punched()기술적으로 정확하지만 추악합니다. receive_punch()작동 할 수도 있습니다 handle_punch(). 자바 스크립트에서 꽤 인기있는 또 다른 방법은, 이벤트 등의 메소드 호출을 치료하는 것입니다, 그리고 그 것 때문에 규칙 '에'로 시작 이벤트 이름으로 가고있다 on_punched()on_hit(). 또는 과거 분사가 수동 음성을 나타내는 규칙을 채택 할 수 있으며, 해당 규칙에 따라 분석법 이름은 그냥 punched()됩니다.

고려해야 할 또 다른 측면은 펀칭 백이 실제로 어떤 타격을 입 었는지 알고 있는지 여부입니다. 펀칭 백, 스틱으로 때리거나 트럭으로 달려 나갈 때 차이가 있습니까? 그렇다면 차이점은 무엇입니까? 그 차이를 논증에 비유 할 수 있습니까? 아니면 다양한 종류의 처벌에 대해 다른 방법이 필요합니까? 제네릭 매개 변수를 사용하는 단일 메서드는 차분 커플 링을 낮게 유지하기 때문에 가장 우아한 솔루션 일 것입니다. 이러한 메서드는 punched()또는 호출하지 handle_punch()말고 오히려보다 일반적인 것이 어야합니다 receive_hit(). 이러한 방법을 사용하면 펀칭 백 자체를 변경하지 않고도 펀칭 백을 칠 수있는 모든 종류의 액터를 구현할 수 있습니다.


4
@Artur : 예, 아니오. 파일은 (개념적으로 말하면) 요청 될 때 스스로 닫힐 수 있습니다. 배열은 스스로 정렬 할 수 있습니다. 펀치 백은 스스로 펀치하지 않습니다.
tdammers

2
펀칭 백이 미친 듯이 빠른 속도로 벽에 부딪히면 벽에 구멍이 뚫린 벽일까요, 아니면 천공 주머니 자체와 실제로 자체적으로 충돌이 발생 했습니까?

1
@tdammers : 일반화 제안은이라는 인터페이스로 이어질 수도 있습니다 Hitable.
Jens Piegsa

2
@Artur : 나는 이것이 모든 문장이 자연스러운 주제를 가지고 있고이 아이디어가 프로그래밍에 적용될 수 있다고 OOP 가정이 분해되는 곳이라고 생각합니다.
tdammers

1
따라서 주요 질문입니다. 파일이 닫힐 수 있고 배열이 스스로 정렬 될 수있는 경우 펀치 백이 펀치 할 수없는 이유는 무엇입니까? 실제 차이점이 있습니까? 아니면 첫 번째 경우에는 익숙하지만 두 번째 경우에는 그렇지 않습니까?
clime

6

나는 그것이 개념적 문제라고 생각합니다 (세계에 대한 우리의 생각). 말하기는 괜찮습니다.

  • 문이 닫힙니다. door.close()
  • 와우, 종이는 저절로 접 힙니다. paper.fold()
  • 도대체?! 책상 위의 파일이 막 닫혔습니다. file.close()

다음과 같이 말하면 이상합니다.

  • 체육관에서 펀칭 백이 막 뚫 렸습니다. bag.punch()

처음부터 펀치 할 무언가가 있어야합니다 (예 : 팔). 당신은 아마 말할 것입니다 :

  • 펀치 백은 누군가가 펀치했을 때처럼 스스로 움직이기 시작했습니다. punching_bag.move()

프로그래밍 방식의 객체가 다른 사람들이 일반적으로 "실제로"하는 일을하는 것은 괜찮습니다. 그러나 나는 그 일이 그 자체로 또는 그 일을하고 있다는 것이 항상 의미가 있어야한다고 생각합니다 . 모호하지 않고 쉽게 상상할 수 있어야합니다 (의 경우처럼 punching_bag).


2

맛의 문제라고 생각합니다. Punching bagpunch()방법은 적어도 그 자체로 행동을 경험하는 것과 일치 file.close()하거나 frame.move()의미가 있습니다. 큰 질문은 다음, 왜 것이 Boxer있습니까 punch(something)전혀 방법을?


file.close ()에 대한 요점이 마음에 듭니다. 그것은 내가 겪고 있던 일이었습니다. 권투 선수를 훈련시키는 코치도 있기 때문에 권투 선수는 펀치 방법을 가지고 있습니다. 사실, 나는 단지 하나의 행동 (메시지)이 여러 객체를 통해 전달되는 예를 보여 주려고 노력했습니다. list.append (4), account.deposit (50), file.close (), paper.fold () vs boxer.punch (), dog.bark (), logger.log () 등에 약간의 문제가 있습니다. .
지방

여러 객체를 통과 할 때 바운드 컨텍스트 (자체)를 사용하고 그렇지 않은 두 가지 경우가 있습니다. 당신이 할 경우, 당신의 방법이 있어야한다 Coach.sayPunchToBoxer(), Boxer.punchNearestBag()Bag.punch(). 그렇지 않으면 전화 할 때마다 어떤 일이 일어날 지 추측해야합니다 Coach.punch(). 일반적인 규칙은 조치를 경험하는 오브젝트가 메소드 이름에 지정되지 않은 경우 수신자가 해당 오브젝트입니다.

글쎄, 나는 이것도 괜찮다고 생각한다 : coach.say_punch (boxer, punching_bag), boxer.punch (punching_bag). 즉, 수신자는 메소드 이름이 아니라 매개 변수에 있습니다.
clime

1
물론, 액션 리시버는 호출 문에서 추측 할 수 있어야합니다.

2

두 개의 서로 다른 메시지가 있습니다. 하나는 물체에 펀치를 명령하고 다른 하나는 물체에 구멍을 뚫었 음을 알려줍니다. Boxer 객체는 두 가지 모두 에 응답해야 할 것 입니다. 다르게 . 그것은 그들에게 다른 이름을 부여하는 정말 좋은 이유입니다.

내 성향은 punch(boxer, object, strength)반대 방법을 로 유지 하고 이름을 바꾸는 것 punched입니다. 당신은 그것을 handle_punch또는 그와 비슷한 것으로 부를 수는 있지만 펀치 명령을 처리할지 또는 그것이 펀치되었다는 알림을 처리할지 여부는 여전히 모호합니다.


펀치와 handle_punch와 같은 것을 필요로하는 Boxer에 대한 좋은 점 ( defend이 특별한 경우에 해당). 그러나 샌드백은 결코 양방향 적이 지 않을 것입니다. 그리고 이미이 파일이 있습니다 .close () ...
clime

defend명령입니다. 객체가에 대한 응답으로 취할 수있는 한 가지 가능한 조치 punched이지만 다른 객체가 defend직접 호출 되는 것을 원하지 않습니다 .
user2313838 2014 년

2

당신의 접근법은 결국 매우 결합 된 코드로 이어질 것입니다.

Eric Lippert를 이상적으로 요약 하면 복서가 많은 것을 펀치 할 수 있기를 바랍니다. 복서 기능의 서명으로 펀치 백을 갖는 것은 복서가 All (즉 펀치 가능)에 대한 즉각적인 지식으로 생성되었음을 의미합니다. 또한 펀치를주고 펀치를받는 것은 매우 다른 두 가지이므로 동일한 이름을 공유해서는 안됩니다.

오히려 펀치 (펀치의 속성 힘, 범위, 방향 등을 포함하는 다른 객체)를 만드는 Boxer로 모델링하고 싶습니다.

그런 다음이 펀치 객체를받는 onPunch와 같은 방법으로 펀치 백을 가지고 펀치 자체에 미치는 영향을 계산할 수 있습니다.

이것을 명심하면 사물의 이름이 중요합니다. 상황에 맞는 정신 모델에 맞아야합니다. 첫눈에 이해가되지 않는 일이 발생하는 방법을 설명하려고 노력하거나, 이름을 딴 데 어려움을 겪는다면, 모델이 잘못되어 변경해야 할 수도 있습니다.

시작한 후에는 모델을 변경하기가 어렵습니다. 사람들은 일반적으로 모델에 맞게 현실을 구부리는 경향이 있습니다. 이것의 문제점은 당신이 만들고있는 세상 (물건을 펀칭 할 수있는 펀칭 백과 같은)을 구부릴수록 점점 더 복잡해지고 상호 작용이 점점 더 어려워진다는 것입니다. 결국 가장 사소한 것을 추가해도 변화와 버그의 악몽이되는 시점에 도달하게됩니다. 이 개념적 기술 부채는 초기 비용이 당시 가장 저렴한 것으로 인식 되더라도 매우 가파른 가격을 가질 수 있습니다.


1

이것이 제가 "개체 / 제목"혼란이라고 부르는 문제이며 매우 널리 퍼져 있습니다.

문장은 일반적으로이 주제 않는 동사를 자신의 목표에 개체를 .

이제 프로그래밍과 관련하여 실제로하는 것은 컴퓨터뿐입니다. 또는 사실상 프로세스, 스레드 또는 섬유. 객체는 기본적으로 애니메이션되지 않습니다. 그들은 자체 스레드를 실행하지 않으므로 실제로 아무것도 할 수 없습니다.

이것은 방법이 그들에게 작용한다는 것을 의미하며, 행동을하는 사람이 아니라 행동의 목표입니다. 그래서 우리는 그것들을 "대상"이 아닌 "대상"이라고 부릅니다!

File.close파일이 닫히지 않는다고 말하면 파일을 닫는 현재 실행중인 스레드입니다. 이라고 말하면 Array.sort현재 실행중인 스레드가 배열을 정렬합니다. 라고 HttpServer.sendRequest하면 현재 실행중인 스레드가 요청을 서버로 보냅니다 (그 반대도 아닙니다). 마찬가지로 PunchingBag.punch현재 진행중인 스레드가 백을 펀칭한다는 의미입니다.

이것은 Boxer펀치를 할 수있게하려면 Thread스레드 기능에서 백을 펀칭하는 것과 같은 일을 할 수 있도록 서브 클래스 여야합니다 .

그러나 때로는 각 객체에 자체 스레드가있는 경우 펀치 백 펀치 자체를 말하는 것이 합리적입니다. 경쟁 조건을 피하고 메시지 전달로 메소드 호출을 구현할 수 있습니다. punch메시지 를 보내서 백을 펀치하면 스레드 펀치입니다. 그런 다음 메시지를 다시 보내지 punch successful만 이는 구현 세부 사항 일뿐입니다.


0

필자는 "펀치"가 Boxer 클래스에 좋은 메소드 이름이라는 데 동의합니다. 다른 오브젝트에 대해 재사용 할 수 있기 때문입니다. 또한 클래스의 객체가 다른 객체에 대해 작업을 수행하고 있음을 정확하게 설명합니다. 그러나 관계를보다 명확하게 보여주기 위해 메서드 이름을 "doPunch"로 바꿉니다.

그러나 PunchingBag 클래스의 경우 메소드 이름이 너무 모호하거나 메소드에서 발생하는 일이 약간 부정확하다는 것을 알았습니다. "펀치"를 볼 때 무언가가 다른 것을 펀칭하고 있다고 생각합니다. 그러나 여기서 PunchingBag 객체는 객체 (이 경우 Boxer 객체)의 펀치에 반응합니다. 따라서 객체가 펀치에 반응하고 있음을 나타 내기 위해 여기에서 메소드 이름을 "isPunched"로 바꿉니다.

그러나 이것이 내가 방법의 이름을 지정하는 방법에 대한 나의 해석입니다. 그것은 모두 맛의 문제이며 어떤 표준을 따르고 있습니까?


3
isPunched프레임 워크 명명 체계에 따라 다소 오해의 소지가 있습니다.

메소드가 호출되는 해당 오브젝트에 적용되는 것이 일반적입니다. 무엇이 잘못 되었나요 punch()?

글쎄, 나는 행동 방향을 지정해야한다는 것을 완전히 이해하고 있지만 OOP와 그 철학에 대해 뭔가 불필요하다고 생각합니다. 객체들이 서로에게 "메시지를 보낸다"는 유명한 설명과 관련된 일종의 추상화.
clime

메소드 이름에서 메소드가 무엇을하고 있는지 명확하지 않으면 이름에 문제가있는 것입니다. OO 나 어떤 패러다임에도 문제가되지 않습니다. 그렇기 때문에 펀치 백의 punch ()가 사용하려는 컨텍스트에 관계없이 잘못되었습니다. 펀칭 백에 펀치를 말할 때 그것은 무엇을 의미합니까? 또한 어떤 가정이 모호성을 유발하는 상황에서는 무언가가 불필요하다고 철학에 의해 가정 할 수없는 이유이기도합니다. 경험치 규칙이 작동하는 상황과 그렇지 않은 상황이 있습니다. 경험 법칙이 항상 효과가 있었다면 규칙이라고 부릅니다 ( "엄지 손가락없이").
Dunk

-2

흠. 펀치 백에 대해 신경 쓰지 않기 때문에 펀치 백에 대해 의문을 제기하고 있습니다. 따라서 방법은 펀치의 영향을 측정하고보고하는 것에 관한 것이어야합니다. 이것이 '펀칭 백'에서 나오는 경우에도, 네이밍은 punchImpactMeter 등과 같은 책임을 밝혀야합니다.


-3

권투 선수는 샌드백 펀치-> boxer.punch

펀치 백은 권투 선수에 의해 펀치됩니다-> punchingbag.get_punch


3
이것은 이전의 6 가지 답변에서 언급되고 설명 된 내용에 비해 실질적인 내용을 제공하지 않는 것 같습니다
gnat
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.