Açık / Kapalı & Open Closed Prensibi | Solid
Tanınmış yazılım ustalarından Ivar Jacobson bu konuda şöyle bir açıklamada bulunmuştur:
“All systems change during their life cycles. This must be born in mind when developing systems are excepted to last longer than the first version.”
Şu şekilde tercüme edilebilir:
“Her program görev süresince değişikliğe uğrar. Bu ilk sürümden ötesi düşünülen programların yazılımında göz önünde bulundurulmalıdır.”
Bertrand Meyer tarafından geliştirilen bu prensip kısaca şöyle açıklanabilir:
“Programlar geliştirilmeye açık ama değiştirilmeye kapalı olmalıdır.”
Bu prensibi tek cümle ile kısaca anlatacak olursak sınıflarımız modüllerimiz ve fonksiyonlarımız geliştirmeye açık değişime kapalı olmalıdır.
Örneğin Spring Framework’ünü ele alırsak, bu frameworkün temel işlevlerini ve mantığını değiştiremeyiz fakat framework içerisindeki sınıfları kalıtım alarak yapıyı genişletebiliriz. Örneğin Spring Security’nin varsayılan oturum oluşturma ve oturum yönetme servislerini kullanabileceğimiz gibi bu sınıfları kalıtım alarak oturum oluşturma ve yönetme işlemlerini kendimizde yapabiliriz.
Başka bir örnek olarak ise gerçek hayatta müşterilerimizden hatta kendimizden örnek verelim. Bir projeye başladığınızda bir özelliğini kaç kere değiştirmişsinizdir ? Ya da tamamen biten bir projeniz var mıdır ? İşte bunun gerçekliğinin bilincinde olan bu prensip bu sorunla ilgili çözüm önerisi olarak çalışan kodun değiştirilmeyip genişleyebilir bir sistem olarak tasarlanması gerektiğini savunuyor.
Özcan Hocamızın sitesinden bu prensibi güzel bir şekilde yorumlayan yazısını okursak daha detaylı anlayabileceğiz.
Programı geliştirmek, programa yeni bir davranış biçimi eklemek anlamına gelmektedir. OCP ye göre programlar geliştirmeye açık olmalıdır, yani programı oluşturan modüller yeni davranış biçimlerini sergileyecek şekilde genişletilebilmelidirler. Bir modüle yeni bir davranış biçimi kazandırılarak düşünülen değişiklik sağlanır. Bu yeni kod yazılarak gerçekleştirilir ( bu yüzden bu işleme değiştirme değil, genişletme denir), mevcut kodu değiştirerek değil! Eğer kendinizi bir müşteri gereksinimini mevcut kod üzerinde değişiklik yaparken bulursanız, biliniz ki OCP prensibine ters düşüyorsunuz. Kod üzerinde yapılan değişiklik, bir sonraki gereksinimlerinde ayni şekilde implemente edilmesini zorunlu kılacaktır. Bu durum, kodun zaman içinde içinden çıkılmaz ve çok karmaşık bir yapıya dönüşmesini çabuklaştırır.
Şimdi Örneğimize geçersek;
Kötü bir örnek için :
AreaCalculator
package SOLID.OCP.Bad;
public class AreaCalculator {
public double Area(Object shape) {
double area = 0;
if (shape instanceof Rectangle) {
area = ((Rectangle) shape).getWidth() * ((Rectangle) shape).getHeight();
} else {
Circle circle = (Circle)shape;
area += circle.getRadius()* circle.getRadius() * Math.PI;
}
return area;
}
}Circle
package SOLID.OCP.Bad;
public class Circle {
private double Radius;
public double getRadius() {
return Radius;
}
public void setRadius(double radius) {
Radius = radius;
}
}Rectangle
package SOLID.OCP.Bad;
public class Rectangle {
private double width;
private double height;
public double getWidth() {
return width;
}
public void setWidth(double width) {
this.width = width;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
}İyi Bir Örnek İçin:
Shape:
package SOLID.OCP.Good;
public abstract class Shape
{
public abstract double Area();
}Rectangle
package SOLID.OCP.Good;
public class Rectangle extends Shape
{
private double width;
private double height;
@Override
public double Area() {
return width*height;
}
}Circle
package SOLID.OCP.Good;
public class Circle extends Shape {
private double radius;
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
@Override
public double Area() {
return radius*radius*Math.PI;
}
}



