“Düz eski veriler” sınıflarını kullanmak için herhangi bir neden var mı?


43

Eski kodda bazen veri için paketleyiciden başka bir şey olmayan sınıfları görüyorum. gibi bir şey:

class Bottle {
   int height;
   int diameter;
   Cap capType;

   getters/setters, maybe a constructor
}

Benim OO anlayışım, sınıfların veri yapıları ve bu veriler üzerinde çalışma yöntemleri olduğu yönündedir. Bu, bu tür nesneleri engelliyor görünmektedir. Bana göre onlar structsOO'nun amacını yenmekten başka bir şey değil . Mutlaka kötülük olduğunu sanmıyorum, bir kod kokusu olsa da.

Bu tür nesnelerin gerekli olacağı bir durum var mı? Bu sık kullanılırsa, tasarımdan şüpheleniyor mu?


1
Bu, sorunuzu tam olarak cevaplamıyor ama yine de alakalı görünüyor: stackoverflow.com/questions/36701/struct-like-objects-in-java
Adam Lear

2
Bence aradığınız terim POD (Plain Old Data).
Gaurav

9
Bu, yapılandırılmış programlamanın tipik bir örneğidir. Mutlaka fena değil, sadece nesneye yönelik değil.
Konrad Rudolph

1
Bu yığın taşması olmamalı mı?
Muad'Dib

7
Muad'Dib'in @: teknik olarak, bu ise programcılar hakkında. Derleyiciniz düz eski veri yapıları kullanmanıza aldırış etmiyor. İşlemciniz muhtemelen bundan hoşlanır ("Önbellekten yeni gelen veri kokusunu seviyorum" türünden). Bu var insanlar kafayı "bu benim metodoloji az saf yapar?" sorular.
Shog9

Yanıtlar:


67

Kesinlikle kötü ve aklımda bir kod kokusu değil. Veri kapları geçerli bir OO vatandaşıdır. Bazen ilgili bilgileri bir arada tutmak istersiniz. Gibi bir yöntem olması çok daha iyi

public void DoStuffWithBottle(Bottle b)
{
    // do something that doesn't modify Bottle, so the method doesn't belong
    // on that class
}

göre

public void DoStuffWithBottle(int bottleHeight, int bottleDiameter, Cap capType)
{
}

Ayrıca bir sınıf kullanmak, DoStuffWithBottle'un her arayanını değiştirmeden Şişe'ye ek bir parametre eklemenizi sağlar. Ayrıca, Şişeyi alt sınıflandırabilir ve gerekirse kodunuzun okunabilirliğini ve düzenini daha da artırabilirsiniz.

Örneğin bir veritabanı sorgusu sonucunda döndürülebilen düz veri nesneleri de vardır. Bu durumda onlar için kullanılan terimin "Veri Aktarım Nesnesi" olduğuna inanıyorum.

Bazı dillerde başka düşünceler de var. Örneğin, C # sınıflarında ve yapılar farklı davranır, çünkü yapılar bir değer türüdür ve sınıflar referans türleridir.


25
Hayır. DoStuffWithBir yöntem olmalıdır arasındaBottle OOP sınıfının (ve büyük ihtimalle de değişmez olmalıdır). Yukarıda yazdıklarınız, bir OO dilinde iyi bir kalıp değildir (eski bir API ile etkileşime girmediğiniz sürece). Bu ise , ancak, olmayan bir OO ortamda geçerli bir tasarım.
Konrad Rudolph

11
@Javier: O zaman Java da en iyi cevap değil. Java'nın OO'ya yaptığı vurgu çok zor, dil temelde başka hiçbir şeyde iyi değil.
Konrad Rudolph

