다형성
사용 getType()
하거나 이와 비슷한 것을 사용하는 한 다형성을 사용하지 않는 것입니다.
어떤 타입인지 알아야한다는 느낌이 듭니다. 그러나 당신이 알고 싶어하면서하고 싶은 일은 실제로 수업에 푸시되어야한다는 것입니다. 그런 다음 언제해야하는지 알려 주면됩니다.
절차 코드는 정보를 얻은 다음 결정을 내립니다. 객체 지향 코드는 객체에게 작업을 수행하도록 지시합니다.
— 알렉 샤프
이 원칙은 tell, do n't ask라고 합니다. 이를 수행하면 유형과 같은 세부 사항을 전파하지 않고 해당 세부 사항에 작용하는 논리를 작성할 수 없습니다. 그렇게하면 수업이 시작됩니다. 클래스 내에서 해당 동작을 유지하는 것이 좋습니다. 따라서 클래스가 변경 될 때 변경 될 수 있습니다.
캡슐화
당신은 나에게 다른 모양이 필요하지 않다고 말할 수 있지만 나는 당신을 믿지 않으며 당신도 믿지 않아야합니다.
다음 캡슐화의 좋은 효과는 세부 사항들이에 표시 코드에 퍼져하지 않기 때문에이 새로운 유형을 쉽게 추가 할 수 있다는 것입니다 if
및 switch
논리. 새로운 유형의 코드는 모두 한 곳에 있어야합니다.
무식 충돌 감지 시스템
유형에 신경 쓰지 않고 성능이 우수하고 2D 모양으로 작동하는 충돌 감지 시스템을 설계하는 방법을 보여 드리겠습니다.
당신이 그걸 그려야한다고 가정 해보십시오. 간단 해 보입니다. 모든 서클입니다. 충돌을 이해하는 원 클래스를 만들고 싶어합니다. 문제는 1000 개의 원이 필요할 때 엇갈리는 사고 방식을 제시한다는 것입니다.
우리는 서클에 대해 생각해서는 안됩니다. 우리는 픽셀에 대해 생각해야합니다.
이 사람을 그리는 데 사용하는 것과 동일한 코드가 사용자가 언제 만지거나 클릭하는 사람을 감지하는 데 사용할 수있는 코드라고 말하면 어떻게됩니까?
여기에 각 원을 고유 한 색상으로 그렸습니다 (눈이 검은 색 외곽선을보기에 충분할 경우 무시하십시오). 즉,이 숨겨진 이미지의 모든 픽셀이 다시 그려진 것을 의미합니다. 해시 맵이 잘 처리합니다. 실제로 이런 방식으로 다형성을 할 수 있습니다.
이 이미지는 사용자에게 보여줄 필요가 없습니다. 첫 번째 코드와 동일한 코드로 작성합니다. 다른 색상으로.
사용자가 원을 클릭하면 하나의 원만 해당 색상이기 때문에 정확히 어느 원인지 알 수 있습니다.
다른 위에 원을 그리면 세트에 덤프하여 덮어 쓰려는 모든 픽셀을 빠르게 읽을 수 있습니다. 설정 포인트가 완료되면 충돌 한 모든 원을 가리키고 충돌을 알리기 위해 각 원을 한 번만 호출하면됩니다.
새로운 유형 : 사각형
이것은 모두 원으로 이루어졌지만 나는 당신에게 묻습니다 : 직사각형과 다르게 작동합니까?
감지 시스템에 원 지식이 유출되지 않았습니다. 반경, 원주 또는 중심점은 신경 쓰지 않습니다. 픽셀과 색상이 중요합니다.
이 충돌 시스템에서 개별 모양으로 밀려 야하는 유일한 부분은 고유 한 색상입니다. 그 외에는 도형이 도형을 그리는 것에 대해서만 생각할 수 있습니다. 어쨌든 그들이 잘하는 것입니다.
이제 충돌 논리를 작성할 때 어떤 하위 유형이 있는지 상관하지 않습니다. 충돌하도록 지시하고 그리는 척하는 모양에서 찾은 것을 알려줍니다. 유형을 알 필요가 없습니다. 즉, 다른 클래스에서 코드를 업데이트하지 않고도 원하는 수의 하위 유형을 추가 할 수 있습니다.
구현 선택
실제로 고유 한 색상 일 필요는 없습니다. 실제 객체 참조 일 수 있으며 간접적 인 수준을 저장합니다. 그러나이 답변에 그려지면 그다지 좋지 않을 것입니다.
이것은 하나의 구현 예입니다. 분명히 다른 사람들이 있습니다. 이것이 보여 주려는 것은 이러한 모양 하위 유형이 단일 책임을 갖도록할수록 전체 시스템이 더 잘 작동한다는 것입니다. 더 빠르고 적은 메모리 집약적 솔루션이있을 수 있지만, 만약 그들이 서브 타입에 대한 지식을 널리 퍼 뜨리게된다면 성능 향상에도 불구하고 그것들을 사용하는 것을 싫어할 것입니다. 분명히 필요하지 않으면 사용하지 않을 것입니다.
이중 파견
지금까지 double dispatch을 완전히 무시했습니다 . 할 수 있었기 때문에 그렇게했습니다. 충돌 논리가 충돌 한 두 가지 유형을 신경 쓰지 않는 한 필요하지 않습니다. 필요하지 않으면 사용하지 마십시오. 필요하다고 생각되면 최대한 오래 다루십시오. 이 자세를 YAGNI 라고 합니다 .
실제로 다른 종류의 충돌이 필요하다고 판단되면 n 모양 하위 유형에 실제로 n 2 종류의 충돌 이 필요한지 스스로에게 물어보십시오 . 지금까지 다른 모양 하위 유형을 쉽게 추가 할 수 있도록 열심히 노력했습니다. 원에 사각형이 있음을 강제로 알리는 이중 디스패치 구현 으로 망치고 싶지 않습니다.
어쨌든 얼마나 많은 충돌이 있습니까? 약간의 추측 (위험한 것)은 탄성 충돌 (탄력), 비 탄력적 (끈적임), 활력 적 (폭발적) 및 파괴적 (모략 적)을 발명합니다. 더 많을 수도 있지만 이것이 n 2 보다 작 으면 충돌을 과도하게 설계하지 않아도됩니다.
이것은 내 어뢰가 손상을 입는 무언가를 때릴 때 우주선에 부딪쳤다는 것을 알 필요가 없다는 것을 의미합니다. "하하! 5 점의 피해를 입었습니다."
피해를 입은 물건은 피해 메시지를받는 물건에 피해 메시지를 보냅니다. 이렇게하면 다른 도형에 새 도형에 대해 알리지 않고 새로운 도형을 추가 할 수 있습니다. 새로운 유형의 충돌에만 확산됩니다.
우주선은 "하하! 100 포인트 데미지를 입었다." "당신은 이제 내 선체에 붙어 있습니다". 그리고 torp는 "음, 나에 대해 잊어 버렸습니다."
어느 쪽도 각각이 무엇인지 정확히 알지 못합니다. 그들은 충돌 인터페이스를 통해 서로 대화하는 방법을 알고 있습니다.
이제 더블 디스패치 (double dispatch)를 사용하면 이것보다 더 친밀하게 제어 할 수 있지만 실제로 원 하십니까?
그렇다면 적어도 실제 모양 구현이 아닌 모양이 받아들이는 충돌의 추상화를 통해 이중 디스패치를 수행하는 것에 대해 생각하십시오. 또한 충돌 동작은 종속성으로 주입하여 해당 종속성에 위임 할 수있는 것입니다.
공연
성능은 항상 중요합니다. 그러나 이것이 항상 문제가되는 것은 아닙니다. 성능을 테스트하십시오. 추측하지 마십시오. 성능의 이름으로 다른 모든 것을 희생한다고해서 일반적으로 성능이 좋은 코드는 아닙니다.