Hi! > - PHP 7 has private classes through anonymous/inner classes.
It's not exactly the same, and I suspect the same is true for Ruby. It's true that anonymous classes can not be instantiated by other code. But that is not what we were discussing here. This particular effect is somewhat similar, the purpose of the feature is different. Of course, some languages have them. Others don't. The point is saying "it's not OO unless it implements $favorite_feature_of_mine" is not very meaningful, at least at this point. > abstract class Data { > protected $id; > protected $name; > protected function __construct() {} > protected function __clone() {} > } > > final class Entity extends Data { > public function getId() { > return $this->id; > } > public function getName() { > return $this->name; > } > } > > final class Builder extends Data { > private $entity; > public function build() { > return clone $this->entity; > } > public function setId($id) { > $this->entity->id = $id; > } > public function setName($name) { > $this->entity->name = $name; > } > } > > ?> I'm afraid I don't understand this code. Why both entity and builder are Data? It looks like combining factory object with actual data object. This is why __construct/__clone exists - so the object could take care of the details and the factory didn't have to know about it in details. I presume you want to say that Data object should be private class. I think - at least from my partial understanding of the code - that it shouldn't exist at all, especially given you don't want to expose it to the user. > Another example that is not solvable with friend classes would be the > strategy pattern of hidden strategies as we find it for example in > Symfony's process component. > > https://github.com/symfony/process/tree/master/Pipes > > The pipes are purely internal to work around differences between PHP on > Unix and Windows. They are not meant for consumption through users, they Sure, they aren't useful for most, but I see no problem in somebody using them if necessary. Say, you may want to use Unix pipe on Windows because you are in unix emulation environment, or you have a weird OS that is not Unix and now Windows and want to reuse parts of these classes to deal with it. There could be many cases we can't foresee when we design it for our ideal use case. > At trivago we have hundreds of applications, packages, libraries and > developers who work in a very fast moving environment. Reading > documentation is not something most people spend time with. I find so many things not right with this statement I don't know where to start... So I just leave it with a note that having no time to do things right usually means doing things wrong many times, and *then* being forced to spend time to do things right because the whole jenga tower crashes on your head. That is not a criticism of you or your employer, but rather the result of experience learned the hard way. You can get away with it from time to time, true, but it's just luck. > It's also easy to work around property and method access modifiers. > However, that is no argument to remove them now. Not very easy. The only way to work around private is to use heavy machinery like reflection. This is why, btw, private should be used very carefully - when if you're *sure* nobody will need or is advised to access that thing directly. Overuse of private, especially for methods, leads to classes that are not extendable without horrendous amounts of copypaste. Also, there's a difference IMO between classes and class' properties. Class details may be - indeed, need to be - hidden because this is what the class is, one of it's reasons to exist - a tool to reduce complexity by hiding irrelevant information and exposing only relevant information as class' public API. You hide things not because you're afraid evil users would abuse them - but as a service to the user to not overload their mental models with irrelevant details and allow to deal with the class by only considering the important things. However, if we're talking about collection of classes sharing a namespace, there's no such thing as "namespace's API", at least not in common use. There's a concept of library's API, but it's not derived from classes alone - it's usually what documentation does, while class API can be yet figured from it's methods, library API is usually impossible to figure out just looking at the classes - you need the next level, documentation. So in my opinion, if you hide some classes from instantiation from outside namespace (which by itself carries a lot of assumptions, such as every class that will ever need it will share the same namespace), reduction in complexity is almost none, since nobody uses "list of available classes in package/namespace" as a way to work with the package anyway. P.S. BTW I still don't know why you need to refactor namespaces to have namespace-private classes anyway. Isn't it just a matter of the match between current scope and target class name? -- Stas Malyshev smalys...@gmail.com -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php