11
@ JohnL: Elbette basitleştiriyordum. Ancak genel olarak, OO'daki nesneler durumu değil, verileri kapsar. Bu iyi ama önemli bir ayrım. OOP'nin amacı, etrafta çok fazla veri bulunmamasıdır. Bu edilir mesaj gönderirken yeni bir devlet yaratmak devletler arasında. Metodsuz bir nesneye nasıl mesaj yollayabileceğinizi göremiyorum. (Ve bu , OOP'un asıl tanımıdır, bu yüzden kusurlu olduğunu düşünmemeliydim.)
Konrad Rudolph

13
@Konrad Rudolph: Bu yüzden açıkça metodun içindeki yorumu yaptım. Şişe örneklerini etkileyen yöntemlerin o sınıfa girmesi gerektiğine katılıyorum. Ancak, bir başka nesnenin Şişe'deki bilgilere dayanarak durumunu değiştirmesi gerekiyorsa, tasarımımın oldukça geçerli olacağını düşünüyorum.
Adam Lear

10
@Konrad, StuffWithBottle ile şişe sınıfına girmemesi konusunda aynı fikirdeyim. Neden bir şişe kendi kendine bir şeyler yapmayı bilesin ki? doStuffWithBottle, başka bir şeyin bir şişe ile bir şey yapabileceğini gösterir . Şişe içinde olsaydı, sıkı bir kaplin olurdu. Ancak, Bottle sınıfında bir isFull () yöntemi varsa, bu tamamen uygun olacaktır.
Nemi,

25

Veri sınıfları bazı durumlarda geçerlidir. DTO'lar Anna Lear tarafından belirtilen iyi bir örnektir. Yine de, genel olarak, onları yöntemleri henüz filizlenmemiş bir sınıfın tohumu olarak görmelisiniz. Ve eski kodda çoğuna giriyorsanız, onlara güçlü bir kod kokusu gibi davranın. Genellikle OO programlamasına geçiş yapmamış ve prosedürel programlamanın işareti olan eski C / C ++ programcıları tarafından kullanılırlar. Her zaman alıcılara ve ayarlayıcılara güvenmek (ya da daha kötüsü, özel olmayan üyelerin doğrudan erişimine), bunu bilmeden önce başınızı belaya sokabilirsiniz. Bilgilendirilmesi gereken harici bir yöntem örneği düşünün Bottle.

İşte Bottlebir veri sınıfı):

void selectShippingContainer(Bottle bottle) {
    if (bottle.getDiameter() > MAX_DIMENSION || bottle.getHeight() > MAX_DIMENSION ||
            bottle.getCapType() == Cap.FANCY_CAP ) {
        shippingContainer = WOODEN_CRATE;
    } else {
        shippingContainer = CARDBOARD_BOX;
    }
}

İşte Bottlebazı davranışlar verdik ):

void selectShippingContainer(Bottle bottle) {
    if (bottle.isBiggerThan(MAX_DIMENSION) || bottle.isFragile()) {
        shippingContainer = WOODEN_CRATE;
    } else {
        shippingContainer = CARDBOARD_BOX;
    }
}

İlk yöntem, Sorma-Yapma ilkesini ihlal ediyor ve Bottledilsiz kalarak , şişeler hakkında gizli bir bilgiyi sınıfın Capdışında kalan mantığa kaçıranlar gibi örtük bilgiler sağladık Bottle. Alışkanca alıcılara güvendiğiniz zaman bu tür bir “sızıntıyı” önlemek için parmak uçlarında olmalısınız.

İkinci yöntem, Bottleyalnızca işini yapması gerekenleri sorar ve Bottlebelirli bir boyuttan daha kırılgan veya daha büyük olup olmadığına karar verir. Sonuç, yöntem ve Şişe'nin uygulanması arasında çok daha gevşek bir bağlantıdır. Hoş bir yan etki, yöntemin daha temiz ve daha etkileyici olmasıdır.

Nesnenin bu kadar çok alanından nadiren faydalanacaksınız, bu alanlarla sınıfta bulunması gereken bir mantık yazmadan. Bu mantığın ne olduğunu bulup, ait olduğu yere taşıyın.


1
Bu cevabın oy kullanmadığına inanamıyorum (peki, şimdi bir tane var). Bu basit bir örnek olabilir, ancak OO yeterince kötüye kullanıldığı zaman, sınıf içinde kapsüllenmesi gereken tonlarca işlevsellik içeren kabuslara dönüşen hizmet sınıfları alırsınız.
Alb

"Eski C / C ++ programcıları tarafından hiçbir zaman OO'ya geçiş yapmamış (sic)"? Bir OO dil, C. yerine C ++ kullanarak yani bütün mesele olarak C ++ programcıları genellikle oldukça OO vardır
nappyfalcon

7

İhtiyacınız olan şey buysa, sorun değil, ama lütfen, lütfen, lütfen bunu yapın

public class Bottle {
    public int height;
    public int diameter;
    public Cap capType;

    public Bottle(int height, int diameter, Cap capType) {
        this.height = height;
        this.diameter = diameter;
        this.capType = capType;
    }
}

