OOP'deki nesneler bir varlığı temsil etmek zorunda mı?


82

Bir nesne bir varlığı temsil etmek zorunda mı?

Bir varlık olarakProduct , yani Motor, ParkingLotvb. Gibi bir şeyi , fiziksel, hatta kesin bir fiziksel olmayan kavramsal nesneyi kastediyorum - iyi tanımlanmış, net bir şekilde nesneye ait bazı temel veriler ve bazı işlevler / yöntemler. açıkça çekirdek veriler üzerinde çalışır.

Mesela, kendimde Demonbir varlık, belki de hayali bir nesneye sahip olabilirim, ancak fiziksel değil, yine de bir varlık olabilir.

Bir nesne sadece bir yöntemler topluluğu olabilir mi, ortak bir hedefle bağlanan ortak bir prosedürler dizisi olabilir mi?

Örnek: Bir sınıf çağrılabilir MotorOperationsmi MotorActions, yoksa varlığın olmadığı yerlerde, sınıf içindeki yöntemler gibi şeyler yapar.

  • getMotorDataFromHTMLForm ()
  • getMotorManufacturers ()
  • selectMotorFromUserRequirements ($ gereksinimleri)
  • canMotorCanHandleOperatingConditions ($ koşullar)
  • computePowerConsumptionForMotor ($ id)

Bir sınıf tipik olarak, verilerdeki nesne + işlemlerinin merkezinde bulunan veriler olarak tanımlanır. Bu nedenle Motor, motor özelliklerine ilişkin bazı motor değişkenleri olabilir ve bir şey üretmek için bu verileri birleştiren işlemler olabilir.

Benim durumumda , sınıf içinden geçen data + verileri üzerinde işlem yapan bir sınıfım olması gibi , sınıf içi geçici veriler dışında, "Motor İşlemleri" için merkezli bir veri bulunmuyor.

Soru

Sınıflar varlıksız nesneleri temsil edebilir mi? Eğer değilse, neden kötü / eksik / OOP merkezli değiller? OOP ile uyumlu olması için kavramsal olarak değiştirilmesi / iyileştirilmesi gereken yollar var mı?


2
+1. Ancak "evet", bir varlığı temsil etmesi gerektiği anlamına mı gelir, yoksa varlıksız nesneleri temsil edebileceği anlamına mı gelir?
Panzercrisis

1
Aklıma gelen ilk şey: java.awt ve "Op" sınıfları (örneğin, docs.oracle.com/javase/7/docs/api/java/awt/image/… ), demek istediğin buysa. Bir işlemi temsil ediyor. Şimdi, iyi bir uygulama olup olmadığından emin değilim (garip ve çirkin görünüyor), ancak Java standart kütüphanesinde bulunuyor ve Java OOP. Çoğu kısım için.
Luke,

1
Hayır değil, ama bu iyi fikir olduğu ya MotorActionsda olmadığı anlamına gelmez MotorOperations.
immibis

1
Bu soru bir teneke kutu spesifikasyonundan faydalanabilir .
reinierpost

3
@Dennis Gerçekten de tüm yanlış soruları sorduğunuzu hissediyorum. Birincisi, OOP'un kesin bir tanımı olmadığı için, ikincisi paradigmalar yalnızca sona ermek için bir araç olduğu için. Önemli olan tek şey "bu şekilde kod yazmak, doğruluğu hakkında düşünmeyi kolaylaştırıyor mu?" ve "bu şekilde kod yazmak yeniden kullanımını kolaylaştırıyor mu?"
Doval

Yanıtlar:


109

Hayır , bir nesnenin bir varlığı temsil etmesi gerekmez.

Aslında, nesneler hakkında fiziksel varlıklar olarak düşünmeyi bıraktığınızda, OOP'nin vaat ettiği faydaları elde ettiğiniz zaman olduğunu iddia edeceğim.

Bu en iyi örnek değil, ama Kahve Makinesi tasarımı muhtemelen ışığın benim için gelmeye başladığı yer.

Nesneler mesajlarla ilgilidir. Sorumluluklar hakkında. Arabalar, Kullanıcılar veya Siparişler ile ilgili değiller.

OO'ya bu şekilde öğrettiğimizi biliyorum, ancak birkaç denemeden sonra, MVC, MVVM veya MVWhatever'i denediğinizde işlerin nereye gittiğini anlamanın ne kadar temelden sinir bozucu olduğunu görünce ortaya çıkıyor. Ya modellerin gülünç şişkinleşir ya da kontrolörlerin yapar. Gezinme özelliği için, Araçlara dokunan herhangi bir şeyin Vehicle.ext dosyasında olduğunu bilmek harika, ancak uygulamanız Araçlar hakkında olduğunda, kaçınılmaz olarak o dosyada 3000 satırlık spagetti kalıyor.

