[part 4] PHP로 좋은 객체 지향(OOP) 습관을 가집시다.
부제: 가장 약한 링크를 받아 들이자(느슨한 결합)
느슨하게 모듈을 연결 하는 것은 좋은 일입니다.
변경 사항을 캡슐화 할 수 있는 속성 중 하나입니다.
느슨하게 클래스를 연결하려면 클래스의 종속성을 낮추는 습관을 구축하여 최종 목적을 개발하세요.
도데체 이게 무슨 말이냐!
하나의 클래스 에서는 하나의 역할만 하는걸 말하는것 같습니다.
나쁜 습관 : 밀접한 결합
아래 예제는 주소를 출력하는 부분에 대해서 타이트하게 연결되어 있습니다.
객체의 format() 메소드 를 호출하는 아래 코드는 멋지게 보일 수 있습니다.
Address 클래스 호출을 사용하면 format() 됩니다.
반대로 다른 포맷을 적절하게 사용되는 다양한 포맷터에 대해 알아야 합니다.
특히 다른 누군가가이 format()메소드 에서 포맷터 클래스를 사용하는 데 관심이 없는 경우에는 객체를 재사용 할 수 없습니다.
사용하는 코드 Address에는 많은 종속성이 없지만 Address 클래스에는 단순한 데이터 객체만 있으면 될 수 있습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | <?php require_once "./AddressFormatters.php"; class Address { private $addressLine1; private $addressLine2; private $city; private $state; // or province... private $postalCode; private $country; public function setAddressLine1($line1) { $this->addressLine1 = $line1; } public function getCountry() { return $this->country; } public function format($type) { if ($type == "inline") { $formatter = new InlineAddressFormatter(); } else if ($type == "multiline") { $formatter = new MultilineAddressFormatter(); } else { $formatter = new NullAddressFormatter(); } return $formatter->format($this->getAddressLine1(), $this->getAddressLine2(), $this->getCity(), $this->getState(), $this->getPostalCode(), $this->getCountry()); } } $addr = new Address(); $addr->setAddressLine1("123 Any St."); $addr->setAddressLine2("Ste 200"); $addr->setCity("Anytown"); $addr->setState("AY"); $addr->setPostalCode("55555-0000"); $addr->setCountry("US"); echo($addr->format("multiline")); echo("\n"); echo($addr->format("inline")); echo("\n"); | cs |
좋은 습관 : 객체 사이의 느슨한 연결
좋은 OO 설계를 작성할 때, Separation of Concerns (SoC) 라는 개념을 생각할 필요가 있습니다.
SoC는 실제로 관심을 기울여야하는 객체를 분리하려고 시도하므로 연결을 낮추는 것을 의미합니다.
원래 Address 클래스에서는 형식을 지정하는 방법에 대해 염려해야했습니다.
그것은 아마도 좋은 디자인이 아닙니다.
오히려 어떤 Address 클래스는 Address 포맷터에 대해 생각해야하며, 어떤 형식의 포맷터는 주소를 올바르게 포맷하는 방법에 대해 걱정해야합니다.
아래 예제는 주소를 형식화 한 코드는 인터페이스, 구현 클래스 및 "인터페이스 사용" 습관을 구축
이제 AddressFormatUtils 클래스는 포맷터를 만들고 서식을 지정합니다.
다른 모든 객체 Address 는 포맷터의 정의를 요구하지 않아도 사용할 수 있습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | <?php interface AddressFormatter { public function format($addressLine1, $addressLine2, $city, $state, $postalCode, $country); } class MultiLineAddressFormatter implements AddressFormatter { public function format($addressLine1, $addressLine2, $city, $state, $postalCode, $country) { return sprintf("%s\n%s\n%s, %s %s\n%s", $addressLine1, $addressLine2, $city, $state, $postalCode, $country); } } class InlineAddressFormatter implements AddressFormatter { public function format($addressLine1, $addressLine2, $city, $state, $postalCode, $country) { return sprintf("%s %s, %s, %s %s %s", $addressLine1, $addressLine2, $city, $state, $postalCode, $country); } } class AddressFormatUtils { public static function formatAddress($type, $address) { $formatter = AddressFormatUtils::createAddressFormatter($type); return $formatter->format($address->getAddressLine1(), $address->getAddressLine2(), $address->getCity(), $address->getState(), $address->getPostalCode(), $address->getCountry()); } private static function createAddressFormatter($type) { if ($type == "inline") { $formatter = new InlineAddressFormatter(); } else if ($type == "multiline") { $formatter = new MultilineAddressFormatter(); } else { $formatter = new NullAddressFormatter(); } return $formatter; } } $addr = new Address(); $addr->setAddressLine1("123 Any St."); $addr->setAddressLine2("Ste 200"); $addr->setCity("Anytown"); $addr->setState("AY"); $addr->setPostalCode("55555-0000"); $addr->setCountry("US"); echo(AddressFormatUtils::formatAddress("multiline", $addr)); echo("\n"); echo(AddressFormatUtils::formatAddress("inline", $addr)); echo("\n"); | cs |
단점은 패턴을 사양할때마다 코드의 양이 많아 진다는것입니다.
그러나 이러한 코드의 증가는 각 클래스의 유지 관리 감소로 상쇄돼며 적절한 재사용 가능성이 확보되면 훨씬 더 줄일수 있습니다.
'소행성이야기' 카테고리의 다른 글
php 에서 다차원 배열 정열하기 (0) | 2018.07.10 |
---|---|
객체지향의 사실과 오해 를 읽고 (0) | 2018.07.09 |
엘라스틱 서치 + 키바나 설치 및 설정 (0) | 2018.07.09 |
코드이그나이터에서 JWT 사용하기 (0) | 2018.07.09 |
JWT의 구조는 어떻게 생겼을까? (1) | 2018.07.09 |