yerine

public class Bottle {
    private int height;
    private int diameter;
    private Cap capType;

    public Bottle(int height, int diameter, Cap capType) {
        this.height = height;
        this.diameter = diameter;
        this.capType = capType;
    }

    public int getHeight() {
        return height;
    }

    public void setHeight(int height) {
        this.height = height;
    }

    public int getDiameter() {
        return diameter;
    }

    public void setDiameter(int diameter) {
        this.diameter = diameter;
    }

    public Cap getCapType() {
        return capType;
    }

    public void setCapType(Cap capType) {
        this.capType = capType;
    }
}

Lütfen.


14
Bununla ilgili tek sorun, doğrulama olmamasıdır. Geçerli bir Şişenin ne olduğuna dair herhangi bir mantık, Şişe sınıfında olmalıdır. Bununla birlikte, önerilen uygulamanızı kullanarak, negatif yüksekliğe ve çapa sahip bir şişeye sahip olabilirim - nesnenin her kullanımını onaylamadan herhangi bir iş kuralını zorlama yolu yoktur. İkinci yöntemi kullanarak, bir Şişe nesnem varsa, sözleşmeme göre geçerli bir Şişe nesnesi olduğundan ve her zaman geçerli bir Şişe nesnesi olduğundan emin olabilirim.
Thomas Owens

6
Bu, .NET'in özellikler üzerinde küçük bir kenara sahip olduğu bir alandır, çünkü doğrulama mantığına sahip bir özellik erişimcisi ekleyebilir, bir alana erişiyormuş gibi aynı sözdizimine sahip olabilirsiniz. Ayrıca sınıfların özellik değerini alabileceği, ancak ayarlayamadığı bir özellik tanımlayabilirsiniz.
JohnL

3
@ user9521 Kodunuzun "kötü" değerlerde önemli bir hataya neden olmayacağından eminseniz, yönteminize gidin. Bununla birlikte, daha fazla doğrulama, tembel yükleme veya veri okunduğunda veya yazıldığında diğer kontrolleri kullanabilme becerisine ihtiyacınız varsa, açık alıcılar ve ayarlayıcılar kullanın. Şahsen değişkenlerimi özel tutma ve tutarlılık için alıcılar ve ayarlayıcılar kullanma eğilimindeyim. Bu yolla, tüm değişkenlerime doğrulama ve / veya diğer "ileri" tekniklerden bağımsız olarak aynı muamele edilir.
Jonathan,

2
Yapıcıyı kullanmanın avantajı, sınıfı değiştirilemez kılmayı çok kolaylaştırmasıdır. Çok iş parçacıklı kod yazmak istiyorsanız bu çok önemlidir.
Fortyrunner

7
Alanları mümkün olduğunca kesinleştiririm. IMHO Varsayılan olarak final alanlarını seçebilir ve değişken alanlar için bir anahtar kelimeye sahip olurdum. örneğin var
Peter Lawrey 1: 30'da

6

@Anna'nın dediği gibi kesinlikle kötü değil. İşlemleri (yöntemleri) sınıflara koyabilirsiniz, ancak yalnızca isterseniz . Sen yok olması için.

Sınıfları soyutlama olduğu fikrinin yanı sıra, işlemleri sınıflara dahil etmek zorunda olduğunuz fikrine dair bana küçük bir yakınma izni verin. Uygulamada, bu programcıları teşvik eder.

  1. İhtiyaç duyduklarından daha fazla sınıf oluşturun (gereksiz veri yapısı). Bir veri yapısı minimal gerekenden daha fazla bileşen içerdiğinde, normalleştirilmez ve bu nedenle tutarsız durumlar içerir. Başka bir deyişle, değiştirildiğinde, tutarlı kalabilmek için birden fazla yerde değiştirilmeye ihtiyacı vardır. Tüm koordineli değişiklikleri yapmamak, tutarsızlığa neden olur ve bir hatadır.

  2. Sorun 1'i bildirim yöntemlerini koyarak çözün , böylece A bölümü değiştirilirse, B ve C bölümlerinde gerekli değişiklikleri yaymaya çalışır. Bu, alma ve ayarlama erişim yöntemlerine sahip olmanın önerilmesinin temel nedenidir. Bu önerilen uygulama olduğundan, 1. sorunun daha fazla ve 2. çözümünün daha fazlasına neden olduğu 1. sorunu mazeret ettiği anlaşılıyor. Bu, yalnızca bildirimlerin tam olarak uygulanmamasından kaynaklanan hatalarla sonuçlanmıyor, aynı zamanda kaçak bildirimlerin performanstan düşme sorununa yol açıyor. Bunlar sonsuz hesaplamalar değil, sadece çok uzun olanlar.

