2009-04-17 3 views
0

오늘 저녁 PHP에서 몇 가지 OOP를 배우고 벽돌 벽에 부딪 치는 여유 시간을 가졌습니다. 내 책 컬렉션을 추적하기 위해 작은 책 라이브러리 앱을 만들고 있는데 연습을 위해 OOP를 사용할 것이라고 생각했습니다.일부 코드를 검토하십니까?

필자는 지금까지 2 개의 주요 클래스를 포함하는 library.php라는 주 PHP 파일을 가지고 있습니다.

  1. 수준의 데이터베이스는, 그래서 (제목, 저자, 장르 정보 등 및 방법은 DB에 데이터를 삽입하기 포함)
  2. 수준의 책

(MySQL의에 데이터베이스 등을 연결) 내 질문 :

모든 수업에 하나의 파일을 사용해도 되나요?

그리고 아래 코드는 db에 책을 추가하는 프로세스 페이지입니다. 괜찮습니까? 아니면 잘못된 방향으로 가고 있습니까?

또한 클래스에서 새 메서드를 만들거나 완전히 새로운 클래스를 만들 때 어떻게 알 수 있습니까?

<?php 
    include 'library.php'; 

    // Connect to Host & DB 
    $database = new database(); 
    $database->mysqlConnect('localhost', 'root', ''); 
    $database->selectDB('books'); 

    // Retrieve Values 
    $book = new books(); 
    $book->retrieveValues(); 
?> 

덕분에, 키스

답변

8

제 의견으로는 모든 클래스에 대해 파일을 만드는 것이 더 좋습니다. 파일의 이름은 클래스 이름을 따서 지정합니다. 나는 차드 자작 나무보다 약간 다른 표기법, 즉 Classname.class.php을 사용합니다. 클래스 자동 로딩은 좋은 기능이지만 매우 자주 사용하지는 않습니다 (동일한 유형의 클래스가 자주 추가되거나 제거되는 MVC와 같은 특정 상황에서만).

개체 모델링 : 명사에 대한 클래스를 만들기 시작하십시오. 애플리케이션의 액터를 식별하십시오. 이를 수행하는 방법은 응용 프로그램이 수행해야 할 작업을 기록한 다음 명사를 스캔하고 그 후에 클래스를 모델링하는 것입니다. 클래스는 단일 객체를 나타내므로 클래스 이름은 대부분 단일 시간입니다. 객체가 여러 개인 경우 ObjectCollection 또는 이와 비슷한 이름을 지정해야합니다 (예 : "BookCollection"). 내 책 수집을 추적하는 작은 책 라이브러리 응용 프로그램을 만들려면

:

그것을 시도 할 수 있습니다. 그것은 내가 소유 한 책, 장르, 저자 (들) 그리고 내가 빌려준 친구들을 추적해야합니다. 또한 모든 친구에게 전화 번호를 저장해야하므로 전화 할 수 있습니다. 모든 정보는 데이터베이스에 저장됩니다.

  1. Book :
  2. Collection
  3. 의 컬렉션을 나타냅니다 : 책 ("대부", "Cryptonomicon")
  4. Library 나타냅니다 이미 라이브러리에 포함을
  5. Genre ("Sci- ("닐 스티븐슨", "마리오 푸조")
  6. Friend ("조", "질", "잭")
  7. PhoneNumber (친구의 속성)
  8. Database (대만족)

그런 다음 계층 구조를 구축. 어떤 객체가 다른 객체를 포함하고 있으며, 그 객체 사이의 관계는 어떻게 생겼는가?

  • Library는 0, 1 이상 Book
  • Book는 정확히 하나의 Genre
  • Book 1 이상 Author
  • 나는 Book 0 또는 1로 빌려줄 수에 의해 작성 속한 포함 Friend 및 한 번에 하나만 Friend
  • FriendPhoneNumber

(데이터베이스가 어떻게 표시되는지 알려줄 것입니다.)

모든 것이 분명하지는 않습니다. 전화 번호 수업이 정말로 필요하십니까? 그것은 단지 문자열입니다. 이 경우 속성으로 지정해야합니다. 또한 친구 전화 번호간에 전화 번호가 실제로 공유되지 않습니다 (같은 친구가 함께 사는 여러 친구가 자주 바뀌면 자주 변경되지만, 현재는 다소 과장 될 수 있습니다). 명사가 스칼라 값 (문자열, 정수, 부동 소수점)으로 표현 될 수 있고 다른 값이 연결되어 있지 않으면 클래스를 만드는 것이 과잉 일 수 있습니다.

시간이 지남에 따라 애플리케이션을 확장하십시오. 전화 번호뿐만 아니라 주소도 저장하기로 결정했습니다. 주소와 전화 번호는 매우 유사한 유형의 정보이므로 거리, 도시, 우편 번호 등 다른 변수를 추가하십시오. 어떤 점에서는 Friend 클래스가 거대 해 졌기 때문에 여러 가지 속성, getters 및 setters 메서드가 있으며 그 중 일부는 함께 그룹화하기 위해 접두사가 붙어 있기 때문에 좌절하게됩니다 (Friend->addressStreet, Friend>addressPostCode 등등). 따라서 Address (전화 번호를 Friend으로 남겨둔 경우) 또는 Contact (코드를 깨끗하게 유지하기 위해)으로 옮길 수 있습니다 (아무 문제가 없지만 조심해야합니다).

클래스 계층 구조 및 개체 계층 구조는 어떻습니까? 그것들을 혼동하지 마라, 그들은 완전히 다른 물건이다! 클래스 계층 구조는 비슷한 클래스가 일부 속성을 공유하지만 다른 클래스에서는 다른 경우에 발생합니다. 따라서 공유하는 속성과 메서드로 하나의 클래스를 만들고 부모 클래스의 속성과 메서드를 상속하고 하위 클래스를 추가하여 차이점을 처리합니다.

예를 들어, 우리 도서관의 예는 무엇입니까? 솔직히 말해서, 나는 조금 말도 안되는 것을 제외하고는 아무것도 생각할 수 없다.하지만 그걸로 가자. ... Friends 및 Authors 모두 Person s! 둘 다 이름, 전화 번호 및 주소가 있습니다. 그러나 저자는 책을 쓰고 친구도하지 않기 때문에 (또한 저자는 일반적으로 책을 빌리지 않습니다.) 따라서 NameAddress -클래스를 정의 할 수 있지만 getUnreturnedBooks()Friend에 분명히 속하고 getBooksWritten()Author에 속합니다.

동일한 실행에서 AuthorFriend을 처리하지 않으므로 실제로 이해가되지 않습니다. 그러나 당신이 도서관에 저장된 모든 주소 목록을 필요로한다고 말하면, 당신의 인물을 반복하여 getAddress()으로 전화 할 수 있습니다. 솔직히 말해서, PHP도 이런 경우에 좋지 않은 예제입니다. 원하는 모든 유형을 배열에 저장하고 원하는 모든 방식으로 액세스 할 수 있지만 가능하지 않은 강력한 형식의 언어로 액세스 할 수 있기 때문입니다. Java에서는 배열에 대한 데이터 유형을 정의해야하며, 상속이 공통된 경우 다른 유형을 저장할 수도 있습니다 (단, 원래 클래스의 메소드에만 제한됨).그 계급의 부도는 충분하지.

개체 계층 구조는 단순히 어떤 개체가 다른 개체를 포함해야 하는지를 나타냅니다. library에는 book 개체가 포함되어 있습니다. book에는 author 개체가 포함되어 있습니다.

일부 추가 포인터 :

  • 시도는 설명한다. Library->retrieveValues()과 같은 이름을 사용하지 마십시오. 대신 개체를 사용하기 때문에 Library->getBooks()으로 이름을 지정하십시오.

  • 때때로 반환 할 데이터 형식 뒤에 메서드를 명명하는 것이 좋습니다. 그들이 부울을 돌려주는 것은 일반적입니다. 올바른 이름 지정 규칙은 has이거나 Friend->hasBook($book) 또는 Book->isInLibraryCurrently()과 같이 is 일 수 있습니다.

  • 특정 클래스의 모든 개체에 대해 항상 동일한 값은 클래스 상수 일 수 있습니다. 말하자면 Person이 남성이거나 여성이고 데이터베이스에 "m"또는 "f"로 저장하는 경우 클래스 상수 Person::GENDER_MALE = 'm'Person::GENDER_FEMALE = 'f'을 정의하는 것이 의미가 있으므로 "m"이 없습니다. 와 "f"는 SQL 쿼리에 흩어져 있습니다.

  • 단일 인스턴스 만 생성하는 클래스는 싱글 톤으로 모델링 할 수 있습니다. 이에 대한 좋은 예가 Database 클래스 일 수 있습니다. 한 번에 둘 이상의 트랜잭션을 열 필요가 거의 없습니다. 위키 피 디아 (http://en.wikipedia.org/wiki/Singleton_pattern)에서 싱글 톤에 대해 자세히 알아보십시오.

업데이트 : 어떤 사람들은 당신이 그 (것)들을 이런 식으로 구현하면 더 많거나 적은 "돌에 새겨진"이기 때문에 싱글 톤이, 나쁜 생각 생각합니다. 따라서 데이터베이스 클래스를 싱글 톤으로 모델링했지만 나중에 하나 이상의 데이터베이스 연결이 필요하다고 판단되면 (가능하지만 가능할 수도 있음) 문제가 발생합니다. 위험을 무릅 쓰면 싱글 톤이 편리 할 수 ​​있습니다.

+0

나는 싱글 톤에 대해 논쟁하겠습니다. "있을 법하지 않음"은 가능성이 있음을 의미하므로 그때 당신은 무엇을합니까? Singleton은 소스 코드에서 방황하는 글로벌 심볼이므로 필요에 따라 쉽게 대체 할 수 없기 때문에 안티 패턴입니다. –

+1

+1 좋은 답변과 문제 해결을 위해 시간을 투자하십시오. –

+0

필자는 PHP에서 정적 변수 레지스트리를 위해 싱글 톤을 사용했습니다. 전역 변수를 사용하고 (참조를 매개 변수로 전달하는) 방법으로 사용했습니다. – Ross

1

나는 OO 프로그래밍의 아이디어의 일부는 아마 별도의 파일로 각 클래스 업을 분할 좋을 것이다, 그래서 클래스와 로직이 분리되어 있다고 생각합니다. 클래스 또는 새 클래스에서 새 메서드를 만드는시기에 대해서는 사용하는 메서드가 해당 특정 클래스의 주 작업과 관련이 있으면 추가해야한다고 생각합니다. 루틴이나 중요한 기능을 수행 할 때만 새 클래스를 만들고 올바른 클래스에 올바른 논리를 유지하십시오.

+0

클래스와 로직이 분리되어 있습니까? 무슨 소리 야? –

3

미안 해요, 난 순간에 모든 질문을 해결하기 위해 시간이 없어 (내가 다시이 내일 아침에 올 수), 그러나 나는 빨리 첫 번째 대답 할 수

가 그것을 OK인가 모든 수업에 하나의 파일을 사용합니까?

기술적으로는 "OK"입니다. 언어에서는 사용자가이를 수행 할 수 있지만 실제로는 허용되지 않습니다. 코드 구성 개선의 이점 외에도 Autoloading Objects이라는 PHP의 멋진 기능을 사용할 수 있습니다. 당신은 예를 해당 페이지 프로그램을 수행하면 다음과 같이

, 당신은 __autoload 함수를 정의 할 수 있습니다 : 당신이 명시 적으로이 클래스 정의가 모든 파일을 포함하지 않도록이 그것을 만드는

function __autoload($class_name) 
{ 
    require_once $class_name . '.php'; 
} 

. 대신 클래스 이름과 동일한 이름의 파일에이 파일을 넣으면 자동 로딩은 필요에 따라 파일을 자동으로 포함합니다. 즉, 코드에서 "books"라는 클래스가 있음을 보여줍니다. 당신은 같은 코드의 라인을 가질 때 "books.php"라는 이름의 파일이 클래스의 정의를 저장하는 경우 :

$book = new books(); 

PHP는 자동으로 그 시점에서 books.php 포함됩니다. 이것은 매우 편리하며 각 클래스를 자체 파일로 유지하는 좋은 동기입니다.

+0

나는 __autoload를 읽을 수 없다는 것을 결코 발견하지 못했습니다. 실제로 내가 무언가를 자동로드한다고 생각했을 때 혼란의 원인이었습니다. 노골적인 표현이 더 좋습니다. –

+0

대단히 감사합니다 –

2

클래스는 함수 및 속성 모음입니다.하나의 특정 조치가 필요하면 새 기능을 작성하십시오. 수행되는 여러 작업 그룹을 가질 수있는 데이터 유형이 필요한 경우 새 클래스를 만듭니다.

그리고 MySQL을 사용하고 있기 때문에 안전하지 않은 코드를 방지하기 위해 준비된 문 (http://us2.php.net/pdo.prepared-statements)을 확인해야합니다.

추신 : 나는 "책"이 아닌 "책"이라는 이름을지었습니다. 신고 방법에 대해 생각하십시오 - new books()? 새 도서를 만들므로 new book()이 더 적절합니다.

+0

건배, 케이 피드백을 주셔서 감사합니다 –

1

이미 작성된 데이터베이스 라이브러리를 사용하는 것이 좋습니다. 프로그래밍과 특히 OOP에 관한 가장 좋은 점 중 하나는 조각을 재사용하여 다른 전체를 만들 수 있다는 것입니다. 개인적으로 나는 ADODB을 사용하여 탁월한 결과를 얻었습니다. 나는 자동 로딩과 당신을 위해 별도의 파일에 클래스를 두는 것에 동의한다. 클래스의 복사본을 여기에 게시하면 메소드 이름뿐만 아니라 클래스의 내부 동작을 더 잘 볼 수 있습니까?

관련 문제