Gönderilecek yeni bir mesajınız olduğunda, en az bir tane yeni nesneniz ve belki bir çiftiniz olur. Bu nedenle, bir yöntem demeti hakkındaki sorunuzda, potansiyel olarak bir mesaj demeti hakkında konuştuğunuzu iddia ediyorum. Ve her biri kendi nesnesi olabilir, yapacak işi de vardır. Ve bu tamam. Her şeyi birbirinden ayırdığınızda, gerçekten bir arada olması gerekenler ortaya çıkacak. Ve onları bir araya getirdin. Ancak, OO'nun tadını çıkarmak istiyorsanız, kolaylık olması için her yöntemi belirsizce uygun bir çekmeceye hemen düşürmeyin.

Fonksiyon çantalarından bahsedelim

Bir nesne sadece bir yöntem koleksiyonu olabilir ve yine de OO olabilir, ancak benim "kurallarım" oldukça katı.

  1. Tahsilatın tek bir sorumluluğu olmalı ve bu sorumluluk "Motorlara iş yapar" kadar genel olamaz. Hizmet katmanı cephesi gibi bir şey yapabilirim, ancak gezinme / keşif nedenlerinden dolayı tembel olduğumun farkındayım, OO kodu yazmaya çalışıyorum.

  2. Tüm yöntemler tutarlı bir soyutlama katmanında olmalıdır. Bir yöntem Motor nesnelerini alırken, diğeri Beygir gücü döndürürse, bu muhtemelen birbirinden çok uzaktır.

  3. Nesne aynı "tür" veri üzerinde çalışmalıdır. Bu nesne motorlara bir şey yapar (başlat / durdur), bu krank uzunluğu olan şeyleri yapar, bu bir ateşleme sekansını işler, bu bir html formu alır. Bu veriler makul bir şekilde nesnenin üzerindeki alanlar olabilir ve uyumlu görünebilir.

Genelde bu tür nesneler yapıyorum; dönüşümler, kompozisyonlar yaparken ya da sadece değişkenlik konusunda endişelenmek istemiyorum.

Nesne sorumluluklarına odaklanmanın beni uyuma götürdüğünü biliyorum. Bir nesne olmak için bir miktar uyum olması gerekir, ancak bir nesne olması için herhangi bir alan veya çok fazla davranış olması gerekmez. Bu 5 motor yöntemine ihtiyaç duyan bir sistem inşa ediyor olsaydım, bunları yapan 5 farklı nesne ile başlardım. Ortak bulduğum gibi, ya bir şeyleri birleştirmeye başlar ya da ortak "yardımcı" nesneleri kullanırdım. Bu beni açık / kapalı kaygılara sürüklüyor - bu işlevsellik parçasını nasıl çıkarabilirim, böylece belirli bir dosyayı bir daha asla değiştirmek zorunda kalmayabilirim ama yine de gerektiğinde kullanabilirim?

Nesneler mesajlarla ilgilidir.

Alanlar bir nesneye zar zor gelir - kayıtları almak ve ayarlamak, program dışındaki dünyayı değiştirmez. Diğer nesnelerle işbirliği yapmak işi halleder. Bununla birlikte, OO'nun gücü soyutlamalar yaratabildiğimiz için tüm bireysel ayrıntıları bir kerede düşünmek zorunda kalmayız. Sızan veya anlam ifade etmeyen soyutlamalar problemlidir, bu yüzden zihinsel modellerimizle eşleşen nesneler yaratma konusunda derinden (çok, belki de) düşünüyoruz.

Anahtar soru: Bu iki nesnenin neden birbiriyle konuşması gerekiyor?

Nesneyi bir insandaki organ olarak düşünün - varsayılan bir amacı vardır ve yalnızca ilgilendiği belirli bir mesajı aldığında davranışını değiştirir.

Yaya geçidinde olduğunuz ve bir arabanın hızlı bir şekilde geldiği bir senaryo düşünün. Beyin nesnesi olarak bir stres etkeni tespit ediyorum. Hipotalamusa kortikotrofin salgılayan hormon göndermesini söylüyorum. Hipofiz bezi bu mesajı alır ve adrenal kortikotrofik hormonu serbest bırakır. Adrenal bezler bu mesajı alır ve adrenalin oluşturur. Kas nesnesi bu adrenalin mesajını aldığında büzülür. Kalp aynı mesajı aldığında, daha hızlı atıyor. Caddenin karşısındaki sprint yapma davranışını başlatmaya dahil olan bütün bir oyuncu zinciri var ve önemli olan mesajlar. Beyin nesnesi, hipotalamusun uyarıyı göndermesini nasıl sağlayacağını bilir, ancak sonunda davranışı gerçekleştirecek olan nesneler zincirini bilmiyor. Aynı şekilde, kalp, adrenalinin nereden geldiği hakkında hiçbir fikri yok.

Dolayısıyla bu ( basitleştirilmiş ) örnekte, böbreküstü bezi nesnesinin yalnızca ACTH'yi nasıl alacağını ve adrenalini nasıl yapacağını bilmesi gerekir. Bunu yapmak için herhangi bir alana ihtiyacı yok, ancak yine de bana bir nesne gibi görünüyor.