Bu kavramlar, genellikle bu konularla uğraşan milyon hat canavar uygulamaları içinde çalışmak zorunda kalmayan öğretmenler tarafından iyi şeyler olarak öğretilir.

İşte yapmaya çalıştığım şey:

  1. Verileri mümkün olduğu kadar normalize edin, böylece verilerde bir değişiklik yapıldığında, tutarsız bir duruma girme olasılığını en aza indirgemek için mümkün olduğunca az kod noktasında yapılır.

  2. Verilerin normalleştirilmemesi gerektiğine ve fazlalık kaçınılmaz olduğu zaman, tutarlı olmasını sağlamak için bildirimleri kullanmayın. Aksine, geçici tutarsızlığa tahammül. Verileri, yalnızca bunu yapan bir işlemle periyodik taramalarla tutarsızlığı giderin. Bu, bildirimlerin yatkın olduğu performans ve doğruluk problemlerinden kaçınırken tutarlılığı sağlama sorumluluğunu merkezileştirir. Bu, kodun çok daha küçük, hatasız ve verimli olmasıyla sonuçlanır.


3

Bu tür sınıflar, bazı nedenlerden dolayı orta büyüklükteki / büyük uygulamalarla çalışırken oldukça yararlıdır:

  • Bazı test durumları oluşturmak ve verilerin tutarlı olmasını sağlamak oldukça kolaydır.
  • bu bilgileri içeren her türlü davranışı tutar, böylece veri hata takip süresi azalır
  • Bunları kullanarak metotların hafif kalmasını sağlamalıdır.
  • ORM kullanırken bu sınıflar esneklik ve tutarlılık sağlar. Zaten sınıftaki basit bilgilere dayanarak hesaplanan karmaşık bir nitelik eklemek, basit bir yöntemle yazılı olarak resutls. Bu, veritabanınızı kontrol etmek ve tüm veritabanlarının yeni bir değişiklikle yamalanmasını sağlamak zorunda kalması konusunda daha çevik ve üretkendir.

Özetle, benim deneyimlerime göre genellikle sinir bozucu olmaktan daha faydalıdır.


3

Oyun tasarımıyla birlikte, 1000'lerin işlev çağrılarının ek yükü ve olay dinleyicileri bazen yalnızca veri depolayan sınıflara ve mantığı gerçekleştirmek için yalnızca tüm veri sınıflarına giren başka sınıflara sahip olmaya değer yapabilir.


3

Anna Lear ile aynı fikirde

Kesinlikle kötü ve aklımda bir kod kokusu değil. Veri kapları geçerli bir OO vatandaşıdır. Bazen ilgili bilgileri bir arada tutmak istersiniz. Gibi bir yöntem olması çok daha iyi ...

Bazen insanlar, bu tür bir programlamanın tamamen iyi olduğunu açıkça belirten 1999 Java Kodlama Sözleşmelerini okumayı unuturlar. Aslında kaçınırsanız, kodunuz kokar! (çok fazla alıcı / ayarlayıcı)

Java Kod Sözleşmelerinden 1999: Uygun genel örnek değişkenlerine bir örnek, sınıfın temelde davranışsız bir veri yapısı olduğu durumudur. Başka bir deyişle, eğer bir sınıf yerine bir yapı kullanmış olsaydınız (eğer Java destekli yapıysa), o zaman sınıfın örnek değişkenlerini ortak yapmak uygun olacaktır. http://www.oracle.com/technetwork/java/javase/documentation/codeconventions-137265.html#177

Doğru kullanıldığında, POD'lar (düz eski veri yapıları) POJO'lardan daha iyidir, POJO'lar çoğu zaman EJB'lerden daha iyidir.
http://en.wikipedia.org/wiki/Plain_Old_Data_Structures


3

Yapılar, Java'da bile kendi yerlerine sahiptir. Bunları yalnızca aşağıdaki iki şey doğruysa kullanmalısınız:

  • Sadece herhangi bir davranışı olmayan verileri toplamanız gerekir, örneğin bir parametre olarak geçmek için
  • Toplanan verilerin ne tür bir değeri olduğu önemli değil.

