笔者的 SAP 技术交流群里,有朋友提问:
我想问一个很基础的问题,为什么类要有friend啊
反正我工作这些年,在 SAP 生产代码里没用过友元,只是在生产代码的单元测试代码里用过,原因也就是让单元测试代码能够访问到被测试的生产类的私有属性。
代码如下:
SAP ABAP 的帮助文档:
在面向对象编程中,封装是一个重要的概念,它可以将代码组织成一些独立的模块,从而提高代码的可维护性、可复用性和可扩展性。封装的核心思想是隐藏对象的实现细节,只暴露出必要的接口供其他对象使用。在这种情况下,对象之间的交互只能通过暴露的接口来进行,从而实现了对象之间的隔离和保护。
然而,在实际的开发过程中,我们有时需要在对象之间共享一些私有信息,以便更好地实现一些功能。这时,就可以使用 friend 机制来解决这个问题。friend 机制是一种面向对象的设计模式,它允许对象之间共享私有信息,并且只有指定的对象才能访问这些信息。具体来说,friend 机制允许一个类将另一个类或函数声明为其友元,从而允许友元访问其私有成员。
在 friend 机制中,一个类将另一个类或函数声明为友元,意味着它允许该类或函数访问其私有成员。这意味着友元类或函数可以突破封装的限制,直接访问另一个对象的私有成员,这可能会破坏封装性。此外,由于 friend 机制是一种特殊的机制,它不遵循常规的面向对象编程规则,因此使用它可能会导致代码更加难以理解和维护。
然而,虽然 friend 机制在某种程度上破坏了封装性,但它也提供了一些好处。它允许一些密切相关的对象共享私有信息,从而更好地实现一些功能。例如,如果一个类和另一个类紧密耦合,它们需要共享一些私有信息以便更好地实现一些功能,那么 friend 机制可以提供一种解决方案。此外,friend 机制还可以提高代码的可读性,因为它可以帮助开发者更清晰地了解对象之间的关系。
尽管 friend 机制有一些优点,但在大多数情况下,应该避免使用它。如果对象之间需要共享一些私有信息,通常最好的方法是通过公共接口来实现。如果两个对象必须彼此知道对方的实现细节,这可能意味着它们之间存在过度耦合的问题,需要进行重新设计。此外,friend 机制的使用可能会导致代码更加难以理解和维护。
在面向对象设计领域中,封装是一种将数据和操作它们的方法组合在一起的方式,目的是隐藏对象内部的实现细节。封装实际上是一种信息隐藏手段,它有助于提高代码的可维护性、可扩展性和可重用性。然而,当引入friend机制时,这种封装性可能会受到影响。接下来,我们将从多个方面探讨friend机制如何影响面向对象设计的封装性,以及在某些情况下如何权衡这种影响。
首先,让我们了解什么是friend机制。在某些面向对象编程语言(如C++)中,friend关键字用于声明一个类或函数可以访问另一个类的私有成员和保护成员。通常,私有成员和保护成员只能被类的成员函数访问,但是通过将一个类或函数声明为另一个类的友元,我们可以允许这些外部实体访问类的内部成员。
的确,friend机制在一定程度上破坏了封装性。允许外部实体访问类的私有成员和保护成员可能导致类的实现细节泄露,使得代码更难维护和扩展。在大型软件项目中,这可能导致潜在的不稳定性和安全风险。
然而,尽管friend机制可能会削弱封装性,但在某些情况下,它仍然是有用的。在以下场景中,使用friend机制可能是有益的:
- 当两个或多个紧密相关的类需要共享某些数据或功能时。在这种情况下,友元类或友元函数可以作为一种更简洁、更直接的方式来实现这些共享功能,而不是通过公共接口暴露过多的实现细节。
- 当需要实现高效的代码时。有时,为了提高性能,我们需要让某些类或函数能够直接访问另一个类的内部成员。通过使用friend机制,我们可以避免创建额外的接口,从而提高代码的执行效率。
- 当用于测试时。在软件测试中,我们可能需要访问类的私有成员来验证其正确性。通过将测试类或测试函数声明为待测类的友元,我们可以更容易地访问这些私有成员,从而编写更全面的测试用例。
总之,虽然friend机制可能会破坏面向对象设计的封装性,但在某些特定情况下,它仍然是一个有用的工具。
Jerry:
gof 23 种设计模式里,并没有一种采取 friend 实现,这本身也能说明问题了。
friend 关键字通常在 C++ 中使用,用于声明友元类或友元函数,以便在类之间共享私有成员。这个概念在其他编程语言中可能有不同的实现方式,例如 C# 中的 internal
关键字。
然而,在23种设计模式中,有些模式可能会用到友元类或友元函数的概念。例如,Mediator(中介者)模式中,类之间的通信会通过一个中介者对象进行。这种情况下,友元类或友元函数可以用来限制对各个类的访问,只允许中介者对象访问它们的私有成员。不过,这并不是 GoF 设计模式的核心内容,而是具体实现时的一种可选方案。
总之,GoF 23种设计模式并没有直接借助面向对象的 friend
机制来实现。然而,在实际应用这些设计模式时,根据具体需求和编程语言的特点, friend
机制可以作为一种实现方式。
在 Gof 23 种设计模式中,并没有直接借助面向对象的 friend 机制实现的设计模式。但是,有一些设计模式涉及到了访问控制和对象间的协作,可以通过类似于 friend 机制的方式实现。
例如,观察者模式(Observer Pattern)中,一个对象(称为 Subject)维护了一系列观察者对象(Observers),并在状态发生改变时通知这些观察者。通常情况下,Subject 对象需要将自身的状态信息告诉 Observer 对象,以便 Observer 对象能够获取到相关的信息。在这种情况下,可以将 Observer 对象设置为 Subject 对象的 friend 类型,使得 Observer 对象可以直接访问 Subject 对象的私有状态,而不需要通过公共接口来访问。
此外,还有一些类似于访问控制和对象间协作的设计模式,如门面模式(Facade Pattern)和中介者模式(Mediator Pattern),都需要协调不同的对象之间的关系。在这些模式中,对象之间需要进行协作,但是又需要保持封装性。可以通过类似于 friend 机制的方式来实现对象之间的协作和信息共享,同时保持封装性。
总之,虽然没有直接借助面向对象的 friend 机制实现的设计模式,但是一些设计模式涉及到了访问控制和对象间的协作,可以通过类似于 friend 机制的方式来实现。这也说明了,在面向对象设计中,合适的访问控制和对象间协作是非常重要的。