SRP'yi uygulamanın pratik yolları nelerdir?


11

Bir sınıfın tek sorumluluk ilkesini ihlal edip etmediğini kontrol etmek için insanların kullandıkları pratik teknikler nelerdir?

Bir sınıfın değişmek için tek bir nedeni olması gerektiğini biliyorum, ama bu cümlenin bunu uygulamak için pratik bir yolu eksik.

Bulduğum tek yol "......... gerekir ......... kendisi" cümlesini kullanmaktır . burada birinci alan sınıf adı ve daha sonra yöntem (sorumluluk) adıdır.

Bununla birlikte, bazen bir sorumluluğun SRP'yi gerçekten ihlal edip etmediğini anlamak zordur.

SRP'yi kontrol etmenin başka yolları var mı?

Not:

Soru, SRP'nin ne anlama geldiği değil, SRP'yi kontrol etmek ve uygulamak için pratik bir yöntem veya bir dizi adım ile ilgilidir.

GÜNCELLEME

Rapor sınıfı

SRP'yi açıkça ihlal eden bir örnek sınıf ekledim. İnsanların tek sorumluluk ilkesine nasıl yaklaştıklarını açıklamak için bunu örnek olarak kullanmaları harika olurdu.

Örnek buradan .


Bu ilginç bir kuraldır, ama yine de şöyle yazabilirsiniz: "Bir Kişi Sınıfı Kendini İşleyebilir". GUI'yi iş kurallarını içeren aynı sınıfa dahil etmek ve veri kalıcılığını sağlamak doğru olmadığından, bu SRP için bir ihlal olarak kabul edilebilir. Bu yüzden mimari alanlar (katmanlar ve katmanlar) kavramını eklemeniz ve bu ifadenin yalnızca bu
alanlardan 1iyle

@EmmadKareem Bu kural Baş Nesneye Yönelik Analiz ve Tasarımda belirtilmiştir ve bu konuda tam olarak düşündüm. Uygulamanın pratik bir yolu yok. Sorumlulukların bazen tasarımcı için aşikar olmayacağını ve yöntemin gerçekten bu sınıfta olması gerekip gerekmediğini yargılamak için büyük bir sağduyu kullanması gerektiğini belirttiler.
Songo

SRP'yi gerçekten anlamak istiyorsanız, Bob Amca'nın bazı yazılarını okuyun. Onun kodu gördüğüm en güzel bazıları ve SRP hakkında söylediklerinin sadece sağlam bir tavsiye değil, aynı zamanda sadece el sallamaktan daha fazlası olduğuna inanıyorum.
Robert Harvey

Ve aşağı seçmen, görevin neden iyileştirileceğini açıklar mı ?!
Songo

Yanıtlar:


7

SRP, belirsiz bir ifadeyle, bir sınıfın değişmek için sadece bir sebebi olması gerektiğini belirtir.

Sorudaki "rapor" sınıfının yeniden yapılandırılmasının üç yöntemi vardır:

  • printReport
  • getReportData
  • formatReport

ReportHer yöntemde kullanılan fazlalığı göz ardı ederek , bunun neden SRP'yi ihlal ettiğini görmek kolaydır:

  • "Yazdır" terimi bir tür kullanıcı arayüzü veya gerçek bir yazıcı anlamına gelir. Dolayısıyla bu sınıf bir miktar kullanıcı arayüzü veya sunum mantığı içerir. Kullanıcı arayüzü gereksinimlerindeki bir değişiklik, Reportsınıfta bir değişiklik yapılmasını gerektirecektir .

  • "Veri" terimi bir tür veri yapısını ifade eder, fakat gerçekten ne olduğunu (XML? JSON? CSV?) Belirtmez. Ne olursa olsun, raporun "içeriği" hiç değişmezse, bu yöntem de değişecektir. Bir veritabanına veya etki alanına bağlantı var.

  • formatReportgenel olarak bir yöntem için korkunç bir isim, ancak bir kez daha UI ile ilgili bir şey olduğunu ve muhtemelen UI'nin farklı bir yönüne sahip olduğunu düşünerek varsayıyorum printReport. Yani, başka, ilgisiz bir değişiklik nedeni.