Şimdi eğer uygulamamız sadece caddeye sıçramak için tasarlandıysa, hipofiz bezine ve böbreküstü bez nesnelerine ihtiyacım olmayabilir. Ya da sadece kavramsal olarak "hipofiz bezi modeli" olarak görebileceklerimizin sadece küçük bir kısmını yapan hipofiz bezi nesnesine ihtiyacım var. Bu kavramların tümü kavramsal varlıklar olarak mevcuttur, ancak bu bir yazılımdır ve AdrenalineSender veya MuscleContractor'ı yapabiliriz veya ne olursa olsun, modelimizin "eksikliği" hakkında endişelenmeyin.


4
Bu cevabın asıl içeriğine katılıyorum, ancak sorunun yanlış anlaşıldığını hissediyorum. Özellikle, soru varlık "veya bir kavram, iyi tanımlanmış bir şey" içerir. Buna karşı örnekler " MotorOperationsveya MotorActions" dir. Bu, gayet eminim orijinal hem ve "bir varlık temsil" nin OP'ın tanım altında Kahve örneği düşüşün son tertip tasarımları
Ben Aaronson

1
Postmodern sistem mimarisi DCI bunu yapı seven mühendislerin yarattığı aşırı soyutlamalar olmadan gerçekleştirir. Bilgisayar gereken kullanıcı, tersi değil ne düşündüğünü düşünüyorum. fulloo.info/doku.php?id=what_is_dci
ciscoheat

@BenAaronson Bu nesneye, yeterli miktarda çaba sarf ederek uyumlu bir konsept olarak evrimleşebileceğini hissediyorum, ancak varlık odaklı bir şeyin ayrı olması gereken şeyleri birlikte zorlama eğilimi buldum. Kurumlar isimlerimizdeki sınırları teşvik eder ki bu da iyidir, ama aynı zamanda incitmeye meyilli olan bu doğruluk / eksiksizlik kavramını da beraberinde getirir. En saçma terimlerle, bir FirstNameValidator nesnesi için ve aynı zamanda ad ve soyadı için doğrulama yapan bir Name nesnesine karşıyım.
Steve Jackson,


2
Nesneler mesajlarla ilgili - Steve Jackson'ın cevabı - bu kesinlikle doğru. MOP, büyük fikrin mesajlaşma olduğunu söyleyen OO Ofisi Alan Kay tarafından tasarlanan "mesajlaşma" ile kastedilen şey değildir . Dahası, uzun zaman önce bu konu için "nesneler" terimini kullandığım için üzgünüm çünkü birçok insanın daha az fikre odaklanması gerekiyor.
radarbob

21

Sınıflar varlıksız nesneleri temsil edebilir mi? Eğer değilse, neden kötü / eksik / OOP merkezli değiller? Değiştirilmeleri / iyileştirilmeleri gereken yollar var mı?

Kısacası, her şeyi yapabilirsiniz, ancak bu özel senaryo OOP ilkelerine aykırı olabilir :)

Tarif ettiğiniz şey bazen "yarar" sınıfı olarak adlandırılır - genellikle kod kokusunun bir işareti. Bazı yöntemleri bir arada tutmak için sınıf oluşturmaktan kaçınmak istiyorsunuz.

Uygulamanızdaki her nesnenin bir motor veya araba gibi gerçek hayattaki bir varlık ile bağlantılı olması gerekmez; bunlar iş objeleri. Başvurunuzda, işletme nesnelerinizin çoğunu kullanmanız olasıdır, ancak listeledikleriniz gibi, işletme varlıklarının parçası olmayan diğer işlemler için de biraz daha ayrılmaya ihtiyacınız olacak.

Ortak mimari kalıplara bir göz atmalısınız - bunlardan biri MVC (Model-View-Controller) .

MVC kullanarak listelediğiniz yöntemleri dağıtıyor olsaydım, yaptığım şey şu:

Sınıfı Görüntüle:

  • GetMotorDataFromHTMLForm ()

Model Sınıfı (Esasen Motorlu):

  • GetMotorManufacturer ()
  • CanMotorHandleOperationConditions ()
  • CalculatePowerConsumption ()

Denetleyici Sınıfı (MotorsController):

  • GetAllMotors ()
  • GetMotorById ()
  • GetMotorByUserRequirements ()

PHP kullanıyor gibisiniz; bakmak için iyi bir MVC çerçevesi Laravel'dir . Örneklerinde hangi yöntemlerin ait olduğunu iyi gösterirler.

Bir başka, daha genel bilgi kaynağı, yöntemlerin nereye ait olduğuna karar vermenin nasıl GRASP ve SOLID ilkeleri olduğuna karar verir .


