"Refactoring: Improving the Design of Existing Code" (Tasarımı Mevcut Kodun
İyileştirilmesi olarak çevrilebilir), Martin Fowler tarafından yazılmış bir
kitaptır. Bu kitap, mevcut kodun tasarımını iyileştirmeye yönelik teknikleri
anlatır. Kitap, kodu düzenlemeyi ve iyileştirmeyi kolaylaştıran adımları adım
adım anlatır ve okuyuculara nasıl daha verimli kod yazabileceklerini öğretir.
Kitap ayrıca kodun okunabilirliğini ve anlaşılabilirliğini artırmak için
yapılacak değişiklikleri de ele alır.
"Encapsulate Field" (Alanı Kapat) refactoring tekniği, bir alanı (değişken) sınıf içinde kapatmayı hedefler. Bu sayede, alanın değerini değiştirmek için kullanılacak metodlar oluşturulur ve böylece alanın direkt olarak erişilememesi sağlanır. Bu teknik, kodun bakımını kolaylaştırır ve hataların önüne geçmeyi hedefler.
"Move Method" (Metod Taşı) refactoring tekniği, bir metodu başka bir sınıfa taşımayı hedefler. Bu sayede, metodun işlevine daha uygun bir sınıf içinde yer alması sağlanır ve kodun düzeni iyileştirilir.
"Extract Interface" (Arayüz Çıkar) refactoring tekniği, bir sınıftaki metodları ve alanları ayrı bir arayüze çıkarmayı hedefler. Bu sayede, sınıfın işlevine daha uygun bir arayüz oluşturulur ve bu arayüzü implemente eden sınıfların daha anlaşılır hale gelmesi sağlanır. Ayrıca, bu teknik sayesinde sınıflar arasında daha esnek bir bağlantı oluşturulur ve kodun bakımı kolaylaşır.
"Collapse Hierarchy" (Hiyerarşiyi Birleştir) refactoring tekniği, bir hiyerarşideki benzer sınıfları birleştirmeyi hedefler. Bu sayede, hiyerarşi daha az katmandan oluşur ve kodun okunabilirliği artar. Ayrıca, bu teknik sayesinde kodun bakımı kolaylaşır ve hatalar önlenir.
"Extract Subclass" (Alt Sınıf Çıkar) refactoring tekniği, bir sınıftan benzer özellikleri paylaşan alt sınıflar oluşturmayı hedefler. Bu sayede, sınıflar daha anlaşılır hale getirilir ve kodun okunabilirliği artar. Ayrıca, bu teknik sayesinde kodun bakımı kolaylaşır ve hatalar önlenir.
Öncelikle, hangi yöntemlerin bir yöntem nesnesi ile değiştirilmesi gerektiğini belirleyin. Örneğin, aşağıdaki sınıftaki "calculateTotalPrice" yöntemini bir yöntem nesnesi ile değiştirmek istiyoruz:
"Replace Type Code with Subclasses" (Alt Sınıflar ile Tür Kodunu Değiştir) refactoring tekniği, bir tür kodunun yerine alt sınıflar kullanılmasını hedefler. Bu sayede, kodun okunabilirliği artar ve daha anlaşılır hale getirilir. Ayrıca, bu teknik sayesinde kodun bakımı kolaylaşır ve hatalar önlenir.
"Convert Iterator to Visitor" (Ziyaretçiye İteratörü Dönüştür) refactoring
tekniği, bir yapıdaki elemanları ziyaret eden bir ziyaretçi oluşturarak
iteratörleri ziyaretçilere dönüştürmeyi hedefler. Bu sayede, kodun
okunabilirliği artar ve daha anlaşılır hale getirilir. Ayrıca, bu teknik
sayesinde kodun bakımı kolaylaşır ve hatalar önlenir.
"Replace Temp with Query" refaktoring tekniğini daha detaylı bir Java kod örneğiyle açıklamaya çalışacağım:
Bu teknik, bir yöntem içinde kullanılan geçici değişkenleri bir sorgu ile değiştirerek daha okunabilir ve anlaşılır bir yapı oluşturmayı amaçlar.
Öncelikle, hangi geçici değişkenlerin bir sorgu ile değiştirilmesi gerektiğini belirleyin. Örneğin, aşağıdaki sınıftaki "basePrice" geçici değişkenini "getBasePrice" yöntemi ile değiştirmek istiyoruz:
"Split Temporary Variable" refaktoring tekniğini daha detaylı bir Java kod örneğiyle açıklamaya çalışacağım:
Bu teknik, bir yöntem içinde aynı değeri birden fazla kez kullanan geçici değişkenleri parçalara bölerek daha okunabilir ve anlaşılır bir yapı oluşturmayı amaçlar.
Öncelikle, hangi geçici değişkenlerin parçalara bölünmesi gerektiğini belirleyin. Örneğin, aşağıdaki sınıftaki "temp" geçici değişkenini "height" ve "width" değişkenlerine bölmek istiyoruz:
"Remove Assignments to Parameters" refaktoring tekniğini daha detaylı bir Java kod örneğiyle açıklamaya çalışacağım:
Bu teknik, bir yöntem içinde parametrelerin değerlerini değiştiren atamaları kaldırarak daha okunabilir ve anlaşılır bir yapı oluşturmayı amaçlar.
Öncelikle, hangi parametrelerin atamalarının kaldırılması gerektiğini belirleyin. Örneğin, aşağıdaki sınıftaki "discountPercentage" parametresinin atamasını kaldırmak istiyoruz:
"Extract Class" refaktoring tekniğini daha detaylı bir Java kod örneğiyle açıklamaya çalışacağım:
Bu teknik, bir sınıftaki birden fazla özelliği ve bu özelliklerle ilgili işlemleri ayrı bir sınıfa taşıyarak daha okunabilir ve anlaşılır bir yapı oluşturmayı amaçlar.
Öncelikle, hangi sınıf özelliklerinin ayrı bir sınıfa taşınması gerektiğini belirleyin. Örneğin, aşağıdaki sınıftaki "name" ve "address" alanlarının "Person" sınıfından "NameAndAddress" sınıfına taşınmasını istiyoruz:
Kodun okunabilirliğini artırmak için, metodların ve fonksiyonların
isimlerini daha anlaşılır hale getirme. Örneğin, "getData" yerine
"getCustomerData" gibi daha açıklayıcı bir isim kullanılabilir.
Kodun düzenini iyileştirmeyi hedefleyen "Extract Method" (Metod Çıkar) refactoring tekniği, bir metodun içinde yer alan kod bloğunu ayrı bir metoda çıkararak daha okunabilir hale getirmeyi hedefler. Bu sayede, metodlar daha küçük ve anlaşılır hale gelir ve kodun anlaşılırlığı artar.
Kodun düzenini iyileştirmeyi hedefleyen "Extract Method" (Metod Çıkar) refactoring tekniği, bir metodun içinde yer alan kod bloğunu ayrı bir metoda çıkararak daha okunabilir hale getirmeyi hedefler. Bu sayede, metodlar daha küçük ve anlaşılır hale gelir ve kodun anlaşılırlığı artar.
void printOwing(double amount) {
printBanner();
// print details
System.out.println("name: " + name);
System.out.println("amount: " + amount);
}
Ayrıntıları yazdıran kodu printDetails adlı ayrı bir yönteme çıkararak bu kodu yeniden düzenleyebilirsiniz:
void printOwing(double amount) {
printBanner();
printDetails(amount);
}
void printDetails(double amount) {
System.out.println("name: " + name);
System.out.println("amount: " + amount);
}
"Encapsulate Field" (Alanı Kapat) refactoring tekniği, bir alanı (değişken) sınıf içinde kapatmayı hedefler. Bu sayede, alanın değerini değiştirmek için kullanılacak metodlar oluşturulur ve böylece alanın direkt olarak erişilememesi sağlanır. Bu teknik, kodun bakımını kolaylaştırır ve hataların önüne geçmeyi hedefler.
class Point {
public double x;
public double y;
}
x ve y alanlarını kapsülleyerek bu kodu yeniden düzenleyebilirsiniz:
class Point {
private double _x;
private double _y;
public double getX() {
return _x;
}
public void setX(double x) {
_x = x;
}
public double getY() {
return _y;
}
public void setY(double y) {
_y = y;
}
}
"Extract Class" (Sınıf Çıkar)
refactoring tekniği, bir sınıfta yer alan bazı alanları ve metodları ayrı
bir sınıfa çıkarmayı hedefler. Bu sayede, sınıflar daha küçük ve anlaşılır
hale gelir ve kodun anlaşılırlığı artar.
class Person {
String name;
String address;
String phone;
String getName() { return name; }
String getAddress() { return address; }
String getPhone() { return phone; }
void setName(String name) { this.name = name; }
void setAddress(String address) { this.address = address; }
void setPhone(String phone) { this.phone = phone; }
}
Ad, adres ve telefon alanlarını ContactInfo adlı ayrı bir sınıfa çıkararak bu kodu yeniden düzenleyebilirsiniz:
class Person {
ContactInfo contactInfo;
String getName() { return contactInfo.getName(); }
String getAddress() { return contactInfo.getAddress(); }
String getPhone() { return contactInfo.getPhone(); }
void setName(String name) { contactInfo.setName(name); }
void setAddress(String address) { contactInfo.setAddress(address); }
void setPhone(String phone) { contactInfo.setPhone(phone); }
}
class ContactInfo {
String name;
String address;
String phone;
String getName() { return name; }
String getAddress() { return address; }
String getPhone() { return phone; }
void setName(String name) { this.name = name; }
void setAddress(String address) { this.address = address; }
void setPhone(String phone) { this.phone = phone; }
}
"Move Method" (Metod Taşı) refactoring tekniği, bir metodu başka bir sınıfa taşımayı hedefler. Bu sayede, metodun işlevine daha uygun bir sınıf içinde yer alması sağlanır ve kodun düzeni iyileştirilir.
public class Customer {
private String name;
private String address;
public Customer(String name, String address) {
this.name = name;
this.address = address;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public boolean isPreferred() {
// Check if customer is preferred
// This method doesn't use any of the Customer's fields, so it could be moved to another class
return true;
}
}
Bu örnekte, Customer sınıfından isPreferred yöntemini yeni bir CustomerUtils sınıfına taşıdık. Bu, Customer sınıfının karmaşıklığının azaltılmasına yardımcı olur ve artık müşteriyle ilgili tüm yardımcı program işlevlerinden sorumlu olan CustomerUtils sınıfının uyumunu geliştirir.
public class Customer {
private String name;
private String address;
public Customer(String name, String address) {
this.name = name;
this.address = address;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
public class CustomerUtils {
public static boolean isPreferred(Customer customer) {
// Check if customer is preferred
return true;
}
}
// Usage
Customer customer = new Customer("John", "123 Main St");
CustomerUtils.isPreferred(customer);
"Rename Method" (Metodu Yeniden Adlandır) refactoring tekniği, bir metodun adını
değiştirmeyi hedefler. Bu sayede, metodun işlevine daha uygun bir ad
verilebilir ve kodun anlaşılırlığı artar.
ShoppingCart adlı bir sınıfta hesaplaCost() adlı bir yönteminiz olduğunu ve amacını daha iyi yansıtması için onu getTotalCost() olarak yeniden adlandırmak istediğinizi hayal edin. Bu yeniden düzenlemeyi şu şekilde gerçekleştirebilirsiniz: HesaplaMaliyet()'in tüm oluşumlarını bulmak için metin düzenleyicinizin arama işlevini kullanın. Yöntemin imzasını bir yere not edin: public double measureCost(). Yeni adı kullanmak için yöntem bildirimini güncelleyin: public double getTotalCost(). Yeni adı kullanmak için yönteme yapılan tüm başvuruları güncelleyin. Örneğin, çift maliyet = cart.calculateCost(); yazan bir kod satırınız varsa, bunu çift maliyet = cart.getTotalCost(); olarak değiştirirsiniz. Yeniden düzenlemenin herhangi bir hata veya soruna yol açmadığından emin olmak için kodunuzu test edin. Değişiklikleri geri almanız gerekebileceğinden, herhangi bir yeniden düzenleme yapmadan önce kodunuzun yedeğini almak her zaman iyi bir fikirdir.
"Inline Method" (Metodu
İçe Aktar) refactoring tekniği, bir metodun içeriğini çağrıldığı yere
kopyalayarak metodun kullanımını ortadan kaldırmayı hedefler. Bu sayede,
kodun okunabilirliği artar ve daha anlaşılır hale gelir.
class Circle {
double radius;
double area() { return Math.PI * radius * radius; }
}
class Main {
void printArea(Circle c) {
System.out.println(c.area());
}
}
Alan yöntemini satır içine alarak bu kodu yeniden düzenleyebilirsiniz:
class Circle {
double radius;
}
class Main {
void printArea(Circle c) {
System.out.println(Math.PI * c.radius * c.radius);
}
}
"Extract Interface" (Arayüz Çıkar) refactoring tekniği, bir sınıftaki metodları ve alanları ayrı bir arayüze çıkarmayı hedefler. Bu sayede, sınıfın işlevine daha uygun bir arayüz oluşturulur ve bu arayüzü implemente eden sınıfların daha anlaşılır hale gelmesi sağlanır. Ayrıca, bu teknik sayesinde sınıflar arasında daha esnek bir bağlantı oluşturulur ve kodun bakımı kolaylaşır.
public class ShoppingCart {
public double calculateTotalCost() { ... }
public double applyDiscount(double discount) { ... }
// Other methods specific to ShoppingCart
}
Arayüzü oluşturun ve yöntemleri arayüze taşıyın:
public interface PricingCalculator {
double calculateTotalCost();
double applyDiscount(double discount);
}
public class ShoppingCart implements PricingCalculator {
public double calculateTotalCost() { ... }
public double applyDiscount(double discount) { ... }
// Other methods specific to ShoppingCart
}
"Introduce Parameter Object" (Parametre
Nesnesi Ekle) refactoring tekniği ise, bir metodun çok sayıda parametresini
bir nesne içinde toplamayı hedefler. Bu sayede, metodun okunabilirliği artar
ve daha anlaşılır hale gelir. Ayrıca, bu teknik sayesinde parametreler
arasında daha kolay bir ilişki kurulur ve kodun bakımı kolaylaşır.
public class CostCalculator {
public static double calcCost(double price, double taxRate, double discount) {
double cost = price + (price * taxRate) - discount;
return cost;
}
}
params parametre nesnesini tanıtarak bu kodu yeniden düzenleyebilirsiniz:
public class CostCalculator {
public static class Parameters {
private final double price;
private final double taxRate;
private final double discount;
public Parameters(double price, double taxRate, double discount) {
this.price = price;
this.taxRate = taxRate;
this.discount = discount;
}
}
public static double calcCost(Parameters params) {
double cost = params.price + (params.price * params.taxRate) - params.discount;
return cost;
}
}
// Usage
CostCalculator.Parameters params = new CostCalculator.Parameters(100, 0.1, 10);
CostCalculator.calcCost(params);
"Replace Conditional with Polymorphism" (Polimorfizm ile Koşullu İfadeyi
Değiştir) refactoring tekniği ise, bir koşullu ifadenin yerine
polimorfizmi kullanmayı hedefler. Bu sayede, koşullu ifadelerden daha
okunabilir ve anlaşılır bir kod yazılır. Ayrıca, bu teknik sayesinde kodun
bakımı kolaylaşır ve hatalar önlenir.
public class Employee {
private String name;
private int salary;
private String type;
public Employee(String name, int salary, String type) {
this.name = name;
this.salary = salary;
this.type = type;
}
public int payAmount() {
if (type.equals("Manager")) {
return salary + 1000;
} else if (type.equals("Supervisor")) {
return salary + 500;
} else {
return salary;
}
}
}
Bu örnekte, payAmount yöntemindeki koşullu ifadeyi polimorfizm ile değiştirdik. Bunu, Çalışan sınıfını soyut bir sınıfa çıkararak ve payAmount yöntemini geçersiz kılan üç somut alt sınıf (Yönetici, Süpervizör ve NormalEmployee) oluşturarak yaptık. Bu, kodun okunmasını ve anlaşılmasını kolaylaştırır, çünkü her durum kendi alt sınıfında işlenir ve ayrıca yalnızca alt sınıfları eklemeniz veya kaldırmanız gerektiğinden, durum eklemeyi veya kaldırmayı kolaylaştırır.
public abstract class Employee {
protected String name;
protected int salary;
public Employee(String name, int salary) {
this.name = name;
this.salary = salary;
}
public abstract int payAmount();
}
public class Manager extends Employee {
public Manager(String name, int salary) {
super(name, salary);
}
@Override
public int payAmount() {
return salary + 1000;
}
}
public class Supervisor extends Employee {
public Supervisor(String name, int salary) {
super(name, salary);
}
@Override
public int payAmount() {
return salary + 500;
}
}
public class RegularEmployee extends Employee {
public RegularEmployee(String name, int salary) {
super(name, salary);
}
@Override
public int payAmount() {
return salary;
}
}
// Usage
Employee employee = new Manager("John", 100000);
System.out.println(employee.payAmount());
employee = new Supervisor("Jane", 80000);
System.out.println(employee.payAmount());
employee = new RegularEmployee("Bob", 70000);
System.out.println(employee.payAmount());
"Collapse Hierarchy" (Hiyerarşiyi Birleştir) refactoring tekniği, bir hiyerarşideki benzer sınıfları birleştirmeyi hedefler. Bu sayede, hiyerarşi daha az katmandan oluşur ve kodun okunabilirliği artar. Ayrıca, bu teknik sayesinde kodun bakımı kolaylaşır ve hatalar önlenir.
public abstract class Shape {
protected String color;
public Shape(String color) {
this.color = color;
}
public abstract double getArea();
}
public class Rectangle extends Shape {
private double width;
private double height;
public Rectangle(String color, double width, double height) {
super(color);
this.width = width;
this.height = height;
}
@Override
public double getArea() {
return width * height;
}
}
Bu örnekte, genişlik ve yükseklik alanlarını Shape sınıfına taşıyarak ve getArea yöntemini tanımlamak için anonim bir iç sınıf kullanarak Rectangle sınıfını Shape sınıfına daralttık. Bu, Rectangle sınıfına ve onunla ilişkili oluşturucuya olan ihtiyacı ortadan kaldırarak kod tabanının karmaşıklığını azaltmaya yardımcı olur.
public abstract class Shape {
protected String color;
protected double width;
protected double height;
public Shape(String color, double width, double height) {
this.color = color;
this.width = width;
this.height = height;
}
public abstract double getArea();
}
// Usage
Shape rectangle = new Shape("Red", 10, 20) {
@Override
public double getArea() {
return width * height;
}
};
"Form Template Method" (Şablon Metod Oluştur) refactoring tekniği, bir sınıfın
metodlarının şablon metod olarak yapılandırılmasını hedefler. Bu sayede,
metodlar arasında benzerlikler varsa bu benzerlikleri ortaya çıkaran şablon
metod oluşturulur ve böylece kodun okunabilirliği artar. Ayrıca, bu teknik
sayesinde kodun bakımı kolaylaşır ve hatalar önlenir.
"Form Template Method" refaktoring tekniği, bir sınıf içinde yer alan yöntemlerin çalışma şeklini tasarlamayı amaçlar. Bu teknik ile, bir yöntem içinde yer alan adım adım işlemlerin özelleştirilebilir olan kısımlarını bir alt yönteme taşıyarak bu işlemlerin çalışma şeklini tasarlamaya çalışılır. Bu sayede, aynı şekilde çalışan yöntemlerin tekrarını önlemek ve kodun daha okunabilir hale gelmesi amaçlanır.
Örneğin, aşağıdaki sınıftaki "calculateTotalPrice" yöntemini "Form Template Method" refaktoring tekniği ile değiştirmeye çalışalım:
public class Order {
public double calculateTotalPrice() {
double basePrice = getBasePrice();
double tax = basePrice * getTaxRate();
return basePrice + tax;
}
public double getBasePrice() { ... }
public double getTaxRate() { ... }
}
Bu şekilde, "calculateTotalPrice" yönteminde yer alan "getBasePrice" ve "getTaxRate" yöntemleri özelleştirilebilir hale getirilmiş ve "Order" sınıfından türetilen "BasicOrder" ve "PremiumOrder" sınıflarında bu yöntemlerin nasıl çalışacağı belirlenmiştir. Bu sayede, aynı şekilde çalışan yöntemlerin tekrarı önlendi ve kodun daha okunabilir hale gelmesi sağlandı.
public abstract class Order {
public double calculateTotalPrice() {
double basePrice = getBasePrice();
double tax = basePrice * getTaxRate();
return basePrice + tax;
}
protected abstract double getBasePrice();
protected abstract double getTaxRate();
}
public class BasicOrder extends Order {
@Override
protected double getBasePrice() {
// Return the base price for a basic order
}
@Override
protected double getTaxRate() {
// Return the tax rate for a basic order
}
}
public class PremiumOrder extends Order {
@Override
protected double getBasePrice() {
// Return the base price for a premium order
}
@Override
protected double getTaxRate() {
// Return the tax rate for a premium order
}
}
"Replace Constructor with Factory Method" (Fabrika Metodu ile Yapıcıyı Değiştir)
refactoring tekniği, bir sınıfın yapıcı metodunu bir fabrika metodu ile
değiştirmeyi hedefler. Bu sayede, sınıfın örneklerinin oluşturulma işlemi daha
esnek hale getirilir ve kodun bakımı kolaylaşır.
public class Rectangle {
private double width;
private double height;
public Rectangle(double width, double height) {
this.width = width;
this.height = height;
}
public static Rectangle createSquare(double sideLength) {
return new Rectangle(sideLength, sideLength);
}
public double getArea() {
return width * height;
}
}
Bu şekilde, "Rectangle" sınıfının yapıcı yöntemlerinden birini kullanarak kare bir dikdörtgen oluşturabilmesi sağlandı.
"Extract Subclass" (Alt Sınıf Çıkar) refactoring tekniği, bir sınıftan benzer özellikleri paylaşan alt sınıflar oluşturmayı hedefler. Bu sayede, sınıflar daha anlaşılır hale getirilir ve kodun okunabilirliği artar. Ayrıca, bu teknik sayesinde kodun bakımı kolaylaşır ve hatalar önlenir.
public class Person {
private String name;
private boolean isEmployee;
private boolean isStudent;
public Person(String name, boolean isEmployee, boolean isStudent) {
this.name = name;
this.isEmployee = isEmployee;
this.isStudent = isStudent;
}
public String getName() {
return name;
}
public boolean isEmployee() {
return isEmployee;
}
public boolean isStudent() {
return isStudent;
}
}
"Person" sınıfını "Employee" ve "Student" alt sınıflarına taşıyarak aşağıdaki gibi değiştirebiliriz:
Bu şekilde, "Employee" ve "Student" sınıfları "Person" sınıfındaki "name" özelliğini ve "getName" yöntemini kalıtır ve bu sayede ortak özellikleri ve işlemleri paylaşan nesnelerin kod tekrarı önlendi ve kod daha okunabilir hale getirildi.
public abstract class Person {
protected String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
public class Employee extends Person {
public Employee(String name) {
super(name);
}
}
public class Student extends Person {
public Student(String name) {
super(name);
}
}
"Replace Method with Method Object" (Metod Nesnesi ile Metodu Değiştir) refactoring tekniği, bir
metodu bir metod nesnesine dönüştürmeyi hedefler. Bu sayede, metodun
okunabilirliği artar ve daha anlaşılır hale getirilir. Ayrıca, bu teknik
sayesinde kodun bakımı kolaylaşır ve hatalar önlenir.Öncelikle, hangi yöntemlerin bir yöntem nesnesi ile değiştirilmesi gerektiğini belirleyin. Örneğin, aşağıdaki sınıftaki "calculateTotalPrice" yöntemini bir yöntem nesnesi ile değiştirmek istiyoruz:
public class Order {
public double calculateTotalPrice() {
double basePrice = getBasePrice();
double tax = basePrice * getTaxRate();
return basePrice + tax;
}
public double getBasePrice() { ... }
public double getTaxRate() { ... }
}
Yöntemi bir yöntem nesnesi ile değiştirin:
public class Order {
public double calculateTotalPrice() {
return new CalculateTotalPriceMethodObject().calculate();
}
private class CalculateTotalPriceMethodObject {
double calculate() {
double basePrice = getBasePrice();
double tax = basePrice * getTaxRate();
return basePrice + tax;
}
}
public double getBasePrice() { ... }
public double getTaxRate() { ... }-
}
"Replace Type Code with Subclasses" (Alt Sınıflar ile Tür Kodunu Değiştir) refactoring tekniği, bir tür kodunun yerine alt sınıflar kullanılmasını hedefler. Bu sayede, kodun okunabilirliği artar ve daha anlaşılır hale getirilir. Ayrıca, bu teknik sayesinde kodun bakımı kolaylaşır ve hatalar önlenir.
"Replace Type Code with State/Strategy" (Durum/Strateji ile Tür Kodunu Değiştir) refactoring tekniği, bir tür kodunun
yerine durum veya strateji kullanılmasını hedefler. Bu sayede, kodun
okunabilirliği artar ve daha anlaşılır hale getirilir. Ayrıca, bu teknik
sayesinde kodun bakımı kolaylaşır ve hatalar önlenir.
to
"Replace Subclass with Fields" (Alanlar ile Alt Sınıfı Değiştir) refactoring tekniği,
bir alt sınıfı alanlarla değiştirmeyi hedefler. Bu sayede, kodun
okunabilirliği artar ve daha anlaşılır hale getirilir. Ayrıca, bu teknik
sayesinde kodun bakımı kolaylaşır ve hatalar önlenir.
to
"Replace Inheritance with Delegation" (Devralma ile Mirası Değiştir) refactoring tekniği, bir sınıfın işlevlerini bir başka sınıfta barındıran bir sınıf oluşturarak miras yerine devralmayı hedefler. Bu sayede, kodun okunabilirliği artar ve daha anlaşılır hale getirilir. Ayrıca, bu teknik sayesinde kodun bakımı kolaylaşır ve hatalar önlenir.
to
"Introduce Null Object" (Boş Nesne Ekle) refactoring tekniği, bir nesnenin
null değerine sahip olma ihtimaline karşı bir boş nesne oluşturarak kodun
çalışmasını sağlamayı hedefler. Bu sayede, kodun okunabilirliği artar ve
daha anlaşılır hale getirilir. Ayrıca, bu teknik sayesinde kodun bakımı
kolaylaşır ve hatalar önlenir.
"Introduce Assertion" (Varsayım Ekle) refactoring tekniği, bir sınıfın işlevlerinin doğruluğunu test etmek
için varsayımlar eklemeyi hedefler. Bu sayede, kodun okunabilirliği artar ve
daha anlaşılır hale getirilir. Ayrıca, bu teknik sayesinde kodun bakımı
kolaylaşır ve hatalar önlenir.
"Convert
Observable to Observer" (Gözlemciye Gözlemleyici Dönüştür) refactoring
tekniği, bir gözlemleyicinin bir olayı gözlemleyip bu olaya uygun bir işlem
yaptıran bir gözlemleyici oluşturarak gözlemleyicilere dönüştürmeyi hedefler.
Bu sayede, kodun okunabilirliği artar ve daha anlaşılır hale getirilir.
Ayrıca, bu teknik sayesinde kodun bakımı kolaylaşır ve hatalar önlenir.
"Convert Collection to List/Set/Map" (Liste/Küme/Harita'ya Koleksiyonu Dönüştür)
refactoring tekniği, bir koleksiyonun işlevlerini bir liste, bir küme veya bir
harita gibi bir yapıda daha uygun bir şekilde gerçekleştirmeyi hedefler. Bu
sayede, kodun okunabilirliği artar ve daha anlaşılır hale getirilir. Ayrıca,
bu teknik sayesinde kodun bakımı kolaylaşır ve hatalar önlenir.
"Change Unidirectional Association to Bidirectional" (Tek Yönlü İlişkiyi Çift
Yönlü İlişkiye Dönüştür) refactoring tekniği, iki sınıf arasındaki tek yönlü
ilişkiyi çift yönlü ilişkiye dönüştürmeyi hedefler. Bu sayede, ilişkiler daha
anlaşılır hale getirilir ve kodun okunabilirliği artar. Ayrıca, bu teknik
sayesinde kodun bakımı kolaylaşır ve hatalar önlenir.
"Replace Array with Object" (Nesne ile Diziyi Değiştir) refactoring tekniği, bir
dizinin yerine bir nesne kullanmayı hedefler. Bu sayede, kodun okunabilirliği
artar ve daha anlaşılır hale getirilir. Ayrıca, bu teknik sayesinde kodun
bakımı kolaylaşır ve hatalar önlenir.
class Order {
private String[] _items;
public String getItem(int index) {
return _items[index];
}
public void setItem(int index, String item) {
_items[index] = item;
}
}
_items dizisini bir Items nesnesiyle değiştirerek bu kodu yeniden düzenleyebilirsiniz:
class Order {
private Items _items;
public String getItem(int index) {
return _items.get(index);
}
public void setItem(int index, String item) {
_items.set(index, item);
}
}
class Items {
private String[] _items;
public String get(int index) {
return _items[index];
}
public void set(int index, String item) {
_items[index] = item;
}
}
"Duplicate Observed Data"
(Gözlenen Veriyi Kopyala) refactoring tekniği, bir nesnenin gözlenen verisini
başka bir nesnenin özelliği olarak kopyalama işlemini hedefler. Bu sayede,
kodun okunabilirliği artar ve daha anlaşılır hale getirilir. Ayrıca, bu teknik
sayesinde kodun bakımı kolaylaşır ve hatalar önlenir.
"Encapsulate Field" (Alanı Kapsülle) refactoring tekniği, bir alanı kapsüllemeyi hedefler.
Bu sayede, alanın kullanımı daha kolay hale getirilir ve kodun okunabilirliği
artar. Ayrıca, bu teknik sayesinde kodun bakımı kolaylaşır ve hatalar
önlenir.
"Encapsulate Collection" (Koleksiyonu Kapsülle) refactoring tekniği, bir koleksiyonu kapsüllemeyi hedefler. Bu sayede,
koleksiyonun kullanımı daha kolay hale getirilir ve kodun okunabilirliği
artar. Ayrıca, bu teknik sayesinde kodun bakımı kolaylaşır ve hatalar
önlenir.
"Extract Superclass" refaktoring tekniğini daha detaylı bir Java kod örneğiyle açıklamaya çalışacağım:
Öncelikle, hangi sınıfların ortak özelliklerini bir süper sınıfa taşımak istediğinizi belirleyin. Örneğin, aşağıdaki iki sınıfın "getName" ve "getAddress" yöntemlerini bir "ContactInfo" süper sınıfına taşımak istiyoruz:
public class Customer {
public String getName() { ... }
public String getAddress() { ... }
// Other methods specific to Customer
}
public class Supplier {
public String getName() { ... }
public String getAddress() { ... }
// Other methods specific to Supplier
}
Süper sınıfı oluşturun ve yöntemleri süper sınıfa taşıyın:
public class ContactInfo {
public String getName() { ... }
public String getAddress() { ... }
}
public class Customer extends ContactInfo {
// Other methods specific to Customer
}
public class Supplier extends ContactInfo {
// Other methods specific to Supplier
}
"Inline Method" (Metodu İçe Aktar) refactoring tekniği,
bir metodun içindeki kodu metodun kullanıldığı yere yerleştirmeyi hedefler. Bu
sayede, metodun okunabilirliği artar ve daha anlaşılır hale getirilir. Ayrıca,
bu teknik sayesinde kodun bakımı kolaylaşır ve hatalar önlenir.
Öncelikle, hangi yöntemlerin satır içi olarak değiştirilmesi gerektiğini belirleyin. Örneğin, aşağıdaki sınıftaki "getDiscountPercentage" yöntemini satır içi olarak "calculateDiscount" yöntemine değiştirmek istiyoruz:
public class DiscountCalculator {
public double calculateDiscount(double amount) {
return amount * getDiscountPercentage();
}
public double getDiscountPercentage() {
// Some complex logic to determine the discount percentage
return 0.1;
}
}
Yöntemi satır içi olarak değiştirin:
public class DiscountCalculator {
public double calculateDiscount(double amount) {
// Some complex logic to determine the discount percentage
return amount * 0.1;
}
}
"Inline Class" (Sınıfı İçe Aktar) refactoring tekniği, bir sınıfın işlevlerini
kullanıldığı yere yerleştirmeyi hedefler. Bu sayede, sınıfın okunabilirliği
artar ve daha anlaşılır hale getirilir. Ayrıca, bu teknik sayesinde kodun
bakımı kolaylaşır ve hatalar önlenir.
to
"Inline Temp" refaktoring tekniğini daha detaylı bir Java kod örneğiyle açıklamaya çalışacağım:
Bu teknik, bir yöntem içinde kullanılan geçici değişkenleri satır içi olarak değiştirerek daha okunabilir ve anlaşılır bir yapı oluşturmayı amaçlar.
Öncelikle, hangi geçici değişkenlerin satır içi olarak değiştirilmesi gerektiğini belirleyin. Örneğin, aşağıdaki sınıftaki "basePrice" geçici değişkenini satır içi olarak "calculateTotalPrice" yönteminde kullanılacak şekilde değiştirmek istiyoruz:
public class Order {
public double calculateTotalPrice() {
double basePrice = getBasePrice();
return basePrice * getDiscountFactor();
}
public double getBasePrice() { ... }
public double getDiscountFactor() { ... }
}
Geçici değişkeni satır içi olarak değiştirin:
public class Order {
public double calculateTotalPrice() {
return getBasePrice() * getDiscountFactor();
}
public double getBasePrice() { ... }
public double getDiscountFactor() { ... }
}
"Move Field" refaktoring tekniğini daha detaylı bir Java kod örneğiyle açıklamaya çalışacağım:
Bu teknik, bir sınıftaki alanları daha mantıklı bir sınıfa taşıyarak daha okunabilir ve anlaşılır bir yapı oluşturmayı amaçlar.
Öncelikle, hangi alanların taşınması gerektiğini belirleyin. Örneğin, aşağıdaki sınıftaki "taxRate" alanını "Customer" sınıfından "TaxCalculator" sınıfına taşımak istiyoruz:
public class Customer {
public double taxRate;
// Other methods and fields specific to Customer
}
public class TaxCalculator {
// Other methods specific to TaxCalculator
}
Alanı taşıyın ve gerekli değişiklikleri yapın:
public class Customer {
// Other methods and fields specific to Customer
}
public class TaxCalculator {
public double taxRate;
// Other methods specific to TaxCalculator
}
public class Order {
public double calculateTotalPrice() {
double basePrice = getBasePrice();
if (basePrice > 1000) {
return basePrice * 0.9;
} else {
return basePrice * 0.95;
}
}
public double getBasePrice() { ... }
}
Geçici değişkeni sorgu ile değiştirin:
public class Order {
public double calculateTotalPrice() {
if (getBasePrice() > 1000) {
return getBasePrice() * 0.9;
} else {
return getBasePrice() * 0.95;
}
}
public double getBasePrice() { ... }
}
public class Rectangle {
public double calculateArea() {
double temp = height * width;
return temp / 2;
}
public double height;
public double width;
}
Geçici değişkeni parçalara bölün:
public class Rectangle {
public double calculateArea() {
double halfHeight = height / 2;
double halfWidth = width / 2;
return halfHeight * halfWidth;
}
public double height;
public double width;
}
public class Order {
public double calculateDiscount(double discountPercentage) {
discountPercentage = Math.max(discountPercentage, 0);
discountPercentage = Math.min(discountPercentage, 100);
return getBasePrice() * (discountPercentage / 100);
}
public double getBasePrice() { ... }
}
Parametre atamasını kaldırın:
public class Order {
public double calculateDiscount(double discountPercentage) {
discountPercentage = Math.max(discountPercentage, 0);
discountPercentage = Math.min(discountPercentage, 100);
double finalDiscountPercentage = discountPercentage;
return getBasePrice() * (finalDiscountPercentage / 100);
}
public double getBasePrice() { ... }
}
public class Person {
public String name;
public String address;
// Other methods and fields specific to Person
}
Özellikleri ayrı bir sınıfa taşıyın ve gerekli değişiklikleri yapın:
public class Person {
private NameAndAddress nameAndAddress;
// Other methods and fields specific to Person
public Person(String name, String address) {
this.nameAndAddress = new NameAndAddress(name, address);
}
public String getName() {
return nameAndAddress.getName();
}
public String getAddress() {
return nameAndAddress.getAddress();
}
}
public class NameAndAddress {
private String name;
private String address;
public NameAndAddress(String name, String address) {
this.name = name;
this.address = address;
}
public String getName() {
return name;
}
public String getAddress