OOP tasarım soru

8 Cevap php

PHP OOP kullanılarak nispeten yeni. Bu organizasyon ve benim kod bakımında son derece yardımcı oluyor, ama benim sınıfları tasarımı ve verimli olarak ben olabildiğince OOP kullanılarak daha iyi olsun istiyorum. Ben Dört Design Patterns kitabının Gang okudum, ama yine de biraz yardıma ihtiyacım var. Birkaç küçük uygulamalar inşa sonra, burada karşısına yayınlanmaya devam bir şey.

Diyelim ki bir okul için kayıt bilgileri izler bir uygulama inşa ediyorum diyelim.

Şu anda bu yaklaşım yolu student denilen sınıf, ve bireysel bir öğrencinin kayıtlarında CRUD için o sınıfın içinde yöntemler sahip olmaktır. Ben bir argüman olarak student_id aldı bu sınıf için bir yapıcı yöntemine sahip olacağını mantıklı görünüyor, bu yüzden bu farklı CRUD işlemleri için tüm nesnesinin içinden başvurmak olabilir.

Ben app inşa devam Ama sonra, ben birden fazla öğrenci dönmek sorguları çalıştırmak için gereken durumlara rastlamak. Örneğin, gibi bir şey, get_all_students_from_grade($grade), get_dropdown_of_all_students(), vb Bu yöntemler sadece bir öğrenci için geçerli değildir, bu yüzden benim {[yöntemler olarak onlara sahip olacağını tuhaf görünüyor (2)]} class, aklımda bir student_id ile nesne örneği beri. Açıkçası ben bu şekilde çalışması yapabilir, ama ben değilim gibi görünüyor 'yanlış yapıyorsun.' Bu yaklaşım en iyi yolu nedir?

8 Cevap

Bunun (duruma göre iş mantığı veya veri erişim,) gibi ilgili faaliyetlerden (bir etki sınıf) student sınıf ayırın:

  • student - etki alanı nesnesi sadece verileri içerir
  • student_service veya student_dao (Data Access Object) - işlemleri gerçekleştirir

Bu bazen kapsülleme kırma olarak kabul, ama bir kabul gören en iyi uygulama olduğunu.

Konuda Here's daha fazla bilgi. Bu kapsülleme kırılma daha bakış cepten açısından daha sakıncaları sağlar. Bu yüzden kabul edilebilir bir uygulama gibi görünüyor olsa da, oldukça OOP değildir.

Iki sınıfa ayırmak:

  1. öğrenci
  2. öğrenci_repository

Öğrenci sınıfı ilişkisel olarak depolanan nasıl hakkında hiçbir şey bilmiyor.

$öğrencis = öğrenci_repository.get_all_öğrencis_from_grade($grade)

Ben "en iyi" şekilde bilmek iddiasında değilim, ama farklı sorunu yaklaşım yardımcı olabilir. Bunun yerine tek bir öğrenciyi temsil etmek için bir sınıf yapma, sen sınıfı, uygulaması ve veritabanı arasında bir veri arayüzü temsil yapabiliriz.

Bu sınıf, db gelen öğrenci satır bir demet (muhtemelen bir) almak yerel bir dizide bunları önbelleğe, app önbelleğe kayıtlarına göz atmak için izin, önbelleğe alınan kayıtlar üzerinde değişiklik izin nasıl ve ne zaman bitmiş, yazmak (değişiklikleri için hesap için SQL üreterek) db değişiklikleri geri önbelleğe.

Bu şekilde, (hala yerine satır kümesi ile çalışmak) ve bireysel nesnelere aynı anda, teklif erişim (önbellek geçerli konuma bir dizin oluşturarak, izin ve her değişiklik için tek bir SQL stateement ateş önlemek bu sınıfın yöntemlerini çağırır gibi, bu "işaretçi"), uygulama tarafından ileri edilecek

Bir başlangıç ​​noktası her zaman vardır. Sizin durumda (yani okul, sınıf, vb.) Gelen öğrencileri alıyorsanız NE olacaktır.

$class = new Model_Class;

$students = $class->students;

foreach($students as $student)
{
    print $student->name. ' is in class '. $class->name;
}

Ben bu aynı problem genelinde geldim, senin kullanarak MySQL tahmin ediyorum? Bu SQL şeyi düzleştirmek için bir eğilimi vardır becuase ortak OOP tasarım zorluklardan biridir.

Ben aşağıdakileri yaparak bu çözdük

1..) Örnekleme üç formları olan bir sınıf yapmak,

Bu yeni bir

$myStudent = new $Student();

Eğer id biliyorum ama kimlikleri verilere ihtiyaç olduğu başka bir

$myStudent = new $Student($student_id);

ve zaten sahip olduğu başka bir ilişkisel dizi veri var

$data = array('id'=13,'name' => 'studentname', 'major' => 'compsci');
$myStudent = new $Student($data['id'], $data);

Bu, mysql bir sorgu çalıştırmak veri ilişkilendirilebilir bir dizi olsun ve sonra öğrencinin her örneği için veritabanı isabet olmadan bu dizi veriden öğrencinin örneklerini oluşturabilirsiniz bir fabrika sınıfını yapmanızı sağlar.

Burada böyle bir sınıf için yapıcı:

public function __construct($id=FALSE, $data=FALSE)
{
    if(!$id) $this->is_new = true;
    else if($id && !$data) $this->get_data_from_db($id);
    else if($id && $data) $this->set_data($data);

}

Sen fabrika yöntemi ile gitmek ve fabrika yeni öğrencinin kimliği ne olması gerektiğine karar olabilir.

Tabii ki bu fabrika (veritabanındaki kaç öğrenci dayalı) de endeksi başlatmak ve (bir ihtimal varsa) silinen öğrenciler hakkında ne karar olurdu nerede görmek için bir veritabanı okumak gerekir.

Eğer öğrenci sınıfta olanlar dahil etmek zorunda neden açıklanan yöntemlere gelince, ben görmüyorum. Sen ancak statik bir yöntem değil, bir üye yöntem olmalıdır olabilir.

Neil (biz bir cevap vermedi neden emin değil), muhtemelen de Course ve School sınıfları olmalıdır yaptığı açıklamada söylediği gibi. Sen, belirli bir sınıf ile bir ders School ve ders-spesifik yöntemler (tüm öğrenciler içinde (vb, eksik gün belirli bir sayıda, belirli bir sınıftaki tüm öğrenciler almak) okul özgü yöntemleri olabilir vs) Course sınıfında.

Siz standart CRUD size bir birey (yani Student class) kendisi yükleme katları sorumluluğu temsil eden bir sınıf vermek istemiyorum doğru düşünme vardır. Eğer (Ruby on istihdam nedir) veri yükleme bir ActiveRecord tarzı daha olacak olsaydı On the other hand, daha sonra would aslında yapmak bütün Student yükleyici yöntemleri statik Student sınıfının kendisi yöntemleri. Bu sadece sizin veri modeli olmaya devam ediyor ne kadar karmaşık kısmen bağlıdır ki, onu stil istiyorum nasıl bağlıdır.

Onları class methods Student yapmak gerekir.