Yani bu bir sınıf muhtemelen bir veritabanı, bir ekran / yazıcı aygıtı ve günlükler veya dosya çıktısı ya da ne için dahili biçimlendirme mantığı ile birleştirilir. Bir sınıftaki her üç işlevin de bulunmasıyla, bağımlılık sayısını çoğaltırsınız ve herhangi bir bağımlılık veya gereksinim değişikliğinin bu sınıfı (veya buna bağlı başka bir şeyi) kırma olasılığını üç katına çıkarırsınız.

Buradaki sorunun bir kısmı, özellikle dikenli bir örnek seçmiş olmanızdır. Muhtemelen Reportsadece bir şey yapsa bile denilen bir sınıfınız olmamalı , çünkü ... hangi rapor? Tüm "raporlar", farklı verilere ve farklı gereksinimlere dayalı olarak tamamen farklı hayvanlar değil mi? Ve rapor , ekran veya yazdırma için zaten biçimlendirilmiş bir şey değil mi?

Ancak, geçmişe bakmak ve varsayımsal bir somut ad oluşturmak - buna IncomeStatement(çok yaygın bir rapor) diyelim - uygun bir "SRPed" mimarisinin üç tipi olacaktır:

  • IncomeStatement- biçimlendirilmiş raporlarda görünen bilgileri içeren ve / veya hesaplayan alan ve / veya model sınıfı .

  • IncomeStatementPrintergibi bir standart arayüz uygular IPrintable<T>. Bir anahtar yönteme Print(IncomeStatement)ve belki de baskıya özgü ayarları yapılandırmak için başka yöntemlere veya özelliklere sahiptir.

  • IncomeStatementRenderer, ekran görüntülemeyi işler ve yazıcı sınıfına çok benzer.

  • Sonunda IncomeStatementExporter/ gibi daha fazla özelliğe özgü sınıf da ekleyebilirsiniz IExportable<TReport, TFormat>.

Bu, jenerikler ve IoC kaplarının tanıtımı ile modern dillerde önemli ölçüde kolaylaştırılmıştır. Uygulama kodunuzun çoğunun belirli IncomeStatementPrintersınıfa dayanması gerekmez IPrintable<T>, herhangi bir yazdırılabilir rapor kullanabilir ve bu şekilde çalışabilir , bu da size Reportbir printyöntemle bir temel sınıfın algılanan tüm avantajlarını verir ve her zamanki SRP ihlallerinden hiçbirini vermez . Gerçek uygulamanın, IoC konteynır kaydında yalnızca bir kez bildirilmesi gerekir.

Bazı insanlar, yukarıdaki tasarımla karşı karşıya kaldıklarında, şöyle bir şeyle yanıt verirler: "ancak bu prosedürel koda benziyor ve OOP'un tamamı, bizi veri ve davranışın ayrılmasından uzaklaştırmaktı!" Dediğim: yanlış .

IncomeStatementOlduğu değil sadece "veri" şeklinde ve yine hata ki içine ilgisiz işlevselliği her türlü parazit başlamak sonradan böyle bir "saydam" sınıfı yaratarak bir şey yanlış yapıyorsun ve hissetmek cepten millet bir sürü sebep budur IncomeStatementki (iyi ve genel tembellik). Bu sınıf sadece veri olarak başlayabilir , ancak zamanla garantili olarak daha fazla model olarak ortaya çıkacaktır .

Örneğin, gerçek gelir tablosunda toplam gelirler , toplam giderler ve net gelir çizgileri bulunur. Düzgün tasarlanmış bir finansal sistem büyük olasılıkla bunları depolamayacaktır çünkü bunlar işlemsel veriler değildir - aslında, yeni işlem verilerinin eklenmesine bağlı olarak değişirler. Ancak, raporu yazdırıyor, oluşturuyor veya dışa aktarıyor olsanız da, bu satırların hesaplanması her zaman tam olarak aynı olacaktır. Senin Yani IncomeStatementsınıf şeklinde kendisine davranışın adil bir miktarına sahip olacak getTotalRevenues(), getTotalExpenses()ve getNetIncome()yöntemlerle ve muhtemelen birkaç diğerleri. Gerçekten fazla bir şey yapmıyor gibi görünse bile, kendi davranışı olan gerçek bir OOP tarzı nesnedir.

