2010-12-12 21 views
7

Java'da ayrı sınıflar arasında veri paylaşmanın en iyi yolu nedir? Farklı sınıflar tarafından farklı dosyalarda farklı şekillerde kullanılan bir dizi değişkenim var. benim sorunun basitleştirilmiş bir sürümünü göstermek için çalışalım:Java'da ayrı sınıflar arasında veri nasıl paylaşılır

Bu önce benim kod: Ben geçmelidir, Neyse

public class Top_Level_Class(){ 
    int x, y; 
    SomeClass1a a = new SomeClass1a(); 
    SomeClass1a b = new SomeClass1b(); 
    // gets user input which changes x, y; 
    public void main(){ 
     int p, q, r, s; 
     // compute p, q, r, s 
     a.doA(p,q,r); 
     b.doB(q,r,s); 
    } 

public class SomeClass1a() { // in its own separate file 
    public void doA(int p, int q, int r){ 
     // do something that requires x,y and p, q, r 
    } 
} 


public class SomeClass1b() { // in its own separate file 
    public void doB(int q, int r, int s){ 
     // does something else that requires x, y and q, r, s 
    } 
} 

:

public class Top_Level_Class(){ 
    int x, y; 

    // gets user input which changes x, y; 
    public void main(){ 
     int p, q, r, s; 
     // compute p, q, r, s 
     doA(p,q,r); 
     doB(q,r,s); 
    } 

    public void doA(int p, int q, int r){ 
     // do something that requires x,y and p, q, r 
    } 

