I would consider this a very bad design. It’s one of those solutions that you think of and tell yourself ”look at how elegant it looks”. Then one month (or more) when you revisit the code to do some additions / code reading, you realize how bad an idea it was.
The customer object is in a good position to decide how the customer should be reached.
The second refactoring is somewhat different. That would make more sense if the communication decision wasn't based solely on the existence of an email address. But all he's really done now is add a kind of bespoke Visitor pattern to work around a lack of double dispatch.
Personally, I'd be inclined to keep the naive version unless there were clear requirements for double dispatch (and probably more than one example). If there were multiple requirements, I'd build in an abstract Visitor framework so you're back to limited coupling at the expense of some complexity.
TBH I'd probably be using a language that had multiple dispatch but that's not always an option.