Ancak formatve printyöntemleri, bilginin kendisiyle hiçbir ilgisi yoktur. Aslında, bu yöntemlerle ilgili birkaç uygulama yapmak istemeniz pek olası değildir , örneğin yönetim için ayrıntılı bir açıklama ve hissedarlar için o kadar ayrıntılı olmayan bir açıklama. Bu bağımsız işlevleri farklı sınıflara ayırmak, tek bir boyuta uyan tüm print(bool includeDetails, bool includeSubtotals, bool includeTotals, int columnWidth, CompanyLetterhead letterhead, ...)yöntemin yükü olmadan çalışma zamanında farklı uygulamaları seçebilmenizi sağlar . Yuck!

Umarım yukarıdaki, büyük ölçüde parametrelendirilmiş yöntemin nerede yanlış gittiğini ve ayrı uygulamaların nerede doğru gittiğini görebilirsiniz; tek nesne durumunda, yazdırma mantığına her yeni kırışıklık eklediğinizde, etki alanı modelinizi değiştirmeniz gerekir ( Finanstaki Tim sayfa numaralarını ister, ancak yalnızca dahili raporda, bunu ekleyebilir misiniz? ) bunun yerine bir veya iki uydu sınıfına bir yapılandırma özelliği eklemek yeterlidir.

SRP'yi doğru şekilde uygulamak bağımlılıkları yönetmekle ilgilidir . Bir sınıf zaten yararlı bir şeyler yapar ve (bir UI, yazıcı bir ağ, bir dosya, ne olursa olsun gibi) yeni bir bağımlılık getirecek başka bir yöntemi ekleyerek düşünüyorsanız Özetle, yok . Bunun yerine bu işlevselliği yeni bir sınıfa nasıl ekleyebileceğinizi ve bu yeni sınıfı genel mimarinize nasıl sığdırabileceğinizi düşünün (bağımlılık enjeksiyonunu tasarlarken oldukça kolaydır). Genel ilke / süreç budur.


Yan not: Robert gibi, SRP uyumlu bir sınıfın yalnızca bir veya iki durum değişkenine sahip olması gerektiği fikrini açıkça reddediyorum. Böyle ince bir ambalajın nadiren gerçekten yararlı bir şey yapması beklenebilir. Yani bununla aşırıya kaçmayın.


+1 büyük cevap gerçekten. Ancak, sadece sınıf hakkında kafam karıştı IncomeStatement. Önerdiğiniz tasarım olduğunu anlamına mı geliyor IncomeStatementörneklerini olacak IncomeStatementPrinterve IncomeStatementRendererbu yüzden çağırdığınızda o print()üzerine IncomeStatementkendisine çağrı devredeceğini IncomeStatementPrinteryerine?
Songo

@Songo: Kesinlikle hayır! SOLID'i takip ediyorsanız döngüsel bağımlılıklarınız olmamalıdır. Görünüşe göre cevabım, IncomeStatementsınıfın bir yöntem, yöntem veya doğrudan rapor verilerinin kendisini denetlemek veya işlemekle ilgilenmeyen başka bir yöntemi olmadığını yeterince netleştirmedi . Diğer sınıflar bunun için. Birini yazdırmak istiyorsanız , kapta kayıtlı olan arabirime bağımlı olursunuz . printformatIPrintable<IncomeStatement>
Aaronaught

ne demek istediğini anlıyorum. Ancak, sınıfta bir örnek enjekte edersem döngüsel bağımlılık nerede ? Hayal ettiğim gibi, onu çağırdığımda temsilci seçeceğim . Bu yaklaşımla ilgili sorun nedir? ... Başka bir soru, veritabanından veya bir XML dosyasından okunmasını istiyorsanız, verileri yükleyen yöntemi ayıklamak gerekir, biçimlendirilmiş raporlarda görünen bilgileri içermesi gerektiğini söyledi ayrı bir sınıfa aktarın ve çağrıyı devredin mi? PrinterIncomeStatementIncomeStatement.print()IncomeStatementPrinter.print(this, format)IncomeStatementIncomeStatement
Songo

@Songo: Sen IncomeStatementPrinterbağlı IncomeStatementve IncomeStatementbağlı IncomeStatementPrinter. Bu döngüsel bir bağımlılık. Ve bu sadece kötü tasarım; IncomeStatementbir Printerveya hakkında bir şey bilmek için hiçbir neden yoktur IncomeStatementPrinter- bu bir etki alanı modelidir, yazdırma ile ilgilenmez ve başka bir sınıfın oluşturabileceği veya edinebildiği için delegasyon anlamsızdır IncomeStatementPrinter. Etki alanı modelinde herhangi bir yazdırma fikrine sahip olmak için iyi bir neden yoktur.
Aaronaught