Teşekkürler. Özünde, bana sahip olduğum şeyin, bir miktar safsızlığı (Model, View, vs.) karıştırılmış olan bir Controller sınıfı olduğu görünüyor. Ben adlandırmak eğer anlamına mı MotorOperationsetmek MotorsControllerve biraz bunu temizlemek, benim fonksiyonları toplama OOP doğrultusunda olacak?
Dennis,

@Dennis, mutlaka değil, her sınıfın altındaki yöntemler koleksiyonuma bir bakın. Denetleyici hepsini içeren bir sınıf değil :) Modelleriniz üzerinde işlem yapan bir sınıf ve daha fazlası değil. Bir denetleyicinin yalnızca bağımlılıkları, genellikle doğrudan DAL (Veri Erişim Katmanı) veya DAL'ye erişim sağlayan hizmetler olabilir. Denetleyiciden Görünüm'e asla erişmek istemezsiniz (örnek: getMotorDataFromHTMLForm), bunun yerine Görünümünüz denetleyiciye bağlı olmalıdır.
Alexus

2
Bir Utilssınıfın neden kod kokusu örneği olacağına dikkat eder misiniz? Merak ediyorum, Utilssadece tek başına işlevler yerine bir sınıfa sarılmış rastgele kullanım işlevlerini kullanmaktan zevk aldığım için ... deneyimimde kodu biraz daha okunaklı hale getiriyor, ancak deneyimlerim sınırlı.
HC_

3
@HC_ Bir Utils sınıfına sahip olmak, resim koleksiyonunuzdaki "Misc" klasörüne sahip olmakla aynıdır. Düzgün / potansiyel olarak eksik nesnelerinize nesnelerinize sorumluluklar atamaktan çekindiğinizi ve bunu telafi etmek için Utils'i kullandığınızı gösterir. Util sınıflarına, özellikle statik fonksiyonlara ve diğer sınıflara genişletmelere sahip bir oda var, ancak böyle bir koleksiyon oluşturmadan önce, onları uygun OOP sınıflarınıza dahil edip edemediğinizi kontrol edin :) tek bir yöntem. Ancak ileriye gitmek için daha fazlasını eklemeniz gerekir ve Utils sınıfı daha büyük bir karmaşaya dönüşür.
Alexus,

Sık sık bir Utils LIBRARY ile sonuçlanır, ancak genellikle utils sınıflarımı biraz daha açıklayıcı olarak gruplandırmaya ve adlandırmaya çalışırım. Bu günlerde, birçok insanın ihtiyaç duyduğu genel amaçlı araçlara sahip olan birçok açık kaynak "ortak yardımcı program" kütüphanesi var, bu yüzden kendi yazınızı yazmadan önce biraz etrafa bakarım.
Guy Schalnat

15

Sınıflar varlıksız nesneleri temsil edebilir mi?

Yapabilmek? Evet. Meli? Muhtemelen hayır - ya da en azından bir şeyi nasıl ifade ettiğinizi.

Nesneler, fiziksel bir nesneyi doğrudan temsil etmediklerinde en iyisidir, çünkü gerçeklik çok nadiren kodlamaya çok uygundur. Ancak, uyumlu bir kavramı veya kod nesnesini temsil etmeleri gerekir. Tek bir yapışkan sorumluluğu temsil etmeleri gerekir.

Sadece teğetsel olarak ilgili fonksiyonların bir demetini bir araya getirmek, bir isim alanı veya bir modül - OOP parlance içindeki bir nesne değil. Bunlar faydalı olabilir, ancak aynı değillerdir ve etkili bir şekilde çalışmak için farklı bir kullanım / düşünce tarzı gerektirir.


3
bundling a bunch of tangentially related functions together is a namespace: Nesneye yönelik olmaktan çok, işlemsel paradigmaya benziyor.
Dennis,

@dennis - tam olarak (veya bir Modül diyorsanız işlevsel). Paradigmaları karıştırmak güçlü olabilir. Ya da çok karışık olabilir.
Telastyn

Veya her ikisi de :) - - - - -
Alexus

@Dennis: Ya da hiçbiri - sadece teğetsel olarak ilişkili işlevleri bir araya getirmek, herhangi bir paradigmada şüpheli bir uygulamadır.
sdenham,

Bir prosedürel kod temeli olarak başlayan kodla uğraşıyorum. Bir noktada onu OOD'ye dönüştürme çabası gösterildi, ancak çoğunlukla herhangi bir gerçek OO tasarımı olmadan "işlevleri ve yöntemleri tutma" için sınıflar oluşturuldu. Paradigmalar arasındaki boşluğu doldurmaya çalışan ama ne birinde ne de diğerinde olmayan oldukça az şey keşfettim
Dennis,

11

