2012-08-26 33 views
5

Đây là câu hỏi rộng và khái niệm một chút.Ngăn chặn một phương thức được gọi trước một phương thức khác

Tôi có một lớp học với nhiều phương pháp khác nhau. Hãy gọi cho họ AB. Làm thế nào tôi có thể đảm bảo rằng các nhà phát triển khác làm việc với lớp này trong tương lai sẽ không gọi phương thức B trước khi gọi phương thức đầu tiên A ít nhất một lần?

Tôi đang làm điều này trong C++ nhưng nói chung cách tốt nhất để thực thi điều này là gì? Tôi đã ngây thơ một số ý tưởng như sử dụng một biến boolean nhưng tôi cũng muốn nghe một số suy nghĩ khác nữa.

+0

bạn không thể thực thi lệnh này (bạn đã có giải pháp được đề cập). Bạn có thể thiết kế lại với mẫu khuôn mẫu và tránh nhu cầu đặc biệt này. http://en.wikipedia.org/wiki/Template_method_pattern – Jayan

Trả lời

10

Một cách để đảm bảo điều này? Làm cho nó trở thành trách nhiệm của phương pháp B để gọi phương thức A một lần.

Bất cứ điều gì khác là API dễ vỡ.

+1

Đây là một ý tưởng hay (+1), Lưu ý rằng bất lợi cho điều này là tất cả thông tin cần thiết để thực hiện cuộc gọi đến A phải được chuyển vào B - điều này có thể buồn bã. (Hãy tưởng tượng cần phải chuyển tất cả dữ liệu kết nối DB của bạn cho mỗi truy vấn ...) –

+0

Ngoài ra "Chỉ có cách" là một IMO mạnh mẽ một chút. –

+0

OK, điểm tốt. –

4

Có biến boolean xác định xem A đã được gọi hay chưa. Sau đó, khi ai đó cố gắng gọi B mà không có biến boolean này được đặt, hãy ném một IllegalStateException.

Hoặc bạn có thể có B chỉ cần gọi A vì có vẻ như nó không thể thực thi mà không có A được gọi là anyways đầu tiên.

Nếu không, và vì cả hai phương pháp đều công khai, thực sự không có cách nào khác để thực thi điều này.

5

Sử dụng boolean là một khởi đầu tốt và việc bật truy cập hoạt động OK.

Tuy nhiên đôi khi rất hay để có thể thực thi điều này lúc biên dịch. Trong trường hợp đó, lựa chọn thực sự duy nhất của bạn là sử dụng một số thủ thuật.

Chỉ tiếp xúc với A trong lớp học của bạn, làm cho nó trở lại một proxy có chứa B.

class MyClass { 
    public: 

    struct BProxy { 
     public: 
     MyClass * root; 
     void B() { root->B(); } 
     protected: 
     BProxy(MyClass * self) : root(self) {}; // Disable construction 
     friend class MyClass; //So that MyClass can construct it 
    }; 

    BProxy A() { ... return BProxy(this); } 
    friend class BProxy; // So that BProxy can call B() 
    protected 
    void B() { ... } 
}; 

int main() { 
    MyClass m; 
    BProxy bp = m.A(); 
    // m.B(); can't do this as it's private - will fail at compile time. 
    bp.B(); // Can do this as we've got the proxy from our previous call to A. 
} 

Bạn cũng có thể đạt được một cái gì đó tương tự như sử dụng thừa kế bảo vệ từ một baseclass thực hiện (hoặc cung cấp một ảo) B().

5

Một cách là thiết kế lại lớp học của bạn một chút khác biệt. Hãy xem xét một lớp cơ sở dữ liệu đơn giản cần được khởi tạo trước khi được sử dụng. Tôi là một anh chàng Java, vì vậy ...

public class Database { 
    public void init(String username, String password) // must call this first! 
    public List<Object> runQuery(String sql) // ... 
} 

Vì vậy, tôi cần phải gọi init trước. Tôi có thể tạo một DatabaseFactory để khởi tạo và trả về đối tượng cơ sở dữ liệu thực tế. Chúng ta có thể ẩn constructor để chỉ có một DatabaseFactory mới có thể tạo một Database (trong Java một lớp lồng nhau, trong C++ một lớp friend có thể?).

public class DatabaseFactory { 
    public Database init(String username, String password) // ... 

    public class Database { 
    private Database() {} 
    public List<Object> runQuery(String sql) // ... 
    } 
} 

Vì vậy, bây giờ tôi phải đi qua Nhà máy để đến đối tượng cơ bản.

DatabaseFactory factory = new DatabaseFactory(); 
Database database = factory.init("username", "password"); // first init (call method A) 
// now I can use database (or B in your case) 
database.runQuery("select * from table"); 
2

Một cách để đảm bảo rằng A được thực hiện trong hàm tạo của lớp. Nếu nhà xây dựng không thành công (ném) thì các nhà phát triển khác không có bất cứ điều gì với những gì để làm điều đó sai số B với. Nếu hàm tạo thành công thì A được thực hiện ít nhất một lần và vì vậy B là hoạt động hợp lệ để thực hiện.

2

Tôi sẽ tạo phương thức "A" cho hàm khởi tạo đối tượng. Điều này đã được gọi một lần để sử dụng đối tượng, được thực thi bởi trình biên dịch.Sau đó bạn có thể gọi một phương thức "B" trong kiến ​​thức rằng một hàm tạo phải được gọi.

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