Bu durumda, alanları halka açık hale getirmeli ve alıcıları / ayarlayıcıları atlamalısınız. Alıcılar ve ayarlayıcılar yine de sıkıntılıdır ve Java, kullanışlı bir dil gibi özelliklere sahip olmadığı için aptalcadır. Yapı benzeri nesneniz zaten herhangi bir yönteme sahip olmamalı olduğundan, ortak alanlar en mantıklı olanıdır.

Ancak, bunlardan herhangi biri geçerli değilse, gerçek bir sınıfla karşı karşıya kalırsınız. Bu, tüm alanların özel olması gerektiği anlamına gelir. (Daha erişilebilir bir kapsamda kesinlikle bir alana ihtiyacınız varsa, bir alıcı / alıcı kullanın.)

Sözde yapınızın davranış olup olmadığını kontrol etmek için alanların ne zaman kullanıldığına bakın. Söylemeyi ihlal ediyor gibi görünüyorsa , sormayın , o zaman bu davranışı sınıfınıza taşımalısınız .

Verilerinizden bazılarının değişmemesi gerekiyorsa, tüm bu alanları kesinleştirmeniz gerekir. Sınıfınızı değişmez kılmayı düşünebilirsiniz . Verilerinizi doğrulamanız gerekiyorsa, ayarlayıcılarda ve kurucularda doğrulama sağlayın. (Yararlı bir püf noktası, özel bir belirleyici tanımlamak ve yalnızca o belirleyiciyi kullanarak alanınızdaki sınıfınızı değiştirmek.)

Şişe örneğiniz muhtemelen her iki testte de başarısız olur. Şuna benzer bir kod (olabilir) olabilir:

public double calculateVolumeAsCylinder(Bottle bottle) {
    return bottle.height * (bottle.diameter / 2.0) * Math.PI);
}

Bunun yerine olmalı

double volume = bottle.calculateVolumeAsCylinder();

Yüksekliği ve çapı değiştirdiyseniz, aynı şişe olur mu? Muhtemelen değil. Bunlar kesin olmalı. Çap için negatif bir değer tamam mı? Şişen geniş olduğundan daha uzun olmalı mı? Kapak null olabilir mi? Hayır? Bunu nasıl onaylıyorsunuz? Müşterinin aptal ya da kötü olduğunu varsayalım. ( Farkı söylemek mümkün değil. ) Bu değerleri kontrol etmeniz gerekiyor.

Yeni Bottle sınıfınız şöyle görünebilir:

public class Bottle {

    private final int height, diameter;

    private Cap capType;

    public Bottle(final int height, final int diameter, final Cap capType) {
        if (diameter < 1) throw new IllegalArgumentException("diameter must be positive");
        if (height < diameter) throw new IllegalArgumentException("bottle must be taller than its diameter");

        setCapType(capType);
        this.height = height;
        this.diameter = diameter;
    }

    public double getVolumeAsCylinder() {
        return height * (diameter / 2.0) * Math.PI;
    }

    public void setCapType(final Cap capType) {
        if (capType == null) throw new NullPointerException("capType cannot be null");
        this.capType = capType;
    }

    // potentially more methods...

}

0

IMHO genellikle orada değil yeterli ağır nesne yönelimli sistemlerde böyle sınıfları. Bunu dikkatlice nitelemeye ihtiyacım var.

Tabii ki veri alanları geniş kapsam ve görünürlük içeriyorsa, kod tabanınızda bu tür verilerle kurcalayan yüzlerce veya binlerce yer varsa, bu oldukça istenmeyen bir durum olabilir. Değişmeyenleri korumak için zorluk ve zorluklar istiyor. Yine de aynı zamanda, kod kodlarının tamamındaki her bir sınıfın bilginin gizlenmesinden faydalandığı anlamına gelmez.

Ancak bu tür veri alanlarının çok dar kapsamlara sahip olacağı birçok durum vardır. Çok basit bir örnek, Nodeveri yapısının özel bir sınıfıdır. Sadece Nodebasit ham verilerden oluşabiliyorsa, devam eden nesne etkileşimlerinin sayısını azaltarak kodu büyük ölçüde basitleştirebilir . Yani diyelim ki, gelen çift yönlü bağlantı gerektirebilir alternatif versiyonunda beri bir ayrıştırıcı bir mekanizma olarak hizmet vermektedir Tree->Nodeve Node->Treebasitçe karşı Tree->Node Data.

