It's not really possible to provide a specific solution without understanding the specific situation. Generally speaking, a major design goal should be to keep each class as independent as possible. When you start using something like the Registry pattern, you start adding a sort of system-wide constraint somewhat analogous to using global variables (though not that bad). Realistically, though, as a system reaches some level of size and complexity, the benefits of such an implementation (using some sort of global object like a Registry object) may well out-weigh the closer coupling it begins to impose on your application. You'll need to make the judgment based on your particular application design whether it makes more sense to use a Registry object or to simply pass object references to other objects as needed (or very likely some of each).
PS: Depending upon what you mean by "communicate", it may be that in some cases you are looking more at some sort of composition pattern, where Class A internally creates its own instance of Class B, for example. Again, it all depends on the specific application design and the context and purpose of those object relationships.