Yüklediğiniz nasıl gelince IncomeStatementveritabanı (veya XML dosyası) - tipik olarak bir depo ve / veya eşleyicisinde, alanadi tarafından işlenir oldu ve bir kez daha, bu yetki de yok içinde etki; başka bir sınıfın bu modellerden birini okuması gerekiyorsa, o depoyu açıkça ister . Aktif Kayıt modelini uygulamadığınız sürece sanırım, ama ben gerçekten hayran değilim.
Aaronaught

2

SRP'yi kontrol etme yöntemim, bir sınıfın her yöntemini (sorumluluğunu) kontrol etmek ve aşağıdaki soruyu sormaktır:

"Bu işlevi uygulama şeklimi değiştirmem gerekecek mi?"

Farklı şekillerde (bir yapılandırma veya koşul türüne bağlı olarak) uygulayacağım bir işlev bulursam, bu sorumluluğu yerine getirmek için ekstra bir sınıfa ihtiyacım olduğunu kesin olarak biliyorum.


1

İşte Nesne Jimnastiği'nin 8. kuralından bir alıntı :

Çoğu sınıf tek bir durum değişkenini işlemekten sorumlu olmalıdır, ancak iki tane gerektirecek birkaç tane vardır. Bir sınıfa yeni bir örnek değişkeni eklemek derhal o sınıfın uyumunu azaltır. Genel olarak, bu kurallar altında programlama yaparken, tek bir örnek değişkeninin durumunu koruyanlar ve iki ayrı değişkeni koordine eden iki tür sınıf olduğunu göreceksiniz. Genel olarak, iki tür sorumluluğu karıştırmayın

Bu (biraz idealistc) görünüm göz önüne alındığında, yalnızca bir veya iki durum değişkeni içeren herhangi bir sınıfın SRP'yi ihlal etme olasılığının düşük olduğunu söyleyebilirsiniz. Ayrıca, ikiden fazla durum değişkenlerini içeren herhangi bir sınıf olduğunu söyleyebiliriz olabilir SRP ihlal etmektedir.


2
Bu görüş umutsuzca basittir. Einstein'ın ünlü ama basit denklemi bile iki değişken gerektirir.
Robert Harvey

OP sorusu " SRP'yi kontrol etmenin başka yolları var mı?" - bu olası bir göstergedir. Evet basittir ve her durumda dayanmaz, ancak SRP'nin ihlal edildiğini kontrol etmenin olası bir yoludur.
MattDavey

1
Değişmez duruma karşı değişmez şüpheli de önemli bir husustur
jk.

Kural 8, sistemi umutsuzca karmaşık, anlaşılmaz ve sürdürülemez hale getiren binlerce ve binlerce sınıfa sahip tasarımlar oluşturmak için mükemmel süreci açıklar. Ancak artı tarafı, SRP'yi takip etmenizdir.
Dunk

@Dunk Sana katılmıyorum, ama bu tartışma tamamen konu dışı bir konu.
MattDavey

1

