2010-12-12 40 views
7

Cách tốt nhất để chia sẻ dữ liệu giữa các lớp riêng biệt trong Java là gì? Tôi có một loạt các biến được sử dụng bởi các lớp khác nhau trong các tệp riêng biệt theo các cách khác nhau. Hãy để tôi cố gắng để minh họa cho một phiên bản đơn giản của vấn đề của tôi:Cách chia sẻ dữ liệu giữa các lớp riêng biệt trong Java

Đây là mã của tôi trước đây:

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 
    } 
} 

Bây giờ nó trông giống như sau:

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 
    } 
} 

Vì vậy, dù sao, tôi phải vượt qua x và y mỗi lần (trong đó x, y là các biến được lưu trong lớp helper func)?

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

Ý tưởng của tôi là có một lớp chứa đặc biệt khi x và y được giữ. Lớp cấp cao nhất sẽ có một thể hiện của lớp container và thay đổi x, y bằng cách sử dụng các phương thức set.

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

Lớp trợ giúp của tôi cũng sẽ có một phiên bản của vùng chứa và nó sẽ trỏ đến cùng một trường hợp ở cấp cao nhất. Bằng cách đó họ truy cập cùng một x, y như ở cấp cao nhất.

Tôi muốn biết nếu tôi nên

  • Sử dụng các lớp container
  • tải x, y mỗi lần vào lớp con
  • ?? Một số phương pháp tốt hơn ??
+3

Câu trả lời ở đây là, thật đáng buồn, 'nó phụ thuộc'. programmers.se có thể là một mục tiêu màu mỡ hơn cho câu hỏi này. – bmargulies

+0

Nếu lớp bên trong không tĩnh, sau đó nó có thể truy cập các thành viên lớp cha ... – Vojta

+0

Nó không phải là một lớp bên trong nếu nó trong một tập tin khác nhau. Và nó không phải là một phân lớp nếu nó không mở rộng siêu lớp. – Armand

Trả lời

10

Tôi đoán câu trả lời cho câu hỏi của bạn là Mẫu thiết kế có tên Singleton. Về cơ bản, nó cho phép bạn nhận và khai thác cùng một cá thể (và duy nhất) của một lớp bất cứ khi nào bạn muốn trong hệ thống của bạn.

Đây là việc thực hiện (xin vui lòng tha thứ cho các lỗi cú pháp có thể, tôi không biên dịch nó):

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; 
    } 
} 

sau đó nếu ở nơi khác trong mã của bạn, bạn nhập các container bạn có thể viết ví dụ

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

và bạn sẽ ảnh hưởng đến các thuộc tính của thể hiện vùng chứa duy nhất mà bạn có trong hệ thống của mình

Trong nhiều trường hợp, tốt hơn hết là nên sử dụng Dependency Injec mô hình tion vì nó làm giảm sự ghép nối giữa các thành phần khác nhau.

+0

Rất thú vị. Nó có một biến tĩnh của chính nó. Chỉ cần tự hỏi, làm thế nào điều này đi ra khỏi phạm vi? Nếu nó là tĩnh, nó sẽ không còn tồn tại? Hay tôi đặt nó thành null khi tôi làm xong nó? – f20k

+0

Xin lỗi nhưng tôi đoán tôi đã không hiểu câu hỏi của bạn: (anyway như trường hợp của nó là tĩnh, một khi khởi tạo, nó sẽ vẫn tồn tại. Bạn không cần phải, và bạn có thể không, thiết lập nó để null. các biến của bạn :) Tuy nhiên, đây là giải thích về mẫu http: //en.wikipedia.org/wiki/Singleton_pattern – Sindico

+0

Hmm cũng Singleton sẽ có ý nghĩa nếu tôi chỉ cần khởi tạo nó một lần. Tuy nhiên, chức năng cấp cao nhất của tôi thực sự là một chuỗi sẽ được khởi tạo/hủy nhiều lần trong suốt quá trình thực hiện chương trình. Vâng, tôi cho rằng tôi chỉ có thể ghi đè lên các giá trị mỗi lần. – f20k

