OSGi 类似于其他编程语言中的模块化
Java 中的 OSGi 框架提供的严格模块化概念可以在任何其他编程语言中使用吗?
我觉得 C++ 中的 friend
类的概念有点相似,但它似乎是一个更精细的控制。我不确定 friend
概念是否可以应用于 namespace
级别。
在其他语言中我不知道,如果有人可以在这里提供一些见解,我将非常感激。
Is the concept of a strict modularity provided by OSGi frameworks in Java, available in any other programming language?
I felt the concept of friend
classes in C++ is somewhat similar, but it seems to be a much more granular control. I'm not sure if the friend
concept can be applied at a namespace
level.
In other languages I have no idea, and would really appreciate if someone can provide some insight here.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
有很多语言都有模块系统。立即浮现在脑海中的三个是 Standard ML 的模块系统、Racket 的单元系统和 Newspeak 的模块系统。
有些人认为这三个系统比 OSGi 或类似系统更强大或设计得更好(或两者兼而有之)。
我特别喜欢 Newspeak 模块系统,因为它非常简单。事实上,Newspeak 甚至没有真正的模块系统,事实证明,如果你认真对待面向对象,类会自动成为模块定义,而对象会自动成为模块定义成为模块。
这与标准 ML、Racket 或 OSGi 等其他模块系统形成鲜明对比,这些系统通常极其复杂。这是 BitC 编程语言的设计者 Jonathan Shapiro 关于设计模块系统的一段有趣的名言:
当 Haskell 的设计者之一 Simon Peyton Jones 被问到为什么 Haskell 只有这么一个基本的模块系统时,他说他们觉得自己没有足够聪明来设计一个真正的模块系统。让我们深入了解……Haskell 的设计者。 不聪明。
Newpeak 的设计非常出色:在面向对象中,一切都是消息发送(在 Java 中,这是一个(非静态)方法调用,在 C++ 中,这是一个虚拟函数调用)。不幸的是,在大多数面向对象语言中,情况并非如此。你有变量、字段、常量、非虚函数、静态方法、类字典、包字典等等。访问其中任何一个都不是通过消息发送完成的,而是通过其他方式完成的。
新话则不然:在新话中,一切都是消息发送。即使是一个类的超类也是一个消息发送。 (即:如果我用新话编写
class Foo extends Bar
,那么Bar
不是对类本身的引用,它只是调用一个名为Bar
的方法,然后它将返回一个类,顺便说一句,这意味着您可以在子类中重写超类,这非常令人兴奋。)这意味着顶级类不能有超类:因为超类。消息已发送,您要将其发送到哪里?在顶级类中,您只能调用类本身中定义的方法:您不能从封闭范围调用方法,因为在顶级类中,没有封闭范围。并且您不能调用从超类继承的方法,因为为了声明超类,您需要调用一个方法,但您只能调用该类内部定义的方法。
现在,这不是很有用,因此类具有类初始值设定项,它允许您将对象(类就是对象)注入到类中。这是将依赖项注入类的唯一方法,因此类初始值设定项充当模块依赖项规范。
另一方面,如果做某事的唯一方法是通过消息发送,那么类的内部自动是私有的,它的功能只能通过调用公共方法来实现。因此,公共方法充当模块接口规范。
其他一些很酷的功能也自然而然地由此产生。许多其他模块系统不具备的功能:由于模块实际上只是一个类,因此您可以拥有一个模块的多个实例,只需像调用任何其他类一样多次调用构造函数即可。在许多其他模块系统中,模块是单例的。
而且,您可以将参数传递给构造函数,从而为您提供参数化模块,这通常仅由非常高级的模块系统支持(如果有的话)。
There are plenty of languages that have module systems. Three that spring to mind immediately are the module system of Standard ML, the unit system of Racket and the module system of Newspeak.
Those three are by some people regarded as either more powerful or better designed (or both) than OSGi or similar systems.
I specifically like the Newspeak module system, because of its incredible simplicity. In fact, Newspeak doesn't even really have a module system, it just turns out that if you take object-orientation seriously, classes automatically become module definitions, and objects automatically become modules.
This is a refreshing contrast to other module systems like Standard ML's, Racket's or OSGi's, which typically are insanely complex. Here is a nice and funny quote by Jonathan Shapiro, the designer of the BitC programming language about designing a module system:
And when Simon Peyton Jones, one of the designers of Haskell, was asked why Haskell has only such a basic module system, he said that they didn't feel they were smart enough to design a real one. Let that sink in ... The designers of Haskell. Not smart.
Newspeak's design is utterly brilliant: in object-orientation, everything is a message send (in Java-speak that's a (non-static) method call, in C++-speak that's a virtual function call). In most object-oriented languages that is unfortunately not true. You have variables, fields, constants, non-virtual functions, static methods, a class dictionary, a package dictionary, and so on. Accessing any of those is not done via a message send, but via some other means.
Not so on Newspeak: in Newspeak, everything is a message send. Even the superclass of a class is a message send. (I.e.: if I write
class Foo extends Bar
in Newspeak, thenBar
is not a reference to the class itself, it is just calling a method namedBar
, which will then return a class. Which BTW means that you can override superclasses in subclasses, which is pretty mindblowing.)This means that top-level classes cannot have a superclass: since the superclass is message send, where would you send it to? In a top-level class, you can only call methods that are defined in the class itself: you cannot call methods from the enclosing scope, because in a top-level class, there is no enclosing scope. And you cannot call methods inherited from a superclass, because in order to declare a superclass, you would need to call a method, but you can only call methods defined inside the class.
Now, this is isn't very useful, so classes have class initializers, which allow you to inject objects (and classes are objects) into a class. And this is the only way to inject dependencies into the class, ergo the class initializer functions as a module dependency specification.
On the flip side, if the only way to do something is via message sending, then the internals of a class are automatically private, its functionality can only be achieved by calling public methods. Ergo, the public methods function as a module interface specification.
A couple of other cool features also fall out naturally from this. Features that many other module systems don't have: since a module is really just a class, you can have multiple instances of a module, just call the constructor multiple times like you would with any other class. In a lot of other module systems, modules are singletons.
And, you can pass in arguments to the constructor, thus providing you with parameterized modules, which is typically only supported by very advanced module systems, if at all.