    public void doB(int q, int r, int s){ 
     // does something else that requires x, y and q, r, s 
    } 
} 

Şimdi şuna benzer x ve y her seferinde (x, y, helpc sınıfı func'de saklanan değişkenlerdir)?

a.set(x,y); 
a.doA(p,q,r); 

Fikrim, x ve y'nin tutulduğu özel bir kapsayıcı sınıfına sahip olmaktı. Üst düzey sınıf, kap sınıfının bir örneğine sahip olacak ve set yöntemlerini kullanarak x, y değerini değiştirecektir.

// in the top level class: 
Container c = new Container(x,y); 
a.setContainer(c); 
b.setContainer(c); 

My yardımcı sınıflar da kabın bir örneğini olurdu ve üst düzeyde aynı örneğine işaret olacaktır. Bu şekilde, aynı x, y'ye üst seviyedeki gibi erişirler.

I

  • alt sınıfları
  • içine kap sınıf
  • Yük x, y, her zaman kullanım gerekir bilmek isteyen ?? Bazı daha iyi bir yöntem?
+3

Buradaki cevap, ne yazık ki, 'bağlıdır'. programmers.se bu soru için daha verimli bir hedef olabilir. – bmargulies

+0

İç sınıf statik değilse, ana sınıf üyelerine de erişebilir ... – Vojta

+0

Farklı bir dosyada bulunuyorsa, bu bir iç sınıf değil. Ve eğer süper sınıfı genişletmezse, bir alt sınıf değildir. – Armand

cevap

10

Sorunun yanıtı, Tekton adı verilen Tasarım Kalıbıdır. Temel olarak sisteminizde istediğiniz zaman bir sınıfın aynı (ve benzersiz) örneğini almanıza ve istismar etmenize izin verir.

Bu

(mümkünse sözdizimi hatalarını affet bunu derlemek vermedi lütfen) kendi uygulamasıdır:

sonra
class Container{ 

    //eventually provides setters and getters 
    public float x; 
    public float y; 
    //------------ 

    private static Container instance = null; 
    private void Container(){ 

    } 
    public static Container getInstance(){ 
    if(instance==null){ 
     instance = new Container(); 
     } 
     return instance; 
    } 
} 

başka yerde kodunuzda Eğer örneğin yazabilirsiniz Kapsayıcı içe eğer

Container.getInstance().x = 3; 
temp = Container.getInstance().x; 

ve sisteminizdeki benzersiz kapsayıcı örneğinin özelliklerini etkileyeceksiniz

Çoğu durumda Bağımlılık Enjecini kullanmak daha iyidir. Bu, farklı bileşenler arasındaki bağlantıyı azaltır.

+0

Çok ilginç. Kendisinin statik bir değişkeni vardır. Sadece merak ediyorum, bu şey kapsam dışında nasıl gidiyor? Statik ise, varlığını sürdürmeyecek mi? Ya da işim bittiğinde null olarak ayarlı mıyım? – f20k

+0

Üzgünüm ama sanırım şu soruyu anlamadım: (örneğin, bir kere başlatıldığında, statik olarak kalıyor, varoluşta kalmaya devam edecek. Sen zorunda değilsin ve bunu yapamazsın, onu boş olarak ayarla. Değişkenlerinizin :) Buradaki Desen http: //en.wikipedia'nin bir açıklaması.org/wiki/Singleton_pattern – Sindico

+0

Hmm, tek seferde sadece bir kez başlatmaya ihtiyacım varsa, Singleton mantıklı olacaktır. Ancak, üst düzey işlevim aslında program yürütme sırasında birkaç kez başlatılacak/yok olacak bir iş parçacığıdır. Sanırım her seferinde değerlerin üzerine yazabilirim. – f20k

0

Sorunun ne olduğunu görmek için zor bir zaman geçiriyorum - neden bir parametre olarak x y'yi geçmek istemiyorsunuz?

Oh, peki. Anlamıyorsan, yeni bir konteyner sınıfına ihtiyacım yok. bu şekilde yapın: Elbette

public class SubClass1a() { // in its own separate file 
    public void doA(Top_Level_Class caller, int p, int q, int r){ 
     // do something that requires x,y and p, q, r 
     // **to get x use the expression term caller.getX() and caller.getY()** 
    } 
} 

toplu alıcı yöntemleri GetX() ve Top_Level_Class için getY() eklemeniz gerekir.

SubClass1a'nın Top_Level_Class'a bağımlı olmasını istemiyorsanız, değişkenlere erişim sağlayan bir arabirim oluşturabilirsiniz. Her kullanım (x, y, z, vs) ve doğru görünmüyordu Birkaç alt çeşitli işlevleri var çünkü

+0

Hmm tamam. Arayüzlere daha fazla bakmam gerekecek. X'i geçmek istemediğim ana sebep, her defasında, her bir kullanımın (x, y, z, vb.) Ve her biri 6-8 değişken gibi geçmek için pek çok alt fonksiyonda birkaç fonksiyona sahip olduğumdan kaynaklanmaktadır. zaman bir fonksiyon çağırırım. Alt sınıflar bağımlıydılar, ancak onları farklı bir projede kullanabilmeleri için dosyadan çıkarmaya çalışıyorum. – f20k

+1

@ f20k Bir yönteme 6-8 parametreyi geçmek istemediğinize dair hissiniz doğru yolda. Bu parametrelerin, genellikle bu parametreleri bir nesneye veya 2. – dhable

+0

@ Dan'a aktarmayı düşünmeniz gerektiğini ima ettiğine dair ipucu, öneriniz için teşekkür ederiz. Galiba bir konteyner yapacağım. Çok mantıklı. Verileri bu şekilde paylaşırsam kötü programlama pratiği olacağından endişeliydim. – f20k

0

Blockquote ben x geçmek istemediğini temel nedeni, y her zaman olduğu Her fonksiyonumda 6-8 değişken gibi geçiyorum. Alt sınıflar bağımlıydılar, ancak onları farklı bir projede kullanabilmeleri için dosyadan çıkarmaya çalışıyorum. Blockquote

Bu durumda, değişkenlerinizi bir kapsayıcı sınıfına ayırmaktan daha iyi olursunuz. Artık bu bağımlı olmayan sınıfların her örneği, bu değişkenlerin büyük bir alt kümesini kullanacaksa, bunların hepsini tek bir durumda olması mantıklıdır. Mantıksal olarak ilgili değişkenler aynı yerde bulunmalıdır.Bu değişken geçen spagetti kod durumdan girmesini tutar

public class Top_Level_Class(){ 
Container container = new Container(x, y, p, q, r, s); 
SubClass1a a = new SubClass1a(container); 
SubClass1a b = new SubClass1b(container); 
// gets user input which changes x, y using container's getters and setters 
public void main(){ 
    // compute and set p, q, r, s 
    a.doA(); 
    b.doB(); 
} 

public class SubClass1a(Container c) { // in its own separate file 
    public void doA(c.getX, c.getY, c.getP, c.getQ, c.getR){ 
     // do something that requires x, y, p, q, and r 
    } 
} 

public class SubClass1b(Container c) { // in its own separate file 

    public void doB(c.getX, c.getY, c.getQ, c.getR, c.getS){ 
     // does something else that requires x, y, q, r, and s 
    } 
} 

public class Container(x, y, p, q, r, s) { 
    //getters and setters for all variables 
} 

ve sadece birini veya bu sınıfların ikisini kullanmak istediğinizde daha sonra kod ile limana kadar modüler: bir şey gibi yaklaşımınız olmalıdır sadece bu sınıflar ve konteyneriniz.

+0

Bu sözdizimi yanlış ve orijinal öneriden daha karmaşık görünüyor. – Armand

0

Bu soru biraz sinirli - sorudaki kod derlenmeyecek.

public class Main { 
    public static void main(String... args) { 
     MutableDataContainer m = new MutableDataContainer(); 
     ImmutableDataContainer i = computeImmutableData(); 
     new ADoer().doA(m, i); 
     new BDoer().doB(m, i); 
    } 
    ... 
} 

class MutableDataContainer { 
    private int x, y; 
    ... // getters and setters below 
} 

class ImmutableDataContainer { 
    private final int p, q, r, s; 
    ... // getters below 
} 

Sen ADoer ve BDoer olarak belirsiz gerekir.

+0

Üzgünüm, yazdığım kod, ne yapmak istediğime dair bir fikir vermek için var. Aslında çalışmıyor. Gerçek kod aslında 100+ satırlarla oldukça karmaşıktır. Temel olarak, top_level_class içinde çok sık kullanılan bazı değişkenleri ayrı dosyalardaki yardımcı sınıflar arasında paylaşmaya çalışıyorum. Soru, hangi yöntemin en iyi - verimli ve akıllıca olduğudır. – f20k

İlgili konular