我有一个示例(不完整)类,例如
class ABC{
public:
void login();
void query_users();
//other methods
private:
//member data
}
这个类的使用方式应该是先调用login,然后再调用query_users等其他方法。登录设置一些私有(private)成员数据供其他方法使用。除了调用一个函数来检查成员数据是否设置在类中每个其他方法的开头之外,有没有更简单的方法来实现这一点?
最佳答案
我知道有两种通用方法,它们有很大的不同。您必须为任务选择合适的机制——在标准的基于类的 OO 语言(例如 Java/C++/C#/Python)中,它们是我所知道的仅有的两种方法。 (可能还有我不熟悉的不同范例中的其他方法。)
1。检查状态。
这已经在许多必须跟踪系统/支持资源状态的类中完成。两个常见示例是(文件)流和数据库连接。
"template"可能如下所示:
void Logon(credentials) { ..; loggedOn = true }
void DieUnlessLoggedIn { if (!loggedOn) { throw .. } }
void DoStuff () { DieUnlessLoggedIn(); .. }
虽然上述方法非常通用,但某些语言可能支持不变量 (Eiffel)、装饰 (Python)、注释、AOP 或其他断言机制。
这种方法对于可变世界中的动态状态很有用:例如“注销”后会发生什么? DoStuff
的状态再次无效,直到重新登录(如果允许)。但是,这种方法一般不能用于主流 OOP 语言的编译时检查,因为运行时状态在编译时根本不可用。
2。使用多种类型来表示状态。
创建两个单独的类型,例如类型 ServiceLogon(方法 Logon
)创建 ServiceAccess(方法 DoStuff
)。因此 DoStuff
只能在从 Logon
(在 ServiceLogon 上)创建后调用(在类型 ServiceAccess 上)。这可以很好地在成员隐藏的静态语言中强制执行调用顺序语义 - 因为如果错误,程序将无法编译。
login = new ServiceLogon(credentials)
access = login.Logon();
access.DoStuff(); // can't be called before obtained via Logon
使用类型来编码附加状态可能过于复杂,因为它会破坏基于类的类型系统,但在“构建器”和“存储库”模式等中很有用;基本上,询问是否保证拆分类型以维持 SRP,然后考虑这种方法。
这种方法无法在不合并状态检查的情况下完全处理“注销”之类的事情,因为 ServiceAccess 类型(在干净的意义上)总是表示相同的状态,因为它是在类型中编码的。 p>
1。 & 2. 使用状态检查和状态/角色特定类型。
当然,混合是完全可以接受的,并且上述两种方法并不相互排斥。分离使一种类型(以及由此调用的方法)依赖于另一种方法的角色,同时仍然适本地检查运行时状态可能是有意义的。如上所述,#1 非常适合运行时守卫(它可以是高度动态的),而#2 可以在编译时强制执行某些规则。
关于oop - 确保在方法 B 之前调用方法 A 的设计模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18499775/