Java 防止一个方法在另一个方法之前被调用
这是一个有点宽泛和概念性的问题 我有一个包含各种方法的类。让我们称它们为Java 防止一个方法在另一个方法之前被调用,java,c++,methods,call,Java,C++,Methods,Call,这是一个有点宽泛和概念性的问题 我有一个包含各种方法的类。让我们称它们为A和B。如何确保将来使用该类的其他开发人员在至少一次调用方法A之前不会调用方法B 我在C++中做这个,但是一般来说,执行这个最好的方法是什么?我有一些天真的想法,比如使用布尔变量,但我也想听听其他想法。有一种方法可以保证这一点吗?让方法B负责调用方法A一次 其他任何东西都是脆弱的API。有一个布尔变量,用于确定是否调用了a。然后,当有人试图在未设置此布尔变量的情况下调用B时,抛出IllegalStateException 或
A
和B
。如何确保将来使用该类的其他开发人员在至少一次调用方法A之前不会调用方法B
我在C++中做这个,但是一般来说,执行这个最好的方法是什么?我有一些天真的想法,比如使用布尔变量,但我也想听听其他想法。有一种方法可以保证这一点吗?让方法B负责调用方法A一次
其他任何东西都是脆弱的API。有一个布尔变量,用于确定是否调用了
a
。然后,当有人试图在未设置此布尔变量的情况下调用B
时,抛出IllegalStateException
或者您可以让B
简单地调用A
,因为它似乎无法在没有先调用A
的情况下执行
否则,由于这两种方法都是公共的,因此实际上没有其他方法来实施这一点。使用布尔值是一个良好的开端,启用access也可以 然而,有时能够在编译时强制执行这一点很好。在这种情况下,你唯一的选择就是使用一些技巧 仅在类中公开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()的基类的受保护继承来实现类似的功能。一种方法是以稍微不同的方式重新设计类。考虑一个简单的数据库类,在使用之前需要初始化。我是爪哇人,所以
public class Database {
public void init(String username, String password) // must call this first!
public List<Object> runQuery(String sql) // ...
}
一种保证方法是在类的构造函数中完成
A
。如果构造函数失败(抛出),那么其他开发人员就不知道该怎么做了。如果构造函数成功,那么A
至少执行一次,因此B
是有效的操作。我将使方法“A”成为初始化对象的构造函数。这必须调用一次才能使用由编译器强制执行的对象。稍后,您可以调用方法“B”,因为必须调用构造函数。您无法真正执行该命令(您已经提到了一个解决方案)。您可以使用模板模式重新设计,避免这种特殊需要。这是一个好主意(+1),请注意,这样做的一个缺点是,调用a所需的所有信息都必须传递到B中-这可能是令人伤心的。(想象一下需要将所有DB连接数据传递给每个查询…)而且“唯一的方法”在IMO中有点强。
public class DatabaseFactory {
public Database init(String username, String password) // ...
public class Database {
private Database() {}
public List<Object> runQuery(String sql) // ...
}
}
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");