Bir olası uygulama (Java'da). Dönüş türleriyle özgürlükler aldım ama her şeyden önce soruyu cevapladığını düşünüyorum. TBH Rapor sınıfının arabiriminin bu kadar kötü olduğunu düşünmüyorum, ancak daha iyi bir ad sıralı olabilir. Muhafız ifadelerini ve kısalık konusundaki iddiaları dışladım.

EDIT: Ayrıca sınıf değişmez olduğunu dikkat edin. Yani bir kez yaratıldığında hiçbir şeyi değiştiremezsiniz. Bir setFormatter () ve setPrinter () ekleyebilir ve çok fazla sorunla karşılaşamazsınız. IMHO'nun anahtarı, somutlaştırıldıktan sonra ham verileri değiştirmemektir.

public class Report
{
    private ReportData data;
    private ReportDataDao dao;
    private ReportFormatter formatter;
    private ReportPrinter printer;


    /*
     *  Parameterized constructor for depndency injection, 
     *  there are better ways but this is explicit.
     */
    public Report(ReportDataDao dao, 
        ReportFormatter formatter, ReportPrinter printer)
    {
        super();
        this.dao = dao;
        this.formatter = formatter;
        this.printer = printer;
    }

    /*
     * Delegates to the injected printer.
     */
    public void printReport()
    {
        printer.print(formatReport());
    }


    /*
     * Lazy loading of data, delegates to the dao 
     * for the meat of the call.
     */
    public ReportData getReportData()
    {
        if (reportData == null)
        {
            reportData = dao.loadData();
        }
        return reportData;
    }

    /*
     * Delegate to the formatter for formatting 
     * (notice a pattern here).
     */
    public ReportData formatReport()
    {
        formatter.format(getReportData());
    }
}

Uygulama için teşekkürler. Benim 2 şeyim var, if (reportData == null)sanırım databunun yerine demek istediğin gibi . İkincisi, u nasıl bu uygulamaya geldi bilmek umuyordum. Bunun gibi tüm çağrıları neden diğer nesnelere devretmeye karar verdiniz. Her zaman merak ettiğim bir şey daha var: Kendini yazdırmak bir raporun sorumluluğu gerçekten mi ?! Neden yapıcısını printeralan ayrı bir sınıf yaratmadınız report?
Songo

Evet, reportData = data, bunun için üzgünüm. Yetki devri, bağımlılıkların ayrıntılı denetimine izin verir. Çalışma zamanında, her bileşen için alternatif uygulamalar sağlayabilirsiniz. Artık bir HtmlPrinter, PdfPrinter, JsonPrinter, vb. Sahip olabilirsiniz. Bu, aynı zamanda test için de kullanışlıdır, çünkü delege edilmiş bileşenlerinizi tek başına test edebilir ve yukarıdaki nesneye entegre edebilirsiniz. Yazıcı ve rapor arasındaki ilişkiyi kesinlikle tersine çevirebilirsiniz, sadece sağlanan sınıf arayüzü ile çözüm sağlamanın mümkün olduğunu göstermek istedim. Eski sistemler üzerinde çalışmak bir alışkanlık. :)
Heath Lilley

hmmmm ... Yani sistemi sıfırdan inşa ediyor olsaydınız, hangi seçeneği alırdınız? Bir Printerrapor veya sürer sınıf Reportbir yazıcı alır sınıfı? Daha önce bir raporu ayrıştırmam gerektiğinde benzer bir sorunla karşılaştım ve bir rapor alan bir ayrıştırıcı oluşturmamız gerektiğinde veya raporun içinde bir ayrıştırıcı bulunup bulunmadığı ve parse()çağrıyı devredip devretmediği konusunda TL ile tartıştım .
Songo

Daha sonra gerekirse ... printer.print (rapor) başlatmak ve report.print () yapmak istiyorum. Printer.print (report) yaklaşımı ile ilgili en güzel şey, yeniden kullanılabilir olmasıdır. Sorumluluğu ayırır ve ihtiyaç duyduğunuz yerlerde kolaylık yöntemlerine sahip olmanızı sağlar. Belki sisteminizdeki diğer nesnelerin ReportPrinter hakkında bilgi sahibi olmasını istemezsiniz, bu nedenle bir sınıfta print () yöntemine sahip olarak rapor yazdırma mantığınızı dış dünyadan yalıtan bir çekim düzeyi elde edersiniz. Bu hala dar bir değişim vektörüne sahiptir ve kullanımı kolaydır.
Heath Lilley

0

Örneğinizde, SRP'nin ihlal edildiği açık değildir. Belki de rapor nispeten basitse kendisini biçimlendirip yazdırabilmelidir:

class Report {
  void format() {
     text = text.trim();
  }

  void print() {
     new Printer().write(text);
  }
}

Yöntemler o kadar basit ki, sahip olmak ReportFormatterya da ReportPrintersınıflar için mantıklı değil . Arayüzdeki tek göze çarpan problem, getReportDatadeğer olmayan nesneye sorma isteğini ihlal etmesidir.

Öte yandan, yöntemler çok karmaşıksa veya bir biçimi biçimlendirmek veya yazdırmak için birçok yol varsa Report, sorumluluğu devretmek mantıklıdır (ayrıca daha test edilebilir):

class Report {
  void format(ReportFormatter formatter) {
     text = formatter.format(text);
  }

  void print(ReportPrinter printer) {
     printer.write(text);
  }
}

