Nesne yönelimli programlama, on yıllarca yazılım geliştirmenin ana paradigması olarak öğretildi ve benimsendi. OOP eleştirisi, bu paradigmanın altında yatan bazı varsayımları sorgulamakla başlar: kapsülleme, miras, polimorfizm ve soyutlama gerçekten kodu daha anlaşılır, sürdürülebilir ve yeniden kullanılabilir yapıyor mu? Theori düzeyinde bu vaatler makul görünür. Ama pratikte OOP'nin nasıl uygulandığına bakıldığında tablo karmaşıklaşır. Derin miras hiyerarşileri, on, on beş seviyeli inheritance zincirleri, bir sistemin davranışını anlamayı kolaylaştırmak yerine zorlaştırır. Hangi metodun hangi sınıftan geldiğini, hangi davranışın nerede ezildiğini izlemek, zamanla sistemle kurulan ilişkiyi kırılganlaştırır. OOP eleştirisi alanında sıkça işaret edilen bir başka sorun, kapsüllemenin pratikte nasıl uygulandığıdır. Getter/setter çiftlerinin nesnenin iç durumunu dışarıya açmasıyla kapsülleme fiilen işlevsizleşir; ama yine de nesne yönelimli yazılmış bir kod gibi görünür. Bu durum, kodun şeklen paradigmaya uyduğu ama özünde prensiplere aykırı davrandığı bir sarmalı doğurur. Fonksiyonel programlama topluluğunun OOP'ye yönelik eleştirilerinden biri de paylaşılan değişken durumun (mutable shared state) yönetimidir. Nesneler kendi durumlarını zamanla değiştiren varlıklar olduğunda, çok sayıda nesnenin bir arada çalıştığı sistemlerde durumu takip etmek ve hataları yeniden üretmek güçleşir. Peki bu eleştiriler OOP'nin terk edilmesi gerektiği anlamına mı gelir? Mutlaka değil. Belirli problem alanları, GUI sistemleri, oyun geliştirme, bazı domain modelleme senaryoları, nesne tabanlı düşünceyle iyi eşleşir. Ama "her şey bir nesne olmalıdır" dogması, gerçekte farklı yaklaşımların daha temiz sonuç üreteceği alanlarda da yapay bir kalıba zorlamaya neden olur. OOP'nin sınırlarını görmek, onu tamamen reddetmekten farklıdır. Paradigmaları dogma olarak değil, alet çantasındaki araçlar olarak görmek, hangi probleme hangi yaklaşımın daha iyi uyduğunu sormayı mümkün kılar.