Bir sınıf bir şeyi modellemelidir - aksi takdirde anlamsızdır. Bununla birlikte, modellenen fiziksel bir "şey" olmayabilir; bunun yerine, 'gerçek' olmayan, ancak modellenmekte olan sistemi kontrol etmek için gereken bir şeyin temsili olabilir. Örneğin, trafik ışığı kontrol sisteminde, bazı işlemlerin yapılması gerektiğini belirtmek için sistemin bir kısmından diğerine gönderilen bir sinyali temsil eden bir tür ControlSignal sınıfına sahip olabilirsiniz. "Gerçek dünyada", bu sinyaller bir kutudan diğerine teller arasında iletilen elektriksel darbelerden oluşabilir. Somut bir nesne olarak "gerçek" olmayan bir şeyi modelleme sürecine "yeniden birleşme" denir.

İyi şanslar.


Evet, tam olarak söyleyeceğim şey buydu. Bir sınıf, bir isim için bir modelden başka bir şey değildir . Bu kadar. Ne fazla ne eksik. Bir sınıf bir isimdir ve yöntemler fiillerdir (ya da eğer istersen mesajlar). Bu basit terimlerle düşünen bir genç mühendis, bu analojiler bozulmadan önce çok uzun bir yol kat edebilir (sınıfların fiziksel nesnelerin tanımları olduğunu düşünmeye çalışmaktan farklı olarak - neredeyse ilk projenizi yıkmaya başlayan bir analoji).
Calphool

7

Hayır. (Başlık tam tersini sormak için düzenlendi!)

Örneğin:

Public class MyRepository
{
    public MyObject GetObject(string id)
    {
        //get data from the DB and build an object
    }
}

veya

Public class MyService
{
    public MyObject3 ProcessData(MyObject1 obj1, MyObject2 obj2)
    {
         //perform a process which is not a sole responsiblity of obj1 or obj2
    }
}

Ancak, genel olarak, OOP'un ardındaki ideal

public struct Car
{
    public Wheel[] Wheels;
}

public int CountWheelsOnCar(MyCarStruct car)
{
   return car.Wheels.Length;
}

için

public class Car
{
    private Wheel[] wheels;
    Public int CountWheels()
    {
        return this.wheels.Length;
    }
}

Varlıksız nesneleri temsil edebileceklerini mi kastediyorsunuz? (Ben soru üzerine bıraktığım yoruma bakın.)
Panzercrisis

3
OO'yu çok uzun zamandır programlıyorum sanırım - MyRepository'ye baktığımda hemen şifonyerimin üzerinde bir avuç dolusu bozuk para olan bir cam kase çizdim. Ulaşın ve bir peni veya bir düğmeyi yakalayın ....
Bill K

@ pan evet, örneğimin hizmet ve repo gibi
Ewan

Bill seni çılgın yaşlı aptal !!! Bu MyButtonAndOrPennyBowl sınıfı! temiz kodlama ftw
Ewan

1
İkinci örneğiniz bana (kendi görüşüme göre) kendi yararına haklı olmayan bir nesne gibi giyinmiş bir işlev gibi bakıyor, ancak başka bir gerekçelendirme olabilir (örneğin, işlevler dilde birinci sınıf varlıklar değilse). )
sdenham,

5

Sınıfları kodlarken gerçek dünyada bir şeyi görselleştirmenin yararlı olduğunu düşünüyorum ama gerekli değil.