SRP, felsefi bir kavram değil, bir tasarım ilkesidir ve bu nedenle üzerinde çalıştığınız asıl koda dayanır. Anlamsal olarak, bir sınıfı istediğiniz kadar sorumluluklara bölebilir veya gruplandırabilirsiniz. Bununla birlikte, pratik bir ilke olarak, SRP, değiştirmeniz gereken kodu bulmanıza yardımcı olmalıdır . SRP'yi ihlal ettiğiniz belirtileri:

  • Sınıflar o kadar büyüktür ki, kaydırma veya doğru yöntemi aramak için zaman kaybedersiniz.
  • Sınıflar çok küçüktür ve aralarında atlama veya doğru olanı bulmak için zaman harcıyorsunuz.
  • Bir değişiklik yapmak zorunda kaldığınızda, bu kadar çok sınıfı etkiler, takip edilmesi zordur.
  • Bir değişiklik yapmanız gerektiğinde, hangi sınıfların değişmesi gerektiği belirsizdir.

Bunları adları iyileştirerek, benzer kodu birlikte gruplandırarak, çoğaltmayı ortadan kaldırarak, katmanlı bir tasarım kullanarak ve sınıfları gerektiği gibi böldüğünde / birleştirerek bunları yeniden düzenleyerek düzeltebilirsiniz. SRP'yi öğrenmenin en iyi yolu, bir kod tabanına daldırmak ve ağrıyı uzaklaştırmaktır.


Gönderiye eklediğim örneği kontrol edebilir ve cevabınızı buna göre hazırlayabilir miyim?
Songo

Güncellenmiş. SRP bağlama bağlıdır, tüm bir sınıfı (ayrı bir soruda) yayınlarsanız açıklamak daha kolay olacaktır.
Garrett Hall

Güncelleme için teşekkürler. Yine de bir soru, Kendini yazdırmak gerçekten bir raporun sorumluluğu mudur ?! Neden yapıcısında rapor alan ayrı bir yazıcı sınıfı oluşturmadınız?
Songo

Ben sadece SRP dogmatik olarak uygulamak gerekir kodun kendisine bağlıdır diyorum.
Garrett Hall

evet anladım. Fakat sistemi sıfırdan inşa etseydiniz, hangi seçeneği alırdınız? Bir Printerrapor veya sürer sınıf Reportbir yazıcı alır sınıfı? Çoğu zaman kodun karmaşık olup olmadığını anlamaya başlamadan önce böyle bir tasarım sorusuyla karşı karşıya kaldım.
Songo

0

Tek Sorumluluk İlkesi , uyum kavramıyla büyük ölçüde bağlantılıdır . Oldukça uyumlu bir sınıfa sahip olmak için, sınıfın örnek değişkenleri ve yöntemleri arasında ortak bağımlılığa sahip olmanız gerekir; yani, yöntemlerin her biri mümkün olduğunca çok sayıda örnek değişkeni üzerinde işlem yapmalıdır. Bir yöntem ne kadar çok değişken kullanırsa sınıfına o kadar bağlı olur; maksimum uyum genellikle ulaşılamaz.

Ayrıca, SRP'yi iyi uygulamak için iş mantığı alanını iyi anlarsınız; her soyutlamanın ne yapması gerektiğini bilmek. Katmanlı mimari, her katmanın belirli bir şey yapmasını sağlayarak SRP ile de ilişkilidir (Veri Kaynağı Katmanı veri sağlamalıdır vb.).

Yöntemleriniz tüm değişkenleri kullanmasa bile kaynaşmaya geri dönersek, bunlar birleştirilmelidir:

public class MyClass {
    private Type1 var1;
    private Type2 var2;
    private Type3 var3;

    public Type3 method1() {
        //use var1 and var3
    }  

    public void method2() {
        //use var1 and var2
    }

    public Type1 method3() {
        //use var2 and var3
    }
}

Örnek değişkenlerinin bir kısmının yöntemlerin bir bölümünde kullanıldığı ve değişkenlerin diğer kısmının yöntemlerin diğer bölümünde kullanıldığı aşağıdaki kod gibi bir şey olmamalıdır (burada iki sınıfınız olmalıdır. değişkenlerin her bir parçası).

public class MyClass {
    private Type1 var1;
    private Type2 var2;
    private Type3 var3;
    private TypeA varA;
    private TypeB varB;

    public Type3 method1() {
        //use var1 and var3
    }  

    public void method2() {
        //use var1 and var2
    }

    public TypeA methodA() {
        //use varA and varB
    }

    public TypeA methodB() {
        //use varA
    }
}
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.