0

Tôi gặp khó khăn khi xem vấn đề của bạn là gì - tại sao bạn không muốn chuyển x y như một tham số?

Ồ, tốt. Giả sử bạn không, tôi không thấy cần một lớp container mới. Thực hiện theo cách này:

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()** 
    } 
} 

Tất nhiên bạn cần thêm phương thức getter công cộng getX() và getY() vào Top_Level_Class.

Nếu bạn không muốn SubClass1a phụ thuộc vào Top_Level_Class thì bạn có thể tạo giao diện cung cấp quyền truy cập vào các biến.

+0

Hmm được rồi. Tôi sẽ phải xem xét giao diện nhiều hơn. Lý do chính mà tôi không muốn vượt qua x, y mỗi lần là bởi vì tôi có một vài hàm trong một số SubClasses mà mỗi lần sử dụng (x, y, z, v.v.) và dường như nó không được chuyển thành 6-8 biến thời gian tôi gọi một hàm. Các lớp con được sử dụng để phụ thuộc, nhưng tôi đang cố gắng đưa chúng ra khỏi tệp để chúng có thể được sử dụng trong một dự án khác. – f20k

+1

@ f20k Cảm giác ruột của bạn về việc không muốn truyền 6-8 tham số cho phương pháp đang đi đúng hướng. Các danh sách tham số thường gợi ý rằng bạn nên cân nhắc việc gộp các tham số đó vào một đối tượng hoặc 2. – dhable

+0

@Dan, cảm ơn đề xuất của bạn. Tôi nghĩ rằng tôi sẽ thực hiện một container. Nó làm cho rất nhiều ý nghĩa. Tôi đã chỉ lo lắng rằng nó sẽ là thực hành lập trình xấu nếu tôi chia sẻ dữ liệu theo cách này. – f20k

0

Blockquote Lý do chính tôi không muốn vượt qua x, y mỗi lần là vì tôi có nhiều chức năng trong một số SubClasses mà mỗi lần sử dụng (x, y, z, v.v.) và dường như không đúng vượt qua như 6-8 biến mỗi lần tôi gọi một hàm. Các lớp con được sử dụng để phụ thuộc, nhưng tôi đang cố gắng đưa chúng ra khỏi tệp để chúng có thể được sử dụng trong một dự án khác. Blockquote

Nếu trường hợp này xảy ra thì bạn nên tắt trừu tượng biến của mình thành lớp chứa. Nếu mọi cá thể của các lớp không còn phụ thuộc này sẽ sử dụng một tập hợp con lớn của các biến này thì sẽ có ý nghĩa để có tất cả chúng trong một cá thể. Các biến có liên quan logic phải được tìm thấy ở cùng một vị trí.Cách tiếp cận của bạn nên được một cái gì đó như:

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 
} 

Điều này sẽ giúp bạn nhận được vào một biến qua tình hình mì spaghetti-mã, và khi bạn muốn sử dụng chỉ một hoặc hai trong số các lớp học sau mã của bạn là mô-đun đủ để cảng với chỉ những lớp học và vùng chứa của bạn.

+0

Cú pháp này sai và có vẻ phức tạp hơn đề xuất ban đầu. – Armand

0

Câu hỏi này hơi điên - mã trong câu hỏi sẽ không biên dịch.

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 
} 

Bạn cũng cần xác định ADoerBDoer.

+0

Xin lỗi, mã tôi viết lên đó là để giúp đưa ra ý tưởng về những gì tôi muốn làm. Nó không thực sự hoạt động. Mã thực tế thực sự khá phức tạp với hơn 100 dòng. Về cơ bản tôi cố gắng chia sẻ một số biến rất thường được sử dụng trong lớp top_level_class giữa các lớp trợ giúp trong các tệp riêng biệt. Câu hỏi đặt ra là phương pháp nào là tốt nhất - hiệu quả và khôn ngoan – f20k

Các vấn đề liên quan