In general idea without considering any implementation specifics, we can consider Facade as a way of hiding a set of sub-systems with a higher level wrapper class using Composition and Encapsulation. The higher level Wrapper class is the one that always talks with any client and the Sub-systems consisted inside the wrapper are the ones that are really doing the jobs.
Example:
public class Bulb{
public void on(){
//logic to turn on the bulb.
}
}
public class Room{
private Bulb bulb;
public void lightUp(){
this.bulb.on();
}
}
In above Bulb is a sub-system and Room is the wrapper (Facade). So a client would like to see as it is directly lighting up the room and not interested in knowing what it has to be done with the bulb.
So back into your question, If we take SOLID principles one by one.
- SRP: You should be thinking that, the wrapper class violates this principle, because it is doing more than a single duty. But on the other hand, it is just calling some others to do them, and not holding the implementation with the wrapper. Anyway that thought can be much personal one.
- OCP: Definitely yes, if you are adding some more subsystems/functionalities. Meantime you can use some modern implementation binding framework to avoid violating OCP in this situation.
- LSP: In general I don't find any. But there can be situations which are implementation specific, not with the pattern.
- ISP: Same as LSP.
- DIP: Same as LSP, ISP.
And about considering Facade as an anti-pattern (Cons of Facade),
- One can see, It is increasing the maintenance effort. For some changes you have to change the sub-system(s) implementation + respective wrapper calls.
- Sub-systems are tightly coupled with the Wrapper.
- It is some what procedural and a bit away from object orientation.
Still the choice of using Facade(Many patterns) would be by personal flavor.