Aslında, ne kadar gerçek olmak istediğinize bağlı olarak, birlikte çalıştığımız birçok nesnenin fiziksel temsili yoktur. Örneğin - MVC mimarisini düşünün. Gerçek dünyada, genellikle sınıflarla temsil edilmelerine rağmen, Model veya Kontrolör yoktur. Üçü birlikte genellikle bir şeyi temsil eder, ancak her zaman değil - ama söylediğim gibi muhtemelen gerçekten bir şeye uyum sağlayabileceksiniz (ve SOMETHING'in yardımcı olduğunu hayal edebilmek! sen gerçek dünyada göreceksin).

Çoğunlukla OO hakkında öğreneceğiniz bu “Kurallar” sadece OO'da günlük olarak kodlamak için kullandığınızda bir kez endişelenmeniz gereken şeyleri düşünmemeye yönlendirmenizi amaçlayan kılavuzlardır.

Bu arada, OO'nun kendisi bir derde deva değil ve bazı çözümleri kodlamadaki ilk geçişiniz boyunca size pek yardımcı olmuyor, ancak doğru yapılırsa kod düzenlemenin gerçekten harika bir yol olduğunu düşünüyorum. sonradan kolayca anlaşıldı. Bakım yapılabilir kod yazmak, muhtemelen yazılım geliştirmedeki en zor görevlerden biridir ve çoğu durumda (devam eden hata ayıklama / bakım gerektiren herhangi bir şey) en önemli olanıdır.


5

Bir nesne bir varlığı temsil etmek zorunda mı?

Soru: Hangi varlığı Loggertemsil eder?

Mecazi değil - kelimenin tam anlamıyla.

OOP'yi öğrencilere açıklarken, fiziksel dünyaya benzeyen nesneleri açıklamakta fayda var.

Alan Kay - babalarından biri OOP - Aşağıdaki yazdı:

[...]

Orijinal anlayışı aşağıdaki bölümleri vardı.

  • Nesnelerin biyolojik hücreler ve / veya bir ağdaki ayrı bilgisayarlar gibi olduklarını, yalnızca mesajlarla iletişim kurabildiklerini düşündüm.
  • Verilerden kurtulmak istedim.

[...]

OOP bana sadece mesajlaşma, yerel tutma ve koruma anlamına gelir ve

devlet sürecinin gizlenmesi ve her şeyin aşırı geç bağlanması.

neredeyse inanılmaz HW mimarisi. Farkettim ki

hücre / tüm bilgisayar metaforu verilerden kurtulur

kaynak

Bundan nesneler en iyisi olarak anlaşılır

  • verileri kapsayan / gizleyen otarkiç nesneler

  • mesajlar yoluyla diğer nesnelerle iletişim kurmak

Sınıflar varlıksız nesneleri temsil edebilir mi?

Kesinlikle: Düşün Math


Örneğinizle ilgili olarak:

Örnek: Bir sınıfa MotorOperations veya MotorActions adı verilebilir, burada varlık yoktur, ancak sınıf içindeki yöntemler gibi şeyler yapar

  • getMotorDataFromHTMLForm ()

  • getMotorManufacturers ()

  • selectMotorFromUserRequirements ($ gereksinimleri)

  • canMotorCanHandleOperatingConditions ($ koşullar)

  • computePowerConsumptionForMotor ($ id)

Bu yöntemleri nereye koyacağınıza karar vermek için şunlara bir göz atmanız gerekir responsibilities: kimin neye karşı sorumlu olduğu .

getMotorDataFromHTMLForm ()

Bu tür bir yöntemin bağlamında olacaktır bir motorlu bir nesne oluşturmak . Bir form aracılığıyla alınan Veriden kendisini oluşturmak motorun sorumluluğunda değildir . En az iki nesne var; biri motor, diğeri ise motorun yaratıcısı .

getMotorManufacturers ()

İçinde böyle bir yöntem yazdığı tipik bağlam a service.

selectMotorFromUserRequirements ($ gereksinimleri)

Bu aynı zamanda bir servicebağlamda kullanılacaktır

canMotorCanHandleOperatingConditions ($ koşullar)

Bu bir motorhedef için bir soru

computePowerConsumptionForMotor ($ id)

Bu da en iyi sorulan bir motorun kendisi.


tl; Dr.

Fiziksel nesnelerobjects olarak metafor, yardımcı olmaktan daha rahatsız edicidir.


vay cevabınız OOP içine bazı hayat nefes! Her şeyin sonu olarak fiziksel demek istemediğimi söylemeliyim . sorumun amacı daha fazlaydı "bir nesnenin thingverinin net bir şekilde ait olduğu veriyle ve bir veriye ait olan veri üzerinde net bir şekilde işleyen fonksiyonları olması gerekiyor mu?" Yani Logger, bu durumda, fiziksel bir şey olmasa da, “fiziksel günlük kitabı” na benzeyen bir kavramdır. Durumunun özü olan ve yalnızca geçici olmayan veriye sahip olup olmadığı, uygulama ve yorumlamaya bağlı olabilir .. ve sorumun gideceği yer daha fazlası ..
Dennis,

ama evet, cevaplar fiziksel yanlılığımı ele almak zorunda kaldı
Dennis,

3

Evet, bunu yapabilirsiniz. Ancak, esasen bir prosedür kütüphanesiyle aynı işlevselliği sağlamak için bir sınıf yaratıyorsunuz. Bunu yapmanın tek nedeni, dilinizin prosedür modüllerinden (örneğin, Java veya Ruby) yok olmasıdır.

Prosedürel modülleri olan bir dilde (PHP'nin prosedür modülleri olduğunu düşünüyorum), sadece prosedür modülünü kullanmayı düşünebilirsiniz.

Ayrıca, sınıfınızı yeniden tasarlamayı düşünebilirsiniz, böylece sınıfın bir örneği tutarlı bir nesneyi temsil eder.

Ancak, yalnızca OO olma uğruna değil, size ekstra güç verirken yalnızca OO gösterimini kullanın!


3

Layman'ın sözleriyle

  • Tanımladığınız şeye yardımcı sınıf denir.
  • Hiçbir devleti yoktur, yani bunun birkaç örneğine gerçekten ihtiyacınız olmayacak demektir.
  • Tüm yöntemler statiktir, yani her şeyi parametre olarak iletmeniz gerekir

Bu tür sınıflar mevcuttur; örneğin, Java SDK, yalnızca koleksiyonlarda çalışan veya geri dönen statik yöntemlerden oluşan Koleksiyonlar sınıfına sahiptir.

Dolayısıyla cevap hayır olacaktır, tüm sınıfların bir etki alanı öğesinden modellenmesi gerekmez.

Öte yandan, bu sınıflar sadece birkaçıdır veya bir OOP dilinde yapılan bir programda sadece birkaçıdır, çünkü OOP'un gerçek gücü polimorfizm ve kapsüllemedir.

Bir yerden diğerine gitmek için uçağı kullanarak değil de otoyollarda sürerek bir uçak kullanmak gibi olur. Uçakların arabaları gibi tekerlekleri vardır, ancak uçmaları amaçlanmıştır.


2

Hayır, bir sınıf sadece somutlaştırılabilecek, üyeleri olan ve miras alınabilecek bir şeyi temsil eder.

Aslında, dilinizde birden fazla kez başlatılmayan statik sınıflar olabilir.

.NETMath , varlığı temsil etmeyen (matematiğin ne olduğu hakkında felsefi olmak istemediğiniz sürece ...) "profesyonel" bir sınıfa harika bir örnektir ve aynı zamanda böyle bir sınıfın meşru bir kullanım durumunu göstermektedir. Yalnızca yöntemleri ve 2 alanı vardır (her ikisi de bireysel sabitleri temsil eder).

Benzer bir kütüphanenin sınıf hiyerarşisi, Math.Netmatematiksel / sayısal yöntemleri türlerine göre sınıflara ayırır. Burada sınıflar bir varlığı değil, mantıklı bir kategoriyi temsil eder.

Ben kendimi sık sık ilgili (statik) işlevler çantasından başka bir şey olmayan (statik) sınıflar ya da tek bir merkezi yerde uygun bir şekilde gruplanmış bir grup sabitler oluşturabilirim. Bunun iyi bir tasarım olduğunu iddia etmem ama bazen en basit çözüm.


1
Matematiğe ilişkin yöntemlerin .NET / BCL’de statik yöntemler olarak ayrı bir sınıfa yerleştirilmesi bir gereklilik veya tasarım değerlendirmesi değil, C # 'da serbest duran yöntemler olmadığı gerçeğinin bir sonucudur. C ++ 'da, bu tür fonksiyonlar sadece bir ad alanına gruplandırılabilir.
Vlad

1

Sorularınızın cevapları nihayetinde “sınıf” ve “varlık” gibi terimlerin tam olarak nasıl tanımlandığına bağlıdır. Hem fiziksel hem de kavramsal varlıklara izin vererek, ikincisini tanımlamak için iyi bir iş çıkardınız. Fakat "sınıf" için "saflaştırıcılar" her zaman "belirli bir iç temsili olan nesnelerin somutlaştırılması için bir fabrika" olacak ve pragmatistler için bu terim, puristler tarafından aşağılanan Java veya C ++ şeylerini kapsayacaktır. Pragmatistler Java ve C ++ 'ın söyleyebileceği, ancak hangilerinin Alan Kay' nın "Kayıtsız nesne yönelimini icat ettim ve sana söylemedim" akılda C ++ var "] ( Öyleyse * Alan Kay gerçekten" nesne yönelimli "terimi ile ne demek istedi? ).

Pragmatik görünümüne bakarsanız, örnek niteliğindeki yarar sınıflarınızı kabul edebilirsiniz. Ancak saf görüş daha ilginç. Kay'a göre OOP her zaman sınıflardan ziyade mesajlarla ilgili olmuştur . Yani sorularınız için:

Sınıflar varlıksız nesneleri temsil edebilir mi?

Hayır. Sınıflar nesneleri sınıflandırır . Sınıflar, tanım gereği new, nesne üretmek gibi bir mesaj gönderdiğiniz varlıklardır . Bir nesne, bir sınıftan yapılmış bir varlıktır. Nesneleri üretmek ve sınıflandırmak için sınıflar mevcuttur. Sınıfların yaptığı budur. Sınıflar nesneler oluşturur. Nesneleri sınıflandırmak için sınıfları kullanıyoruz. Bu nedenle eğer C, yalnızca başlatmaya veya alt sınıfa izin vermeyen bir yöntem demetiyse, C tarafından sınıflandırılan herhangi bir nesne olamaz, bu nedenle C bir sınıf değildir.

Eğer değilse, neden kötü / eksik / OOP merkezli değiller?

Fena değiller. Sadece onlara sınıf deme. Yöntemlerin bir paket olan şey bir yöntemi çağırmak için bir mesaj gönderebilir, ancak bir nesne örneğini sürece bu bir sınıf değil: OOPable. Ruby'yi tanıyor musun? Ruby'de bir modül bir yöntemler grubudur. Bir sınıf nesneleri örneğini bir modüldür. Bir modül hakkında kötü bir şey yok . Fakat bir sınıfı bir modülden farklı kılan şey (saf OOP terimleriyle) bir sınıfın örnekleri olabileceğidir. Bir modül sadece bazı yöntemlerdir. Karışıklık, C ++ ve Java ile diğer dillerin hem sınıf hem de modül için "sınıf" terimini kullanmasıdır .

Şimdi, belirli örneklerden birine bakmak için MotorOperations, mesajı computePowerConsumptionForMotorargümanla gönderebileceğiniz bir sınıf hakkında soru sorabilirsiniz id. Kötümü? En azından, Soru Sorma İlkesini ihlal etmiyor . Biz Do sahip bir motorlu sınıfını yapmak ve ona gönderme powerConsumptionmesajı? Belki de zamanın% 100'ü değil, ama belki de böyle şeyler yapmaya çalışmak kodunuz hakkında bazı güzel içgörülere yol açacaktır. Veya, kötü olabilecek küçük sınıfların patlamasına yol açabilir.

OOP ile uyumlu olması için kavramsal olarak değiştirilmesi / iyileştirilmesi gereken yollar var mı?

"OOP yapmak" sizin için önemliyse, bir sistemi birbirine mesaj göndererek iletişim kuran bileşenlere dönüştürmenin yollarını aramak istersiniz. Bu sadece OOP'nin ne olduğu veya en azından terimin belirleyicisinin aklında olan şeydir. Yardımcı program sınıfları bu görünümde OOP değildir. Ancak bazı insanlar için olabilir.

Tamamı sınıflardan örneklenen milyonlarca canlı, nefes alan, nesneden büyük bir sistem yapmaya çalışmak bazı projeler için işe yarayabilir. Ancak, kendinizi yapay, yanlış ses veren sınıflar oluştururken bulursanız, modüller tanıtılmalıdır. Sınıfları vurgulamaya çalışın ve başlatılabilir sınıfların saçma olduğu durumlarda modülleri kullanın.

TL; DR - yöntem paketleri her zaman kötü değildir. İlk önce somutlaştırılabilir sınıfları kullanmaya çalışın. Sadece gerektiğinde "modüllere" geri dönün.


0

Verilen örneklerin alınması:

getMotorDataFromHTMLForm()
selectMotorFromUserRequirements($requirements)

Bunlar “fabrika” yöntemlerine benziyor, bu da Motornesneyi geri getirecek . İkincisi, ya gereksinimleri karşılayacak yeni bir nesne yarattığınızı ya da incelemekte olduğunuz bir veritabanına ya da bellekte bir koleksiyona sahip olduğunuz anlamına gelir. Bu durumda bu konuda bir yöntem olmalı. Veya gereksinimler nesnesindeki bir yöntem olabilir.

getMotorManufacturers()

Onları nereden alıyorsun? Bunun bir yöntemi olmalıydı.

canMotorCanHandleOperatingConditions($conditions)
computePowerConsumptionForMotor($id)

Bunlar üzerinde yöntem olması gerektiği gibi görünüyor Motor.


Evet. "muhtemelen alakasız yöntemlerin bir demeti" dir (kısaca BOPUM). Fabrika ve Motor yorumlarına katılıyorum. getMotorManufacturerstüm motor üreticilerini veri tabanından iade etmektir. Bunun nereye gittiğinden emin değilim. Gitmeleri gereken şeyleri koymak için bu BOPUM'u çözmem biraz zaman alacak ..
Dennis

getMotorManufacturersVeritabanından alıyorum . Veritabanının bir yöntemi olamaz ... Şu anda veritabanını sorgulayan, bir diziyi başlatan ve bunu Motor Nesneleriyle (ayrıca Üretici bilgilerini de içeren) dolduran ve daha sonra bu diziyi arayana döndüren bir DataMapper şablonum var. Arayan, benim MotorOperationssınıfımdır ve sırayla bir ProductSelectionsınıftan çağrılır (Motorları seçmek için kullanılan bir algoritmayı içerir ve yüklü motor bilgisi bu algoritmanın verileridir)
Dennis,

0

Bir nesne, yüksek uyumu olan bir yöntem ve veri topluluğudur. Onlar bir sınıfa mensupturlar çünkü birbirleriyle çok ilişkili ve devletleri koruyorlar.

Bu, büyük ön tasarım kullanıyorsanız ve her şeyi modelleme girişiminde bulunuyorsanız ya da nesneyi o andaki sistemin gereksinimlerine uyan her şeye yineleyen ve geliştiren ortaya çıkan tasarımı tasarlarsanız geçerlidir.

Devleti korumak için bir nedeniniz yoksa, muhtemelen bir nesneyi somutlaştırmak için hiçbir nedeniniz yoktur, yani bir sınıfa sahip olmak için muhtemelen bir neden yoktur. Aksi takdirde, kullandığınız dil, sınıf kullanmaktan başka bir ad alanı tanımlayamaz. Hangi sınıf kullanmak iyi olmalı çünkü deyimsel olurdu.

Sınıfları normalden başka bu şekilde kullanmanın olumsuz yönlerini düşünemiyorum. Bir "ad alanı" nı başlatmak zorunda kalarak, gereksiz maliyet ve karmaşıklığı davet etmek. Bu kodu destekleyen herkes, verilerin nereden bilişsel yüke mal olduğunu merak edecektir (büyük olasılıkla kişi başına bir kerelik maliyet). Herhangi bir ek değer olmadan sıradışı bir kullanımdır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.