Daha karmaşık bir örnek, oyun motorlarında sıkça kullanılan varlık bileşen sistemleri olabilir. Bu durumlarda, bileşenler genellikle yalnızca ham verilerdir ve gösterdikleriniz gibi sınıflardır. Bununla birlikte, bunların kapsamı / görünürlüğü sınırlı olma eğilimindedir, çünkü tipik olarak bu belirli bileşen tipine erişebilecek yalnızca bir veya iki sistem vardır. Sonuç olarak, bu sistemlerde değişmezleri korumayı oldukça kolay bulma eğilimindesiniz ve dahası, bu tür sistemler çok az object->objectetkileşime sahiptir, bu da kuşun gözünde neler olup bittiğini kavratmayı çok kolaylaştırır.

Bu gibi durumlarda, etkileşimler devam ettiği sürece buna benzer bir şeyle sonuçlanabilir (bu şema, eşleşmeyi değil etkileşimleri gösterir, çünkü bir eşleştirme şeması aşağıdaki ikinci görüntü için soyut arayüzleri içerebilir):

görüntü tanımını buraya girin

... bunun aksine:

görüntü tanımını buraya girin

... ve eski tip sistemlerin bakımı çok daha kolay olma eğilimindedir ve bağımlılıkların gerçekte verilere doğru aktığı gerçeğine rağmen, doğruluk açısından sebep vardır. Öncelikle çok daha az birleşme elde edersiniz, çünkü birçok şey birbiriyle etkileşime giren nesneler yerine ham verilere dönüştürülebilir, çok karmaşık etkileşimler grafiği oluşturur.


-1

OOP dünyasında bile çok garip yaratıklar var. Bir zamanlar soyut ve hiçbir şey içermeyen bir sınıf yarattım, sadece diğer iki sınıfın ortak bir ebeveyni olmak için ... Port sınıfı:

SceneMember 
Message extends SceneMember
Port extends SceneMember
InputPort extends Port
OutputPort extends Port

Böylece, SceneMember temel sınıftır, sahnede görünmesi gereken tüm işi yapar: ekleme, silme, kimlik ayarlama vb. Mesaj portlar arasındaki bağlantıdır, kendi yaşamı vardır. InputPort ve OutputPort, özel giriş / çıkış fonksiyonlarını içerir.

Bağlantı noktası boş. Sadece bir portlist için InputPort ve OutputPort gruplandırılması için kullanılır. Boş çünkü SceneMember, üye olarak hareket etmek için her şeyi içeriyor ve InputPort ve OutputPort, limanda belirtilen görevleri içeriyor. InputPort ve OutputPort çok farklı, ortak (SceneMember hariç) fonksiyonlara sahip değiller. Yani, liman boş. Ama bu yasal.

Belki bir antipattern , ama hoşuma gitti.

(Hem "eş" hem de "koca" için kullanılan "eş" kelimesi gibidir. Hiç bir "eş" kelimesini somut bir kişi için kullanmazsınız, çünkü onun cinsiyetini biliyorsunuzdur ve önemli değil) eğer evli ya da evli değilse, onun yerine "birini" kullanıyorsunuz, ancak hala var ve nadir, soyut durumlarda, örneğin bir hukuk metni olarak kullanılıyor.)


1
Bağlantı noktalarınızın neden SceneMember'i uzatması gerekiyor? neden SceneMembers'te çalışmak üzere port sınıfları oluşturmuyorsunuz?
Michael K,

1
Peki neden standart marker arayüz deseni kullanmıyorsunuz? Temelde boş soyut temel sınıfınızla aynı, ancak çok daha yaygın bir deyimdir.
TMN

1
@Michael: Sadece teorik nedenlerle, gelecekteki kullanım için Port'u ayırdım, ancak bu gelecek henüz gelmedi ve belki de asla gelmeyecek. İsimlerinin aksine, hiçbir ortak yönlerinin olmadığını farketmemiştim. Bu boş sınıfa neden olmuş herhangi bir zararı olan herkese tazminat ödeyeceğim ...
ern0

1
@TMN: SceneMember (türev) tipleri getMemberType () yöntemine sahiptir, SceneMember nesnelerinin alt kümesi için Scene tarandığında birkaç durum vardır.
ern0

4
Bu soruya cevap vermiyor.
Eva
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.