OCP etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
OCP etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

Java Stream'de map() ile flatMap() arasındaki farkın örnek bir senaryo ile anlatımı



Elbette, Java Stream API'de bulunan map ve flatMap metodları arasındaki farkı bir senaryo üzerinden açıklayabilirim. Öncelikle bu iki fonksiyonun genel tanımlarını yapalım:


map: Bu işlev, belirli bir fonksiyonu akışın (Stream) her bir elemanına uygular ve işlenmiş elemanlardan oluşan yeni bir akış oluşturur.

flatMap: Bu işlev, her bir girdi öğesini birden çok çıktı öğesiyle eşleyen bir işlevi uygular ve tüm çıktıları tek bir "düz" akışa (Stream) dönüştürür.

Senaryomuz ise bir kitaplık üzerine olsun:


java

Copy code

class Book {

    private String name;

    private List<String> authors;


    // constructor, getters, setters 

}

Diyelim ki, bir List<Book> koleksiyonunuz var ve her bir kitabın adını büyük harflerle elde etmek istiyorsunuz. İşte burada map fonksiyonunu kullanabiliriz.


java

Copy code

List<Book> books = //...

List<String> bookNames = books.stream()

                            .map(book -> book.getName().toUpperCase())

                            .collect(Collectors.toList());

map fonksiyonu, kitap adını alır ve büyük harflerle dönüştürür. Sonuç olarak, büyük harflerle kitap adlarının listesini alırız.


Şimdi, her bir kitabın yazarlarının listesini almak istediğimizi düşünelim. Burada flatMap kullanabiliriz çünkü her kitabın birden çok yazarı olabilir ve biz tüm yazarları tek bir liste haline getirmek istiyoruz.


java

Copy code

List<String> authors = books.stream()

                            .flatMap(book -> book.getAuthors().stream())

                            .collect(Collectors.toList());

flatMap, kitabın yazarlarının listesini alır ve bu listeleri tek bir liste haline getirir. Sonuç olarak, kitaplıkta bulunan tüm yazarların tek bir listesini elde ederiz.


Yani kısaca, map her bir elemanı tek bir elemana dönüştürürken, flatMap her bir elemanı birden çok elemana (ve bunları tek bir akış haline getirecek şekilde) dönüştürebilir.


Bir başka örnek


ChatGPT

Bu iki fonksiyonun farkını daha da açıkça görmek için birkaç örnek daha ele alalım.


Map örneği

Örneğin, bir sayı listesinin her elemanını karesi ile değiştirmek isteyelim:


java

Copy code

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);

List<Integer> squares = numbers.stream()

                               .map(n -> n * n)

                               .collect(Collectors.toList());


System.out.println(squares); // [1, 4, 9, 16, 25]

Burada, map fonksiyonunu kullanarak her sayının karesini hesapladık ve sonuç olarak karelerin listesini elde ettik.


FlatMap örneği

Şimdi biraz daha karmaşık bir senaryoya bakalım. Diyelim ki bir List<List<Integer>> veri yapısına sahipsiniz ve bunu düz bir List<Integer> listesine dönüştürmek istiyorsunuz.


java

Copy code

List<List<Integer>> listOfLists = Arrays.asList(Arrays.asList(1, 2, 3), Arrays.asList(4, 5, 6));


List<Integer> flatList = listOfLists.stream()

                                    .flatMap(List::stream)

                                    .collect(Collectors.toList());


System.out.println(flatList); // [1, 2, 3, 4, 5, 6]

Burada, flatMap fonksiyonu, iç içe geçmiş listeleri düz bir listeye dönüştürdü. Her bir alt listeyi ayrı bir akışa dönüştürdü ve bunları tek bir akışa birleştirdi.


Sonuç olarak, map ve flatMap arasındaki temel fark, map'in her bir girdi öğesini tek bir çıktı öğesiyle eşlemesi, flatMap'in ise her girdi öğesini birden çok çıktı öğesiyle (bir akış) eşlemesi ve tüm çıktıları tek bir "düz" akışa dönüştürmesidir.

Java'da zaman ve tarihle ilgili tüm api'ler sınıflar metotlar, senaryo ve java kod örnekleri ile detaylı anlatım.


Java 17'de zaman ve tarihle ilgili API'ler, genelde java.time paketi altında toplanır. Bu paket, JSR-310 özelliklerini içerir ve Java 8 ile tanıtılmıştır. Bu özellikler arasında yerel tarih, yerel saat, zaman dilimi ve tarih aralığı bulunur. Ayrıca tarih ve saatler arasında dönüştürme, biçimlendirme ve ayrıştırma işlemleri de bulunur.



Yerel Tarih ve Saat:


java.time.LocalDate ve java.time.LocalTime sınıflarını kullanarak yerel tarih ve saati elde edebilirsiniz.


Örneğin;


java

Copy code

import java.time.LocalDate;

import java.time.LocalTime;


public class Main {

    public static void main(String[] args) {

        LocalDate date = LocalDate.now();

        System.out.println("Bugünün tarihi: " + date);

        

        LocalTime time = LocalTime.now();

        System.out.println("Şu anki saat: " + time);

    }

}

Zaman Dilimi ile Tarih ve Saat:


java.time.ZonedDateTime sınıfı, zaman dilimi bilgisi ile tarih ve saati temsil eder.


Örneğin;


java

Copy code

import java.time.ZonedDateTime;

import java.time.ZoneId;


public class Main {

    public static void main(String[] args) {

        ZonedDateTime dateTime = ZonedDateTime.now(ZoneId.of("Europe/Istanbul"));

        System.out.println("İstanbul'daki tarih ve saat: " + dateTime);

    }

}

Tarih Aralığı:


java.time.Period ve java.time.Duration sınıfları, iki tarih veya saat arasındaki süreyi temsil eder.


Örneğin;


java

Copy code

import java.time.LocalDate;

import java.time.Period;


public class Main {

    public static void main(String[] args) {

        LocalDate startDate = LocalDate.of(2023, 1, 1);

        LocalDate endDate = LocalDate.of(2023, 12, 31);

        

        Period period = Period.between(startDate, endDate);

        System.out.println("Bu yılın gün sayısı: " + period.getDays());

    }

}

Tarih ve Saat Dönüştürme, Biçimlendirme ve Ayrıştırma:


java.time.format.DateTimeFormatter sınıfı, tarih ve saat biçimlendirmesi ve ayrıştırma işlemlerini yapar.


Örneğin;


java

Copy code

import java.time.LocalDateTime;

import java.time.format.DateTimeFormatter;


public class Main {

    public static void main(String[] args) {

        LocalDateTime dateTime = LocalDateTime.now();

        

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss");

        String formattedDateTime = dateTime.format(formatter);

        

        System.out.println("Biçimlendirilmiş tarih ve saat: " + formattedDateTime);

        

        LocalDateTime parsedDateTime = LocalDateTime.parse(formattedDateTime, formatter);

        System.out.println("Ayrıştırılmış tarih ve saat: " + parsedDateTime);

    }

}

Bu temel kullanımların yanı sıra java.time paketi, daha fazla ihtiyaçları karşılayacak bir dizi API sunar. Ayrıca tarih ve saatlerle ilgili daha karmaşık işlemler için ek API'ler ve sınıflar sunar. Örneğin, java.time.Instant sınıfı, Epoch'tan (1970-01-01T00:00:00Z) bu yana geçen süreyi temsil eder. Diğer tüm tarih ve saat sınıfları, bu anlık zamanla uyumludur. Bu, tarih ve saatler arasında dönüştürme işlemlerini kolaylaştırır.


Bunlarla ilgili daha fazla bilgiye ihtiyacınız olursa veya belirli bir senaryoya göre Java tarih ve saat API'lerini kullanmak hakkında daha fazla bilgi almak isterseniz, bana söyleyin

Tarih ve Saat Düzenlemesi


LocalDate, LocalTime ve LocalDateTime sınıflarının plus ve minus metotları, tarih ve saat düzenlemeleri yapabilirsiniz.


Örneğin, mevcut tarihe 5 gün eklemek için;


java

Copy code

import java.time.LocalDate;


public class Main {

    public static void main(String[] args) {

        LocalDate today = LocalDate.now();

        LocalDate futureDate = today.plusDays(5);

        System.out.println("5 gün sonraki tarih: " + futureDate);

    }

}

Benzer şekilde, belirli bir süre eklemek veya çıkarmak için plus veya minus metodlarını kullanabiliriz.


Tarih ve Saat Karşılaştırmaları


Tarih ve saatleri karşılaştırmak için isBefore, isAfter ve isEqual metodları kullanılabilir.


Örneğin;


java

Copy code

import java.time.LocalDate;


public class Main {

    public static void main(String[] args) {

        LocalDate today = LocalDate.now();

        LocalDate tomorrow = today.plusDays(1);

        

        if (tomorrow.isAfter(today)) {

            System.out.println("Yarın, bugünden sonradır.");

        }

        

        if (today.isBefore(tomorrow)) {

            System.out.println("Bugün, yarıdan öncedir.");

        }

        

        if (today.isEqual(today)) {

            System.out.println("Bugün, bugüne eşittir.");

        }

    }

}

Zaman Dilimleri


Java 8 ile gelen ZoneId sınıfı, dünyanın farklı bölgelerindeki saat dilimlerini temsil eder. ZonedDateTime sınıfını kullanarak belirli bir saat dilimindeki anlık tarihi ve saati elde edebilirsiniz.


Örneğin;


java

Copy code

import java.time.ZoneId;

import java.time.ZonedDateTime;


public class Main {

    public static void main(String[] args) {

        ZonedDateTime istanbulTime = ZonedDateTime.now(ZoneId.of("Europe/Istanbul"));

        System.out.println("İstanbul'daki şu anki saat: " + istanbulTime);

    }

}

Bu kod, İstanbul'daki anlık tarih ve saati verir.


Tarih ve Saat Biçimlendirme


Tarih ve saat nesnelerini belirli bir formatla dizeye dönüştürmek için DateTimeFormatter sınıfını kullanabiliriz.


Örneğin;


java

Copy code

import java.time.LocalDateTime;

import java.time.format.DateTimeFormatter;


public class Main {

    public static void main(String[] args) {

        LocalDateTime now = LocalDateTime.now();

        

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss");

        String formattedNow = now.format(formatter);

        

        System.out.println("Biçimlendirilmiş tarih ve saat: " + formattedNow);

    }

}

Bu kod, şimdiki tarihi ve saati "dd-MM-yyyy HH:mm:ss" formatına dönüştürür.


Bu özellikler, Java'nın tarih ve saat API'sinin temel işlevlerini sağlar. Daha karmaşık işlemler için, java.time paketinin diğer sınıfları ve metotlarına bakabilirsiniz. Örneğin, ChronoUnit sınıfı, iki tarih veya saat arasındaki zaman farkını belirli bir zaman birimine göre hesaplamanıza olanak sağlar.


ChronoUnit Sınıfı


ChronoUnit sınıfı, tarihler arasındaki farkı belirli bir zaman birimine göre hesaplamanıza olanak sağlar.


Örneğin, iki tarih arasındaki gün sayısını hesaplamak için;


java

Copy code

import java.time.LocalDate;

import java.time.temporal.ChronoUnit;


public class Main {

    public static void main(String[] args) {

        LocalDate startDate = LocalDate.of(2023, 1, 1);

        LocalDate endDate = LocalDate.of(2023, 12, 31);

        

        long daysBetween = ChronoUnit.DAYS.between(startDate, endDate);

        System.out.println("Bu yılın gün sayısı: " + daysBetween);

    }

}

Clock Sınıfı


java.time.Clock sınıfı, mevcut anlık tarih ve saati almanızı sağlar.


java

Copy code

import java.time.Clock;

import java.time.Instant;


public class Main {

    public static void main(String[] args) {

        Clock clock = Clock.systemUTC();

        Instant instant = clock.instant();

        

        System.out.println("Anlık tarih ve saat: " + instant);

    }

}

Year, YearMonth ve MonthDay Sınıfları


Bu sınıflar, yıl, ay ve gün gibi belirli tarih parçalarıyla çalışmanızı sağlar.


java

Copy code

import java.time.MonthDay;

import java.time.Year;

import java.time.YearMonth;


public class Main {

    public static void main(String[] args) {

        Year currentYear = Year.now();

        System.out.println("Bu yıl: " + currentYear);

        

        YearMonth currentYearMonth = YearMonth.now();

        System.out.println("Bu yıl ve ay: " + currentYearMonth);

        

        MonthDay currentMonthDay = MonthDay.now();

        System.out.println("Bu ay ve gün: " + currentMonthDay);

    }

}

Timestamp ve Instant Sınıfları


Epoch'tan (1970-01-01T00:00:00Z) bu yana geçen süreyi temsil etmek için Instant sınıfı kullanılabilir. Instant sınıfı, nanosaniye hassasiyetine sahip tarih ve saat bilgisi sağlar.


java

Copy code

import java.time.Instant;


public class Main {

    public static void main(String[] args) {

        Instant now = Instant.now();

        System.out.println("Anlık zaman: " + now);

        

        long epochSecond = now.getEpochSecond();

        System.out.println("Epoch'tan bu yana geçen saniye: " + epochSecond);

        

        int nano = now.getNano();

        System.out.println("Nanosaniye: " + nano);

    }

}

Java'nın java.time paketi, daha pek çok işlem için API'ler ve sınıflar sunar. Belirli bir senaryo hakkında daha fazla bilgiye ihtiyacınız varsa veya belirli bir sorunuz varsa, bana bildirin.


Daha fazla detaya gidelim. Aşağıdaki örnekler, daha karmaşık ve belirli senaryolar için zaman ve tarihle ilgili kullanışlı Java kodlarını içerir.


Java’da Geçerli Zaman Damgasını Alma


java.time paketindeki Instant sınıfı, zaman damgasını almak için kullanılır. Zaman damgası, belirli bir zaman diliminde geçen süreyi temsil eder ve genellikle loglarda ve zamanlama işlemlerinde kullanılır.


java

Copy code

import java.time.Instant;


public class Main {

    public static void main(String[] args) {

        Instant timestamp = Instant.now();

        System.out.println("Geçerli Zaman Damgası: " + timestamp);

    }

}

Java’da Geçerli Zaman Damgasını Unix Zamanı Olarak Alma


Unix zamanı, 1 Ocak 1970 UTC tarihinden bu yana geçen saniyeyi temsil eder. Unix zaman damgası, genellikle birçok sistem ve platform arasında tarih ve saat bilgilerini paylaşmak için kullanılır.


java

Copy code

import java.time.Instant;


public class Main {

    public static void main(String[] args) {

        Instant instant = Instant.now();

        long unixTimestamp = instant.getEpochSecond();

        System.out.println("Geçerli Unix Zaman Damgası: " + unixTimestamp);

    }

}

Java’da İki Tarih Arasındaki Farkı Hesaplama


java.time paketindeki Period sınıfı, iki tarih arasındaki farkı hesaplamak için kullanılır.


java

Copy code

import java.time.LocalDate;

import java.time.Period;


public class Main {

    public static void main(String[] args) {

        LocalDate dateOfBirth = LocalDate.of(1990, 2, 1);

        LocalDate currentDate = LocalDate.now();

        

        Period age = Period.between(dateOfBirth, currentDate);

        

        System.out.printf("Yaş: %d yıl, %d ay, %d gün\n", age.getYears(), age.getMonths(), age.getDays());

    }

}

Java’da İki Zaman Arasındaki Farkı Hesaplama


java.time paketindeki Duration sınıfı, iki zaman arasındaki farkı hesaplamak için kullanılır.


java

Copy code

import java.time.Duration;

import java.time.LocalTime;


public class Main {

    public static void main(String[] args) {

        LocalTime startTime = LocalTime.of(1, 20, 25, 1024);

        LocalTime endTime = LocalTime.now();

        

        Duration duration = Duration.between(startTime, endTime);

        

        System.out.println("Fark: " + duration.getSeconds() + " saniye");

    }

}

Java’da Tarih ve Zamanı Biçimlendirme


java.time.format.DateTimeFormatter sınıfı, tarih ve zamanı biçimlendirmek için kullanılır.


java

Copy code

import java.time.LocalDateTime;

import java.time.format.DateTimeFormatter;


public class Main {

    public static void main(String[] args) {

        LocalDateTime dateTime = LocalDateTime.now();

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss");

        

        String formattedDateTime = dateTime.format(formatter);

        

        System.out.println("Biçimlendirilmiş Tarih ve Saat: " + formattedDateTime);

    }

}

Bu örnekler, Java'nın java.time paketinin çeşitli işlevlerini ve kullanımlarını gösterir. Daha fazla senaryoyu tartışmak veya belirli bir konuda daha fazla bilgi almak için bana bildirin.


Elbette, tarih ve saatle ilgili işlemlere devam edelim. Aşağıdaki örnekler, java.time paketi ile birlikte gelen bazı diğer kullanışlı sınıflar ve metodları gösterir.


DayOfWeek ve Month Sınıfları


DayOfWeek ve Month sınıfları enum türünde olup haftanın günlerini ve yılın aylarını temsil ederler. Bu sınıflarla yapılan bazı basit işlemler aşağıda gösterilmiştir.


java

Copy code

import java.time.DayOfWeek;

import java.time.Month;


public class Main {

    public static void main(String[] args) {

        DayOfWeek day = DayOfWeek.MONDAY;

        System.out.println(day); // MONDAY

        System.out.println(day.getValue()); // 1


        Month month = Month.DECEMBER;

        System.out.println(month); // DECEMBER

        System.out.println(month.getValue()); // 12

    }

}

TemporalAdjusters Sınıfı


TemporalAdjusters sınıfı, belirli bir tarihle ilgili çeşitli ayarlamalar yapmamıza olanak sağlar. Aşağıdaki örnekte, mevcut ayın ilk ve son günlerine nasıl ulaşıldığı gösterilmiştir.


java

Copy code

import java.time.LocalDate;

import java.time.temporal.TemporalAdjusters;


public class Main {

    public static void main(String[] args) {

        LocalDate today = LocalDate.now();


        LocalDate firstDayOfMonth = today.with(TemporalAdjusters.firstDayOfMonth());

        System.out.println("Bu ayın ilk günü: " + firstDayOfMonth);


        LocalDate lastDayOfMonth = today.with(TemporalAdjusters.lastDayOfMonth());

        System.out.println("Bu ayın son günü: " + lastDayOfMonth);

    }

}

DST (Daylight Saving Time) ve ZonedDateTime


Java'da yaz saati uygulamasını işlemek için ZonedDateTime kullanılır. Aşağıdaki örnekte, yaz saati uygulamasının bir etkisi olduğu bir zaman dilimindeki yerel bir tarihin UTC'ye nasıl çevrildiği gösterilmektedir.


java

Copy code

import java.time.LocalDateTime;

import java.time.ZoneId;

import java.time.ZonedDateTime;

import java.time.format.DateTimeFormatter;


public class Main {

    public static void main(String[] args) {

        LocalDateTime localDateTime = LocalDateTime.of(2023, 3, 26, 1, 30);

        ZonedDateTime zonedDateTime = ZonedDateTime.of(localDateTime, ZoneId.of("Europe/Istanbul"));


        ZonedDateTime utcDateTime = zonedDateTime.withZoneSameInstant(ZoneId.of("UTC"));

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm:ss Z");


        System.out.println("Yerel tarih ve saat: " + formatter.format(zonedDateTime));

        System.out.println("UTC'ye dönüştürülmüş tarih ve saat: " + formatter.format(utcDateTime));

    }

}

Bu örnekler, Java'nın java.time paketi ile birlikte gelen bazı ek özelliklerin ve yeteneklerin bir özetidir. Her türlü sorunuz veya belirli bir konuda daha fazla bilgi almak için bana başvurabilirsiniz.


Tarihleri Karşılaştırma


Belirli bir tarihle mevcut tarihi karşılaştırmak oldukça yaygın bir işlemdir. Aşağıdaki kod, bir tarihin bugünden önce mi yoksa sonra mı olduğunu kontrol eder:


java

Copy code

import java.time.LocalDate;


public class Main {

    public static void main(String[] args) {

        LocalDate givenDate = LocalDate.of(2030, 1, 1);

        LocalDate today = LocalDate.now();


        if (givenDate.isAfter(today)) {

            System.out.println("Verilen tarih bugünden sonradır.");

        } else if (givenDate.isBefore(today)) {

            System.out.println("Verilen tarih bugünden öncedir.");

        } else {

            System.out.println("Verilen tarih bugündür.");

        }

    }

}

Java’da Geçmiş Tarihleri Belirleme ve Karşılaştırma


LocalDate sınıfı, geçmiş tarihlerin oluşturulmasına ve karşılaştırılmasına olanak sağlar. Aşağıdaki örnekte, belirli bir tarihin belirli bir başka tarihten önce mi sonra mı olduğu kontrol edilir:


java

Copy code

import java.time.LocalDate;


public class Main {

    public static void main(String[] args) {

        LocalDate date1 = LocalDate.of(2020, 1, 1);

        LocalDate date2 = LocalDate.of(2021, 1, 1);


        if (date1.isBefore(date2)) {

            System.out.println("İlk tarih, ikinci tarihten öncedir.");

        } else if (date1.isAfter(date2)) {

            System.out.println("İlk tarih, ikinci tarihten sonradır.");

        } else {

            System.out.println("Tarihler aynıdır.");

        }

    }

}

Tarihe Belirli Bir Süre Ekleme veya Çıkarma


Belirli bir tarihe belirli bir süre eklemek veya çıkarmak genellikle gereklidir. Aşağıdaki örnek, bir tarihe belirli bir sayıda gün ekler:


java

Copy code

import java.time.LocalDate;


public class Main {

    public static void main(String[] args) {

        LocalDate today = LocalDate.now();

        LocalDate futureDate = today.plusDays(10);

        System.out.println("10 gün sonraki tarih: " + futureDate);

    }

}

Aynı şekilde, bir tarihten belirli bir sayıda gün çıkarmak için minusDays metodunu kullanabiliriz:


java

Copy code

import java.time.LocalDate;


public class Main {

    public static void main(String[] args) {

        LocalDate today = LocalDate.now();

        LocalDate pastDate = today.minusDays(10);

        System.out.println("10 gün önceki tarih: " + pastDate);

    }

}

Java’nın java.time paketi çok kapsamlıdır ve bu konuda daha fazla detay ve senaryo var. Belirli bir senaryo hakkında daha fazla bilgiye ihtiyacınız varsa veya belirli bir sorunuz varsa,


Elbette, java.time paketi hakkında daha fazla ayrıntıya girelim. Aşağıda, saatler, dakikalar ve saniyelerle ilgili birkaç kullanışlı işlemi bulacaksınız.


Belirli bir Saati Ayarlama


Belirli bir saat ayarlamak için LocalTime sınıfını kullanabilirsiniz. Aşağıdaki örnek, belirli bir saati ayarlar ve basar:


java

Copy code

import java.time.LocalTime;


public class Main {

    public static void main(String[] args) {

        LocalTime specificTime = LocalTime.of(12, 30, 15);

        System.out.println("Belirli saat: " + specificTime);

    }

}

Mevcut Saati Alma


Geçerli saati almak için LocalTime sınıfının now metodunu kullanabilirsiniz. Aşağıdaki örnek, mevcut saati alır ve basar:


java

Copy code

import java.time.LocalTime;


public class Main {

    public static void main(String[] args) {

        LocalTime currentTime = LocalTime.now();

        System.out.println("Mevcut saat: " + currentTime);

    }

}

Saate Belirli Bir Süre Ekleme veya Çıkarma


Bir saate belirli bir süre eklemek veya çıkarmak genellikle gereklidir. Aşağıdaki örnek, mevcut saate belirli bir sayıda saat ekler:


java

Copy code

import java.time.LocalTime;


public class Main {

    public static void main(String[] args) {

        LocalTime currentTime = LocalTime.now();

        LocalTime futureTime = currentTime.plusHours(2);

        System.out.println("2 saat sonraki saat: " + futureTime);

    }

}

Aynı şekilde, bir saatten belirli bir sayıda saat çıkarmak için minusHours metodunu kullanabiliriz:


java

Copy code

import java.time.LocalTime;


public class Main {

    public static void main(String[] args) {

        LocalTime currentTime = LocalTime.now();

        LocalTime pastTime = currentTime.minusHours(2);

        System.out.println("2 saat önceki saat: " + pastTime);

    }

}

Bu örnekler, java.time paketi kullanılarak zamanla ilgili birçok işlemin nasıl gerçekleştirileceğini gösterir. Her türlü sorunuz veya belirli bir konuda daha fazla bilgi almak için bana başvurabilirsiniz.


Belirli bir Tarih ve Saati Ayarlama


Bazen belirli bir tarih ve saat ayarlamamız gerekebilir. Bu durumda, LocalDateTime sınıfını kullanabiliriz. Aşağıdaki örnekte, belirli bir tarih ve saat ayarlanmıştır:


java

Copy code

import java.time.LocalDateTime;


public class Main {

    public static void main(String[] args) {

        LocalDateTime specificDateTime = LocalDateTime.of(2023, 12, 25, 15, 30);

        System.out.println("Belirli tarih ve saat: " + specificDateTime);

    }

}

Mevcut Tarih ve Saati Alma


Mevcut tarih ve saati almak için LocalDateTime sınıfının now metodunu kullanabiliriz. Aşağıdaki örnek, mevcut tarih ve saati alır ve basar:


java

Copy code

import java.time.LocalDateTime;


public class Main {

    public static void main(String[] args) {

        LocalDateTime currentDateTime = LocalDateTime.now();

        System.out.println("Mevcut tarih ve saat: " + currentDateTime);

    }

}

Belirli bir Tarih ve Saate Belirli Bir Süre Ekleme veya Çıkarma


Bir tarih ve saate belirli bir süre eklemek veya çıkarmak genellikle gereklidir. Aşağıdaki örnekte, mevcut tarih ve saate belirli bir sayıda saat eklenir:


java

Copy code

import java.time.LocalDateTime;


public class Main {

    public static void main(String[] args) {

        LocalDateTime currentDateTime = LocalDateTime.now();

        LocalDateTime futureDateTime = currentDateTime.plusHours(2);

        System.out.println("2 saat sonraki tarih ve saat: " + futureDateTime);

    }

}

Aynı şekilde, bir tarih ve saatten belirli bir sayıda saat çıkarmak için minusHours metodunu kullanabiliriz:


java

Copy code

import java.time.LocalDateTime;


public class Main {

    public static void main(String[] args) {

        LocalDateTime currentDateTime = LocalDateTime.now();

        LocalDateTime pastDateTime = currentDateTime.minusHours(2);

        System.out.println("2 saat önceki tarih ve saat: " + pastDateTime);

    }

}

Bu örnekler, java.time paketi kullanılarak tarih ve saatle ilgili birçok işlemin nasıl gerçekleştirilebileceğini göstermektedir. Her türlü sorunuz veya belirli bir konuda daha fazla bilgi almak için bana başvurabilirsiniz.


Tabii ki, java.time paketi hakkındaki bu ayrıntılı incelememizi genişleterek devam edelim. Aşağıda, yıl, ay ve gün arasındaki farkı hesaplama gibi daha karmaşık senaryoları ele alacağım.


Yıl, Ay ve Gün Arasındaki Farkı Hesaplama


Java'da iki tarih arasındaki farkı hesaplamanın çeşitli yolları vardır. Bunlardan biri, java.time.temporal.ChronoUnit sınıfını kullanmaktır. Bu sınıf, iki tarih arasındaki farkı belirli bir zaman biriminde hesaplamanıza olanak sağlar. Aşağıda, iki tarih arasındaki yıl, ay ve gün farkını hesaplayan bir örneği görebilirsiniz:


java

Copy code

import java.time.LocalDate;

import java.time.temporal.ChronoUnit;


public class Main {

    public static void main(String[] args) {

        LocalDate date1 = LocalDate.of(2020, 1, 1);

        LocalDate date2 = LocalDate.of(2023, 7, 2);


        long yearsBetween = ChronoUnit.YEARS.between(date1, date2);

        long monthsBetween = ChronoUnit.MONTHS.between(date1, date2);

        long daysBetween = ChronoUnit.DAYS.between(date1, date2);


        System.out.println("Yıl farkı: " + yearsBetween);

        System.out.println("Ay farkı: " + monthsBetween);

        System.out.println("Gün farkı: " + daysBetween);

    }

}

Period ve Duration Sınıfları


Period ve Duration sınıfları, belirli bir zaman aralığını temsil eder. Period, tarih birimleri (yıl, ay, gün) arasındaki farkı temsil ederken, Duration saat, dakika, saniye ve milisaniye gibi zaman birimleri arasındaki farkı temsil eder.


java

Copy code

import java.time.Duration;

import java.time.LocalTime;

import java.time.Period;

import java.time.LocalDate;


public class Main {

    public static void main(String[] args) {

        LocalDate date1 = LocalDate.of(2020, 1, 1);

        LocalDate date2 = LocalDate.of(2023, 7, 2);


        Period periodBetween = Period.between(date1, date2);

        System.out.println("Period: " + periodBetween.getYears() + " yıl " 

                                        + periodBetween.getMonths() + " ay " 

                                        + periodBetween.getDays() + " gün");


        LocalTime time1 = LocalTime.of(6, 30);

        LocalTime time2 = LocalTime.of(10, 15);


        Duration durationBetween = Duration.between(time1, time2);

        System.out.println("Duration: " + durationBetween.toHoursPart() + " saat " 

                                       + durationBetween.toMinutesPart() + " dakika " 

                                       + durationBetween.toSecondsPart() + " saniye");

    }

}

Bu örnekler, java.time paketi kullanılarak zamanla ilgili karmaşık işlemlerin nasıl gerçekleştirilebileceğini göstermektedir. Belirli bir senaryo hakkında daha fazla bilgiye ihtiyacınız varsa veya belirli bir sorunuz varsa, her zaman bana başvurabilirsiniz.

The previous model used in this conversation is unavailable. We've switched you to the latest default model.


Tarih ve Saati Karşılaştırma


Java'nın java.time paketi, tarih ve saatlerin karşılaştırılmasını kolaylaştıran çeşitli metotlar sunar. Aşağıda bu metotların kullanımını görebilirsiniz:


java

Copy code

import java.time.LocalDate;

import java.time.LocalTime;


public class Main {

    public static void main(String[] args) {

        LocalDate date1 = LocalDate.of(2022, 1, 1);

        LocalDate date2 = LocalDate.of(2023, 1, 1);

        

        if (date1.isBefore(date2)) {

            System.out.println("date1, date2'den öncedir.");

        } else if (date1.isAfter(date2)) {

            System.out.println("date1, date2'den sonradır.");

        } else {

            System.out.println("date1, date2'ye eşittir.");

        }

        

        LocalTime time1 = LocalTime.of(10, 30);

        LocalTime time2 = LocalTime.of(12, 0);

        

        if (time1.isBefore(time2)) {

            System.out.println("time1, time2'den öncedir.");

        } else if (time1.isAfter(time2)) {

            System.out.println("time1, time2'den sonradır.");

        } else {

            System.out.println("time1, time2'ye eşittir.");

        }

    }

}

Zaman Dilimlerinde Çalışma


java.time paketi, farklı zaman dilimlerinde çalışmayı da destekler. ZoneId sınıfını kullanarak farklı bir zaman dilimini temsil edebiliriz. Aşağıdaki örnekte, farklı zaman dilimlerinde tarih ve saatleri nasıl elde edebileceğimizi görebilirsiniz:


java

Copy code

import java.time.LocalDateTime;

import java.time.ZoneId;

import java.time.ZonedDateTime;


public class Main {

    public static void main(String[] args) {

        LocalDateTime localDateTime = LocalDateTime.now();

        

        ZoneId newYorkZoneId = ZoneId.of("America/New_York");

        ZonedDateTime newYorkDateTime = ZonedDateTime.of(localDateTime, newYorkZoneId);

        System.out.println("New York: " + newYorkDateTime);

        

        ZoneId londonZoneId = ZoneId.of("Europe/London");

        ZonedDateTime londonDateTime = ZonedDateTime.of(localDateTime, londonZoneId);

        System.out.println("London: " + londonDateTime);

    }

}

Tarih ve Saati Biçimlendirme


java.time.format.DateTimeFormatter sınıfı, tarih ve saatlerin belirli bir biçimde gösterilmesini sağlar. Aşağıdaki örnekte, tarihi ve saati belirli bir biçime göre nasıl biçimlendireceğimizi görebilirsiniz:


java

Copy code

import java.time.LocalDateTime;

import java.time.format.DateTimeFormatter;


public class Main {

    public static void main(String[] args) {

        LocalDateTime dateTime = LocalDateTime.now();

        

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss");

        String formattedDateTime = dateTime.format(formatter);

        

        System.out.println("Biçimlendirilmiş tarih ve saat: " + formattedDateTime);

    }

}

Bu örnekler, java.time paketi kullanarak tarih ve saatlerle ilgili farklı senaryoları ele almanın bazı yol ve yöntemlerini göstermektedir. Herhangi bir sorunuz veya belirli bir senaryo hakkında daha fazla bilgiye ihtiyacınız varsa, her zaman bana başvurabilirsiniz.


Geçerli Tarih ve Saati Biçimlendirme


java.time.format.DateTimeFormatter sınıfı, tarih ve saatleri belirli bir biçime göre biçimlendirmemize olanak sağlar. Aşağıdaki örnekte, geçerli tarihi ve saati belirli bir biçime göre biçimlendiriyoruz:


java

Copy code

import java.time.LocalDateTime;

import java.time.format.DateTimeFormatter;


public class Main {

    public static void main(String[] args) {

        LocalDateTime now = LocalDateTime.now();


        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");

        String formattedDateTime = now.format(formatter);


        System.out.println("Biçimlendirilmiş tarih ve saat: " + formattedDateTime);

    }

}

Tarih ve Saati Ayrıştırma


java.time.format.DateTimeFormatter sınıfını kullanarak, bir metinden tarih ve saat bilgisini ayrıştırabiliriz. Aşağıdaki örnekte, bir metinden tarih ve saat bilgisini ayrıştırıyoruz:


java

Copy code

import java.time.LocalDate;

import java.time.LocalTime;

import java.time.format.DateTimeFormatter;


public class Main {

    public static void main(String[] args) {

        String dateText = "2023-07-02";

        String timeText = "10:30:00";


        DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

        LocalDate date = LocalDate.parse(dateText, dateFormatter);


        DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm:ss");

        LocalTime time = LocalTime.parse(timeText, timeFormatter);


        System.out.println("Ayrıştırılan tarih: " + date);

        System.out.println("Ayrıştırılan saat: " + time);

    }

}

Tarih ve Saati Unix Zaman Damgasına Dönüştürme


Unix zaman damgası, 1970-01-01T00:00:00Z'den bu yana geçen süreyi saniye cinsinden temsil eder. java.time.Instant sınıfı, tarih ve saati Unix zaman damgasına dönüştürmemize olanak sağlar. Aşağıdaki örnekte, bir tarih ve saati Unix zaman damgasına dönüştürüyoruz:


java

Copy code

import java.time.Instant;

import java.time.LocalDateTime;

import java.time.ZoneOffset;


public class Main {

    public static void main(String[] args) {

        LocalDateTime dateTime = LocalDateTime.of(2023, 7, 2, 10, 30, 0);

        Instant instant = dateTime.toInstant(ZoneOffset.UTC);

        long unixTimestamp = instant.getEpochSecond();


        System.out.println("Unix zaman damgası: " + unixTimestamp);

    }

}

Bu örnekler, java.time paketiyle birlikte gelen DateTimeFormatter ve Instant sınıflarının kullanımını göstermektedir. Daha fazla senaryo ve özellik hakkında bilgi almak için bana bildirin.


Tarih ve Saati Sıralama


java.time paketi, tarih ve saatleri sıralamak için compareTo metodu ile birlikte Comparable arayüzünü uygular. Aşağıdaki örnekte, iki tarihi sıralama işlemini görüyoruz:


java

Copy code

import java.time.LocalDate;


public class Main {

    public static void main(String[] args) {

        LocalDate date1 = LocalDate.of(2022, 1, 1);

        LocalDate date2 = LocalDate.of(2023, 1, 1);


        int result = date1.compareTo(date2);


        if (result < 0) {

            System.out.println("date1, date2'den öncedir.");

        } else if (result > 0) {

            System.out.println("date1, date2'den sonradır.");

        } else {

            System.out.println("date1, date2'ye eşittir.");

        }

    }

}

Tarih ve Saatlerin Doğruluğunu Kontrol Etme


java.time paketi, tarih ve saatlerin doğruluğunu kontrol etmek için LocalDate, LocalTime ve LocalDateTime sınıflarında of ve is metotlarını kullanır. Aşağıdaki örnekte, bir tarih ve saat kombinasyonunun geçerli olup olmadığını kontrol ediyoruz:


java

Copy code

import java.time.LocalDate;

import java.time.LocalTime;

import java.time.LocalDateTime;


public class Main {

    public static void main(String[] args) {

        LocalDate date = LocalDate.of(2023, 2, 30);

        boolean isValidDate = date.isSupported(LocalDate.now().toLocalDate().getChronology().dateNow());


        LocalTime time = LocalTime.of(25, 30);

        boolean isValidTime = time.isSupported(LocalTime.now().toLocalTime().getChronology().timeNow());


        LocalDateTime dateTime = LocalDateTime.of(2023, 2, 30, 25, 30);

        boolean isValidDateTime = dateTime.isSupported(LocalDateTime.now().toLocalDateTime().getChronology().dateTimeNow());


        System.out.println("Geçerli tarih: " + isValidDate);

        System.out.println("Geçerli saat: " + isValidTime);

        System.out.println("Geçerli tarih ve saat: " + isValidDateTime);

    }

}

Tarih ve Saat Aralıklarını Kontrol Etme


java.time paketi, belirli bir tarih veya saatin belirli bir aralıkta olup olmadığını kontrol etmek için isAfter ve isBefore metotlarını kullanır. Aşağıdaki örnekte, bir tarih ve saat aralığının kontrolünü görüyoruz:


java

Copy code

import java.time.LocalDate;

import java.time.LocalTime;


public class Main {

    public static void main(String[] args) {

        LocalDate date = LocalDate.now();

        LocalDate startDate = LocalDate.of(2023, 1, 1);

        LocalDate endDate = LocalDate.of(2023, 12, 31);


        boolean isDateInRange = date.isAfter(startDate) && date.isBefore(endDate);


        LocalTime time = LocalTime.now();

        LocalTime startTime = LocalTime.of(9, 0);

        LocalTime endTime = LocalTime.of(17, 0);


        boolean isTimeInRange = time.isAfter(startTime) && time.isBefore(endTime);


        System.out.println("Tarih aralığında mı: " + isDateInRange);

        System.out.println("Saat aralığında mı: " + isTimeInRange);

    }

}

Bu örnekler, java.time paketinin sunduğu tarih ve saatlerle ilgili daha fazla kullanım senaryosunu göstermektedir. Herhangi bir sorunuz veya belirli bir senaryo hakkında daha fazla bilgiye ihtiyacınız varsa, bana bildirebilirsiniz.


Kod örnekleri ile Java date time mülakat soruları ve cevapları


Java'da tarih ve saatle ilgili mülakat sorularına cevap vermek için bazı kod örnekleri sunabilirim. İşte yaygın olarak sorulan bazı sorular ve bu sorulara verilebilecek cevaplara örnekler:


Soru 1: Java'da bir tarih nasıl oluşturulur ve temsil edilir?


Örnek Cevap 1:


java

Copy code

// LocalDate sınıfıyla bir tarih oluşturulabilir

LocalDate date = LocalDate.of(2022, 10, 15);

Örnek Cevap 2:


java

Copy code

// Şu anki tarihi temsil eden LocalDate nesnesini alabiliriz

LocalDate currentDate = LocalDate.now();

Soru 2: Java'da bir saat nasıl oluşturulur ve temsil edilir?


Örnek Cevap 1:


java

Copy code

// LocalTime sınıfıyla bir saat oluşturulabilir

LocalTime time = LocalTime.of(15, 30);

Örnek Cevap 2:


java

Copy code

// Şu anki saati temsil eden LocalTime nesnesini alabiliriz

LocalTime currentTime = LocalTime.now();

Soru 3: Java'da bir tarih ve saat nasıl oluşturulur ve temsil edilir?


Örnek Cevap 1:


java

Copy code

// LocalDateTime sınıfıyla bir tarih ve saat kombinasyonu oluşturulabilir

LocalDateTime dateTime = LocalDateTime.of(2022, 10, 15, 15, 30);

Örnek Cevap 2:


java

Copy code

// Şu anki tarih ve saati temsil eden LocalDateTime nesnesini alabiliriz

LocalDateTime currentDateTime = LocalDateTime.now();

Soru 4: İki tarih arasındaki farkı nasıl hesaplarız?


Örnek Cevap:


java

Copy code

LocalDate date1 = LocalDate.of(2022, 10, 15);

LocalDate date2 = LocalDate.of(2023, 3, 1);


long daysBetween = ChronoUnit.DAYS.between(date1, date2);

System.out.println("İki tarih arasındaki gün farkı: " + daysBetween);

Soru 5: Tarihe belirli bir süre eklemek veya çıkarmak için nasıl yaparız?


Örnek Cevap:


java

Copy code

LocalDate date = LocalDate.now();

LocalDate futureDate = date.plusDays(7);

LocalDate pastDate = date.minusMonths(1);


System.out.println("7 gün sonrası: " + futureDate);

System.out.println("1 ay öncesi: " + pastDate);

Bu örnekler, Java'da tarih ve saatle ilgili mülakat sorularına verilebilecek bazı cevaplara örneklerdir. Herhangi başka bir sorunuz veya daha fazla bilgiye ihtiyacınız varsa, bana bildirebilirsiniz.


Soru 6: Java'da iki tarih arasındaki farkı yıl, ay ve gün olarak nasıl hesaplarız?


Örnek Cevap:


java

Copy code

LocalDate date1 = LocalDate.of(2022, 10, 15);

LocalDate date2 = LocalDate.of(2023, 3, 1);


Period period = Period.between(date1, date2);

int years = period.getYears();

int months = period.getMonths();

int days = period.getDays();


System.out.println("Yıl farkı: " + years);

System.out.println("Ay farkı: " + months);

System.out.println("Gün farkı: " + days);

Soru 7: Verilen bir tarihin haftanın hangi günü olduğunu bulmak için nasıl yaparız?


Örnek Cevap:


java

Copy code

LocalDate date = LocalDate.of(2022, 10, 15);

DayOfWeek dayOfWeek = date.getDayOfWeek();


System.out.println("Tarih: " + date);

System.out.println("Haftanın günü: " + dayOfWeek);

Soru 8: Java'da belirli bir tarihin geçerli olup olmadığını nasıl kontrol ederiz?


Örnek Cevap:


java

Copy code

LocalDate date = LocalDate.of(2022, 2, 30);

boolean isValidDate = date.isSupported(LocalDate.now().toLocalDate().getChronology().dateNow());


System.out.println("Geçerli tarih: " + isValidDate);

Bu örnekler, Java'da tarih ve saatle ilgili mülakat sorularına verilebilecek bazı cevaplara örneklerdir. Herhangi bir sorunuz veya belirli bir senaryo hakkında daha fazla bilgiye ihtiyacınız varsa, bana bildirebilirsiniz.


Soru 9: Java'da iki saat arasındaki farkı nasıl hesaplarız?


Örnek Cevap:


java

Copy code

LocalTime time1 = LocalTime.of(10, 30);

LocalTime time2 = LocalTime.of(12, 0);


Duration duration = Duration.between(time1, time2);

long hours = duration.toHours();

long minutes = duration.toMinutesPart();

long seconds = duration.toSecondsPart();


System.out.println("Saat farkı: " + hours);

System.out.println("Dakika farkı: " + minutes);

System.out.println("Saniye farkı: " + seconds);

Soru 10: Belirli bir tarih ve saat aralığında olup olmadığını kontrol etmek için Java'da nasıl yaparız?


Örnek Cevap:


java

Copy code

LocalDateTime dateTime = LocalDateTime.now();

LocalDateTime startDateTime = LocalDateTime.of(2023, 1, 1, 10, 0);

LocalDateTime endDateTime = LocalDateTime.of(2023, 1, 1, 18, 0);


boolean isInRange = dateTime.isAfter(startDateTime) && dateTime.isBefore(endDateTime);


System.out.println("Belirli aralıkta mı: " + isInRange);

Soru 11: Verilen bir tarihin ayın kaçıncı haftası olduğunu nasıl bulabiliriz?


Örnek Cevap:


java

Copy code

LocalDate date = LocalDate.of(2022, 10, 15);

int weekOfMonth = date.get(ChronoField.ALIGNED_WEEK_OF_MONTH);


System.out.println("Tarih: " + date);

System.out.println("Ayın haftası: " + weekOfMonth);

Soru 12: Java'da saat dilimlerini nasıl temsil ederiz?


Örnek Cevap:


java

Copy code

ZoneId newYorkZoneId = ZoneId.of("America/New_York");

ZoneId londonZoneId = ZoneId.of("Europe/London");


ZonedDateTime newYorkDateTime = ZonedDateTime.now(newYorkZoneId);

ZonedDateTime londonDateTime = ZonedDateTime.now(londonZoneId);


System.out.println("New York: " + newYorkDateTime);

System.out.println("London: " + londonDateTime);

Bu örnekler, Java'da tarih ve saatle ilgili mülakat sorularına verilebilecek bazı cevaplara örneklerdir. Herhangi bir sorunuz veya belirli bir senaryo hakkında daha fazla bilgiye ihtiyacınız varsa, bana bildirebilirsiniz.


Soru 13: Java'da bir tarihi belirli bir biçime nasıl dönüştürebiliriz?


Örnek Cevap:


java

Copy code

LocalDate date = LocalDate.of(2022, 10, 15);

String formattedDate = date.format(DateTimeFormatter.ofPattern("dd/MM/yyyy"));


System.out.println("Biçimlendirilmiş tarih: " + formattedDate);

Soru 14: Java'da bir metinden tarih nasıl ayrıştırılır?


Örnek Cevap:


java

Copy code

String dateText = "2022-10-15";

LocalDate date = LocalDate.parse(dateText);


System.out.println("Ayrıştırılan tarih: " + date);

Soru 15: Java'da Unix zaman damgasını tarih ve saate nasıl dönüştürebiliriz?


Örnek Cevap:


java

Copy code

long unixTimestamp = 1679193600;

Instant instant = Instant.ofEpochSecond(unixTimestamp);

LocalDateTime dateTime = LocalDateTime.ofInstant(instant, ZoneOffset.UTC);


System.out.println("Unix zaman damgası: " + unixTimestamp);

System.out.println("Tarih ve saat: " + dateTime);

Soru 16: Java'da bir tarih veya saatle ilgili işlemler yaparken hangi sınıfı tercih edersiniz ve neden?


Örnek Cevap:


java

Copy code

Eğer sadece bir tarih bilgisiyle çalışıyorsam LocalDate sınıfını kullanırım çünkü sadece tarihi temsil eder ve saat veya zaman dilimi gibi ek bilgilere ihtiyaç duymaz. Benzer şekilde, sadece bir saat bilgisiyle çalışıyorsam LocalTime sınıfını kullanırım. Ancak tarih ve saat bilgisine ihtiyacım varsa LocalDateTime sınıfını kullanırım çünkü hem tarihi hem de saati birleştirir ve daha kapsamlı işlemler yapmamı sağlar.

Bu örnekler, Java'da tarih ve saatle ilgili mülakat sorularına verilebilecek bazı cevaplara örneklerdir. Herhangi bir sorunuz veya belirli bir senaryo hakkında daha fazla bilgiye ihtiyacınız varsa, bana bildirebilirsiniz.


Soru 17: Java'da bir tarih veya saat arasındaki farkı zaman birimleriyle nasıl hesaplarız?


Örnek Cevap:


java

Copy code

LocalDateTime dateTime1 = LocalDateTime.of(2022, 10, 15, 10, 0);

LocalDateTime dateTime2 = LocalDateTime.of(2022, 10, 15, 12, 30);


Duration duration = Duration.between(dateTime1, dateTime2);

long hours = duration.toHours();

long minutes = duration.toMinutesPart();

long seconds = duration.toSecondsPart();


System.out.println("Saat farkı: " + hours);

System.out.println("Dakika farkı: " + minutes);

System.out.println("Saniye farkı: " + seconds);

Soru 18: Java'da bir tarihi belirli bir zaman dilimine dönüştürmek için nasıl yaparız?


Örnek Cevap:


java

Copy code

LocalDateTime dateTime = LocalDateTime.of(2022, 10, 15, 10, 0);

ZoneId zoneId = ZoneId.of("America/New_York");

ZonedDateTime zonedDateTime = dateTime.atZone(zoneId);


System.out.println("Tarih ve saat: " + dateTime);

System.out.println("Zaman dilimi: " + zoneId);

System.out.println("Dönüştürülen tarih ve saat: " + zonedDateTime);

Soru 19: Java'da tarih ve saatlerin dilimler arasında dönüştürülmesi nasıl yapılır?


Örnek Cevap:


java

Copy code

LocalDateTime localDateTime = LocalDateTime.now();


// LocalDateTime'i ZonedDateTime'e dönüştürme

ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.of("Europe/London"));


// ZonedDateTime'i LocalDateTime'e dönüştürme

LocalDateTime convertedDateTime = zonedDateTime.toLocalDateTime();


System.out.println("LocalDateTime: " + localDateTime);

System.out.println("Dönüştürülen ZonedDateTime: " + zonedDateTime);

System.out.println("Dönüştürülen LocalDateTime: " + convertedDateTime);

Soru 20: Java'da iki tarih arasında hafta sayısı nasıl hesaplanır?


Örnek Cevap:


java

Copy code

LocalDate startDate = LocalDate.of(2022, 10, 15);

LocalDate endDate = LocalDate.of(2023, 1, 1);


long weeksBetween = ChronoUnit.WEEKS.between(startDate, endDate);


System.out.println("İki tarih arasındaki hafta sayısı: " + weeksBetween);

Bu örnekler, Java'da tarih ve saatle ilgili mülakat sorularına verilebilecek bazı cevaplara örneklerdir. Herhangi bir sorunuz veya belirli bir senaryo hakkında daha fazla bilgiye ihtiyacınız varsa, bana bildirebilirsiniz.


Soru 1: Java'da tarih ve saat işlemleri için hangi paket kullanılır?


Cevap: Java'da tarih ve saat işlemleri için java.time paketi kullanılır.


Soru 2: java.time paketinde en sık kullanılan sınıflar hangileridir?


Cevap: java.time paketinde en sık kullanılan sınıflar LocalDate, LocalTime, LocalDateTime, ZonedDateTime ve Duration sınıflarıdır.


Soru 3: LocalDate ve LocalDateTime arasındaki fark nedir?


Cevap: LocalDate, yalnızca tarih bilgisini temsil ederken, LocalDateTime hem tarih hem de saat bilgisini temsil eder.


Soru 4: Java'da bir tarih nasıl oluşturulur?


Cevap: Bir tarih oluşturmak için LocalDate.of() metodunu kullanabiliriz. Örneğin: LocalDate date = LocalDate.of(2022, 7, 1);


Soru 5: Java'da bir saat nasıl oluşturulur?


Cevap: Bir saat oluşturmak için LocalTime.of() metodunu kullanabiliriz. Örneğin: LocalTime time = LocalTime.of(15, 30);


Soru 6: Java'da bir tarih ve saat nasıl oluşturulur?


Cevap: Bir tarih ve saat oluşturmak için LocalDateTime.of() metodunu kullanabiliriz. Örneğin: LocalDateTime dateTime = LocalDateTime.of(2022, 7, 1, 15, 30);


Soru 7: İki tarih arasındaki farkı nasıl hesaplarız?


Cevap: İki tarih arasındaki farkı hesaplamak için ChronoUnit sınıfının between() metodunu kullanabiliriz. Örneğin: long daysBetween = ChronoUnit.DAYS.between(date1, date2);


Soru 8: Belirli bir tarih veya saat aralığında olup olmadığını nasıl kontrol ederiz?


Cevap: Belirli bir tarih veya saat aralığında olup olmadığını kontrol etmek için isAfter(), isBefore() ve isEqual() metodlarını kullanabiliriz.


Soru 9: Bir tarihi belirli bir biçime nasıl dönüştürebiliriz?


Cevap: Bir tarihi belirli bir biçime dönüştürmek için DateTimeFormatter sınıfını kullanabiliriz. Örneğin: String formattedDate = date.format(DateTimeFormatter.ofPattern("dd-MM-yyyy"));


Soru 10: Java'da tarih ve saatlerin dilimler arasında dönüştürülmesi nasıl yapılır?


Cevap: Tarih ve saatlerin dilimler arasında dönüştürülmesi için atZone() ve toLocalDateTime() gibi metodları kullanabiliriz. Örneğin:


java

Copy code

ZonedDateTime zonedDateTime = localDateTime.atZone(zoneId);

LocalDateTime convertedDateTime = zonedDateTime.toLocalDateTime();


Soru 11: java.time paketiyle ilgili bazı özel durumlar ve sınıflar nelerdir?


Cevap: java.time paketindeki bazı özel durumlar ve sınıflar şunlardır:


Instant: Anlık bir zamandaki tarih ve saati temsil eder.

Period: İki tarih arasındaki farkı yıl, ay ve gün olarak temsil eder.

Duration: İki saat veya zaman arasındaki farkı temsil eder.

ZoneId: Zaman dilimini temsil eder.

ZoneOffset: UTC'ye göre sabit bir saat ofsetini temsil eder.

DateTimeFormatter: Tarih ve saatlerin biçimlendirilmesi ve ayrıştırılması için kullanılır.

TemporalAdjuster: Tarih ve saatleri ayarlamak için kullanılan arayüzdür.

TemporalUnit: Tarih ve saat birimlerini temsil eden bir arayüzdür (örneğin, gün, saat, dakika).

Soru 12: Java'da zaman dilimi ve saat dilimi arasındaki fark nedir?


Cevap: Zaman dilimi (time zone), dünya üzerindeki belli bir bölgenin saatiyle ilgili bilgiyi temsil eder. Örneğin, "America/New_York" zaman dilimi doğu Amerika Standart Zamanı'na (EST) veya Doğu Amerika Yaz Saati Uygulaması'na (EDT) karşılık gelir.


Saat dilimi (offset), UTC'ye (Koordinatlı Evrensel Zaman) göre belirli bir saat ofsetini temsil eder. Örneğin, UTC+03:00 saat dilimi, UTC'den üç saat ileride bulunan bir saat dilimini temsil eder.


Soru 13: java.util.Date sınıfı ve java.time paketi arasındaki farklar nelerdir?


Cevap: java.util.Date sınıfı, Java'nın eski tarih ve saat işlemlerini temsil ederken, java.time paketi Java 8'de tanıtılan yeni tarih ve saat API'sini temsil eder. İşte java.util.Date ve java.time arasındaki bazı farklar:


java.util.Date, mutable (değiştirilebilir) bir sınıftır ve thread güvenli değildir, oysa java.time sınıfları immutable (değiştirilemez) ve thread güvenlidir.

java.util.Date sınıfı tasarım açısından eksikliklere sahiptir ve bazı hatalı davranışları vardır, java.time sınıfları ise daha tutarlı ve hatasız bir şekilde çalışır.

java.util.Date sınıfı, UTC zaman dilimini varsayar, oysa java.time paketi zaman dilimlerini doğru bir şekilde yönetir.

java.util.Date sınıfı, birçok işlemi gerçekleştirmek için java.util.Calendar sınıfıyla birlikte kullanılırken, java.time paketi bu işlemleri doğrudan destekler.

Soru 14: Java 8 öncesi sürümlerde tarih ve saatle ilgili işlemleri nasıl yapardık?


Cevap: Java 8 öncesinde, tarih ve saatle ilgili işlemler genellikle java.util.Date ve java.util.Calendar sınıflarıyla yapılırdı. Ancak bu sınıflar tasarım açısından hatalı ve zorluklarla dolu olduğundan, tarih ve saat işlemleri oldukça zahmetli olabilirdi. Java 8'de tanıtılan java.time paketi, daha kolay kullanılabilen, daha tutarlı ve hatasız bir API sunarak bu sorunları çözmüştür.

SOLID Prensipleri -The Open-Closed Principle- Uncle Bob Çevirisi

Merhaba, bu seride sizlere Uncele Bob'un (Robert C. Martin) SOILD presnipleri için yazdığı makaleleri Türkçe'ye çevireceğim. Umarım yararlı bir yazı dizisi olur.

Seri'nin diğer yazıları :

The Single Responsibility Principle




2- The Open-Closed Principle


Ivar Jacobson'un dediği gibi: “Tüm sistemler yaşam döngüleri boyunca değişir. İlk sürümden daha uzun sürmesi beklenen sistemler geliştirilirken bu akılda tutulmalıdır. ” Değişim karşısında, kararlı ve ilk sürümden daha uzun sürecek tasarımlar nasıl oluşturabiliriz? Bertrand Meyer, ünlü open-closed prensibini icat ettiği 1988'den beri bize rehberlik etti. Onu yeniden ifade etmek için:

SOFTWARE ENTITIES (CLASSES, MODULES, FUNCTIONS, ETC.) SHOULD BE OPEN FOR EXTENSION, BUT CLOSED FOR MODIFICATION.
(Yazılım varlıkları (SINIFLAR, MODÜLLER, FONKSİYONLAR, VB.) gelişime açık, ancak değişikliğe kapalı olmalıdır.) 

Bir programda yapılan tek bir değişiklik, bağımlı modüllerde kademeli bir değişiklikle sonuçlandığında, bu program “kötü” tasarımla ilişkilendirdiğimiz istenmeyen nitelikleri sergiler. Program kırılgan, katı, öngörülemez ve kullanılamaz hale gelir. Açık kapalı prensibi bunu çok basit bir şekilde engeller. Asla değişmeyen modüller tasarlamanız gerektiğini söylüyen bu prensip, gereksinimler değiştiğinde, bu tür modüllerin davranışlarını, zaten çalışan eski kodu değiştirerek değil, yeni kod ekleyerek genişletmeyi önerir.

TANIM

Açık-kapalı prensibine uyan modüllerin iki temel özelliği vardır.

1.  “Genişlemeye Açık” dır.
Bu, modülün davranışının genişletilebileceği anlamına gelir. Uygulamanın gereksinimleri değiştikçe veya yeni uygulamaların gereksinimlerini karşılamak için modülün yeni ve farklı şekillerde davranmasını sağlayabiliriz.

2. “Değişikliğe Kapalıdır”.
Böyle bir modülün kaynak kodu dokunulmazdır. Hiç kimsenin kaynak kodda değişiklik yapmasına izin verilmez.

Bu iki özelliğin birbiriyle çeliştiği anlaşılıyor. Bir modülün davranışını genişletmenin normal yolu, o modülde değişiklik yapmaktır. Değiştirilemeyen bir modülün normalde sabit bir davranışı olduğu düşünülmektedir. Bu iki karşıt özellik nasıl çözülebilir?


Abstraction is the Key
(Soyutlama burada kilit anahtardır)

C ++ 'da, nesne yönelimli tasarım ilkelerini kullanarak, sabit ve sınırsız olası davranış grubunu temsil eden soyutlamalar oluşturmak mümkündür. Soyutlamalar soyut temel sınıflardır ve sınırsız olası davranış grubu tüm olası alt sınıfları tarafından temsil edilir. Bir modülün bir soyutlamayı manipüle etmesi mümkündür. Böyle bir modül, düzeltilmiş bir soyutlamaya bağlı olduğu için modifikasyon için kapatılabilir. Yine de bu modülün davranışı, soyutlamanın yeni alt sınıfları yaratılarak genişletilebilir.

Şekil 1, açık-kapalı prensibine uymayan basit bir tasarımı göstermektedir. Hem Client hem de Server sınıfları somuttur. Server sınıfının üye metodlarının abstract olduğuna dair bir garanti yoktur. Client sınıfı Server sınıfını kullanır. Bir Client nesnesinin farklı bir sunucu nesnesi kullanmasını istiyorsak, yeni sunucu sınıfını adlandırmak için Client sınıfının değiştirilmesi gerekir.


Şekil 2, açık-kapalı prensibine uyan ilgili tasarımı göstermektedir. Bu durumda, AbstractServer sınıfı saf abstract üye metodlarına sahip soyut bir sınıftır. Client sınıfı bu soyutlamayı kullanır. Ancak Client sınıfının nesneleri, alt sınıf Server sınıfının nesnelerini kullanacaktır. Client nesnelerinin farklı bir sunucu sınıfı kullanmasını istiyorsak, AbstractServer sınıfının yeni bir alt sınıfı oluşturulabilir. Client sınıfı değişmeden kalabilir.



The Shape Abstraction
(Şekil Soyutlaması)


Aşağıdaki örneği ele alalım. Standart bir GUI üzerine daireler ve kareler çizebilmemiz gereken bir uygulamamız var. Daireler ve kareler belirli bir sırada çizilmelidir. Dairelerin ve karelerin bir listesi uygun sırayla oluşturulacaktır ve program listeyi bu sırayla yürütmeli ve her daireyi veya kareyi çizmelidir.

C'de, açık-kapalı prensibine uymayan prosedürel teknikler kullanarak, bu problemi aşağıdai kodda gösterildiği gibi çözebiliriz. Burada aynı ilk öğeye sahip olan ancak bunun ötesinde farklı bir veri yapıları kümesi görüyoruz. Her birinin ilk öğesi, veri yapısını daire veya kare olarak tanımlayan bir tür kodudur. DrawAllShapes metodu, bu veri yapılarına bir dizi işaretçi yürütür, tür kodunu inceler ve sonra uygun fonksiyonu çağırır (DrawCircle veya DrawSquare).
Procedural Solution to the Square/Circle Problem
enum ShapeType {circle, square};
struct Shape
{
 ShapeType itsType;
};
struct Circle
{
 ShapeType itsType;
 double itsRadius;
 Point itsCenter;
};
struct Square
{
 ShapeType itsType;
 double itsSide;
 Point itsTopLeft;
};
//
// These functions are implemented elsewhere
//
void DrawSquare(struct Square*)
void DrawCircle(struct Circle*);
typedef struct Shape *ShapePointer;
void DrawAllShapes(ShapePointer list[], int n)
{
 int i;
 for (i=0; iitsType)
 {
 case square:
 DrawSquare((struct Square*)s);
 break;
 case circle:
 DrawCircle((struct Circle*)s);
 break;
 }
 }
}

DrawAllShapes metodu, yeni şekil türlerine karşı kapatılamadığından açık-kapalı prensibine uymaz. Üçgenleri içeren şekiller listesi çizebilmek için bu fonksiyonu genişletmek isteseydim, fonksiyonu değiştirmek zorunda kalırdım. Aslında, çizmem gereken herhangi bir yeni şekil için fonksiyonu değiştirmem gerekirdi.

Elbette bu program sadece basit bir örnektir. Gerçek hayatta DrawAllShapes fonksiyonundaki switch deyimi, uygulamanın her yerindeki çeşitli fonksiyonlarda tekrar tekrar tekrarlanır; her biri biraz farklı bir şey yapar. Böyle bir uygulamaya yeni bir şekil eklemek, bu tür anahtar ifadelerin (veya if / else zincirlerinin) bulunduğu her yer için her birine yeni şekil ekleme anlamına gelir. Ayrıca, tüm switch deyimlerinin ve if / else zincirlerinin DrawAllShapes'deki kadar güzel yapılandırılmış olması pek olası değildir.

İf ifadelerinin tahminlerinin mantıksal işleçlerle birleştirilecek ya da
switch statementlarının case'leri yerel karar almayı “basitleştirmek” için birleştirilecektir. Bu nedenle, yeni şeklin eklenmesi gereken tüm yerleri bulma ve anlama problemi önemsiz olabilir.

Aşağıdaki kod bloğu, açık-kapalı prensibine uyan kare / daire problemine bir çözüm kodunu gösterir. Bu durumda soyut bir Shape sınıfı oluşturulur. Bu soyut sınıf, Draw adında tek bir saf sanal metoda sahiptir. Daire ve Kare, Shape sınıfının alt sınıflarıdır.


Square/Circle problemine OOD Çözümü.
class Shape
{
 public:
 virtual void Draw() const = 0;
};
class Square : public Shape
{
 public:
 virtual void Draw() const;
};
class Circle : public Shape
{
 public:
 virtual void Draw() const;
};
void DrawAllShapes(Set& list)
{
 for (Iteratori(list); i; i++)
 (*i)->Draw();
}

Yeni bir şekil çizmek için yukarıdaki kodda DrawAllShapes metodunun davranışını genişletmek istiyorsak, tek yapmamız gereken Shape sınıfının yeni bir alt sınıfı eklemektir. DrawAllShapes metodunun değiştirilmesi gerekmez. Böylece DrawAllShapes açık kapalı prensibine uygundur. Davranışı değiştirilmeden genişletilebilir.

Gerçek dünyada Shape sınıfının çok daha fazla methodu olacaktır. Yine de uygulamaya yeni bir şekil eklemek hala oldukça basittir, çünkü gerekli olan tek şey yeni alt sınıfı oluşturmak ve tüm metodlarını uygulamaktır. Değişiklik gerektiren yerleri arayan tüm uygulamada arayarak avlanmaya gerek yoktur.

Açık-kapalı prensibine uyan programlar, mevcut kodu değiştirmek yerine yeni kod ekleyerek değiştirildiğinden, bu presibe uymayan programlar tarafından sergilenen değişikliklerin sıkıntısını yaşamazlar.

STRATEJİK KAPATMA

Hiçbir programın% 100 kapatılamayacağı açık olmalıdır. Örneğin, tüm Circle'ların herhangi bir Square'den önce çizilmesi gerektiğine karar verirsek, yukarıdaki koddaki DrawAllShapes metoduna ne olacağını düşünün. DrawAllShapes metodu böyle bir değişikliğe karşı kapalı değildir. Genel olarak, bir modül ne kadar “kapalı” olursa olsun, her zaman kapalı olmadığı bir tür değişiklik olacaktır.

Kapanış tamamlanamayacağı için stratejik olmalı. Yani, tasarımcı tasarımını kapatmak için hangi tür değişiklikleri yapması gerektiğini seçmelidir. Bu, deneyimden elde edilen belli bir miktar önseziyi gerektirir. Deneyimli tasarımcı, kullanıcıları ve sektörü farklı türdeki değişikliklerin olasılığını değerlendirecek kadar iyi tanır. Daha sonra açık-kapalı prensibinin en olası değişiklikler için çağrıldığından emin olur.

Using Abstraction to Gain Explicit Closure.
(Açık Kapatma Kazanmak için Soyutlama Kullanma.)

Çizim sırasındaki değişikliklere karşı DrawAllShapes metodunu nasıl kapatabiliriz? Kapamanın soyutlamaya dayandığını unutmayın. Bu nedenle, DrawAllShapes'i sıralamaya karşı kapatmak için bir çeşit “sıralama soyutlaması” na ihtiyacımız var. Yukarıdaki özel sıralama durumu, diğer şekil türlerinden önce belirli şekil türlerinin çizilmesiyle ilgilidir.

Bir sıralama politikası, herhangi iki nesne göz önüne alındığında, hangisinin önce çizilmesi gerektiğini keşfetmenin mümkün olduğunu gösterir. Böylece, başka bir Şekli bağımsız değişken olarak alan ve bir bool sonucu döndüren Precedes adlı bir Shape yöntemi tanımlayabiliriz. İletiyi alan Shape nesnesinin, Shape nesnesi bağımsız değişken olarak geçmeden önce sıralanması gerekmesi sonucunu doğrudur.

C ++ 'da bu metod aşırı yüklenmiş bir operatör <fonksiyonu ile temsil edilebilir.
Liste 3, yerinde sıralama yöntemleriyle Shape sınıfının nasıl görünebileceğini göstermektedir. Artık iki Shape nesnesinin göreceli sırasını belirlemenin bir yoluna sahip olduğumuza göre, bunları sıralayabilir ve sonra sırayla çizebiliriz. Liste 4, bunu yapan C ++ kodunu gösterir.

Bu bize Shape nesnelerini sıralamak ve bunları uygun sırada çizmek için bir araç sağlar. Ama hala iyi bir sıralama soyutlamamız yok. Haliyle, her bir Shape nesnesinin sıralamasını belirtmek için Precedes yöntemini geçersiz kılması gerekecektir. Bu nasıl olurdu? Karelerin Liste 5'ten önce çizildiğinden emin olmak için, Circle :: Preedes'de ne tür bir kod yazardık?


Listing 3
Shape with ordering methods.
class Shape
{
 public:
 virtual void Draw() const = 0;
 virtual bool Precedes(const Shape&) const = 0;
 bool operator<(const Shape& s) {return Precedes(s);}
};
Listing 4
DrawAllShapes with Ordering
void DrawAllShapes(Set& list)
{
 // copy elements into OrderedSet and then sort.
 OrderedSet orderedList = list;
 orderedList.Sort();
 for (Iterator i(orderedList); i; i++)
 (*i)->Draw();
}

}
Listing 5
Ordering a Circle
bool Circle::Precedes(const Shape& s) const
{
 if (dynamic_cast(s))
 return true;
 else
 return false;
}
<
Bu metodun açık-kapalı prensibine uymadığı çok açık olmalıdır. Yeni Shape alt sınıflarına karşı kapatmanın bir yolu yoktur. Her yeni bir Shape alt sınıfı oluşturulduğunda, bu metodun değiştirilmesi gerekir.


Using a “Data Driven” Approach to Achieve Closure.
(Kapanışı Gerçekleştirmek için “Veriye Dayalı” Bir Yaklaşım Kullanmak.)

Shape alt sınıflarının kapatılması, türetilmiş her sınıftaki değişiklikleri zorlamayan tablo güdümlü bir yaklaşım kullanılarak elde edilebilir. Liste 6'da bir olasılık gösterilmektedir.
Bu yaklaşımı kullanarak, genel olarak sıralama sorunlarına karşı DrawAllShapes metodunu ve yeni Shape alt sınıflarının oluşturulmasına veya Shape nesnelerini türlerine göre yeniden sıralayan politikadaki bir değişikliğe karşı Shape alt sınıflarının her birini başarıyla kapattık. (örneğin, önce Kareler çizilecek şekilde sıralamayı değiştirme.)

Listing 6
Tabloya dayalı sıralama mekanizması
#include 
#include 
enum {false, true};
typedef int bool;
class Shape
{
 public:
 virtual void Draw() const = 0;
 virtual bool Precedes(const Shape&) const;
 bool operator<(const Shape& s) const
 {return Precedes(s);}
 private:
 static char* typeOrderTable[];
};
char* Shape::typeOrderTable[] =
{
 “Circle”,
 “Square”,
 0
};
// Bu fonksiyon sınıf isimlerine göre tabloda arama yapar
// Tablo hangi şeklin çizileceğikonusunda sıralama bilgisi verir
// Bulunamayan şekiller
// her zaman bulunan şekillerden önce gelir.

bool Shape::Precedes(const Shape& s) const
{
 const char* thisType = typeid(*this).name();
 const char* argType = typeid(s).name();
 bool done = false;
 int thisOrd = -1;
 int argOrd = -1;
 for (int i=0; !done; i++)
 {
 const char* tableEntry = typeOrderTable[i];
 if (tableEntry != 0)
 {
 if (strcmp(tableEntry, thisType) == 0)
 thisOrd = i;
 if (strcmp(tableEntry, argType) == 0)
 argOrd = i;
 if ((argOrd > 0) && (thisOrd > 0))
 done = true;
 }
 else // table entry == 0
 done = true;
 }
 return thisOrd < argOrd;
}

Çeşitli Şekillerin sırasına karşı kapalı olmayan tek öğe tablonun kendisidir. Ve bu tablo, diğer modüllerden ayrı olarak kendi modülüne yerleştirilebilir, böylece tabloda yapılan değişiklikler diğer modüllerin hiçbirini etkilemez.


Heuristics and Conventions
(Buluşsal Yöntemler ve Sözleşmeler)

Bu makalenin başında belirtildiği gibi, açık-kapalı prensibi, yıllar boyunca OOD ile ilgili olarak yayınlanan birçok buluşsal yöntem ve sözleşmenin arkasındaki temel motivasyondur. İşte bunların en önemlilerinden bazıları.

Make all Member Variables Private.
(Tüm Üye Değişkenlerini Private Yap.)

Bu, OOD'nin tüm sözleşmelerinde en yaygın olarak tutulanlardan biridir. Sınıfların üye değişkenleri, yalnızca sınıfın tanımlayan yöntemleri tarafından bilinmelidir. Üye değişkenler, türetilmiş sınıflar da dahil olmak üzere hiçbir zaman başka bir sınıf tarafından bilinmemelidir. Bu nedenle, public ya da protected yerine private ilan edilmelidir. Açık kapalı prensibi ışığında, bu sözleşmenin nedeni açık olmalıdır. Bir sınıfın üye değişkenleri değiştiğinde, bu değişkenlere bağlı her metod değiştirilmelidir. Böylece, bir değişkene bağlı hiçbir fonksiyon, bu değişkene göre kapatılamaz.

OOD'de, bir sınıfın metodlarının, o sınıfın üye değişkenlerindeki değişikliklere kapalı olmamasını bekliyoruz. Ancak, alt sınıflar da dahil olmak üzere diğer sınıfların bu değişkenlerdeki değişikliklere karşı kapalı olmasını bekliyoruz. Bu beklenti için bir ismimiz var, buna encapsulation (kapsülleme) diyoruz. Peki ya asla değişmeyeceğini bildiğiniz bir üye değişkeniniz olsaydı? Özel yapmak için herhangi bir neden var mı? Örneğin, Liste 7'de bool durum değişkeni olan bir sınıf Device gösterilmektedir. Bu değişken son işlemin durumunu içerir. Bu işlem başarılı olursa, durum true, aksi halde false olur.

Listing 7
non-const public variable
class Device
{
 public:
 bool status;
};

Bu değişkenin türü veya anlamının asla değişmeyeceğini biliyoruz. Öyleyse neden herkese açık hale getirmiyor ve istemci kodunun içeriğini incelemesine izin vermiyoruz? Bu değişken gerçekten hiç değişmezse ve diğer tüm istemciler kurallara uyarsa ve yalnızca durumun içeriğini sorgularsa, değişkenin herkese açık olması hiçbir zarar vermez. Bununla birlikte, bir istemci bile status değişkenin yazılabilir doğasından yararlanırsa ve değerini değiştirirse ne olacağını düşünün. Aniden, bu bir istemci diğer tüm istemcileri etkileyebilir. Bu, herhangi bir Device istemcisini bu hatalı davranış modülündeki değişikliklere karşı kapatmanın imkansız olduğu anlamına gelir. Bu muhtemelen alınamayacak kadar büyük bir risktir.


Öte yandan, Liste 8'de gösterildiği gibi Time sınıfına sahip olduğumuzu varsayalım. Bu sınıftaki public üye değişkenlerin verdiği zarar nedir? Elbette değişmeleri pek olası değildir. Ayrıca, istemci modüllerinden herhangi birinin değişkenlerde değişiklik yapması önemli değildir, değişkenlerin istemciler tarafından değiştirilmesi gerekir. Ayrıca, türetilmiş bir sınıfın belirli bir üye değişkenin ayarını değiştirmek istemesi pek olası değildir. Peki bu durumun herhangi bir zarar var mı?


Listing 8
class Time
{
 public:
 int hours, minutes, seconds;
 Time& operator-=(int seconds);
 Time& operator+=(int seconds);
 bool operator< (const Time&);
 bool operator> (const Time&);
 bool operator==(const Time&);
 bool operator!=(const Time&);
};

Liste 8 ile ilgili yapabileceğim bir şikayet, zamanın değiştirilmesinin atomik olmamasıdır. Yani, istemci hours değişkenini hours değişkenini değiştirmeden değiştirebilir. Bu bir Time nesnesi için tutarsız değerlere neden olabilir. Üç argüman alıp zamanı atomik olarak ayarlayan tek bir fonksiyonu tercih ederdim. Fakat bu çok zayıf bir argüman.


Bu değişkenlerin public doğasının bazı sorunlara neden olduğu diğer koşulları düşünmek zor olmayacaktır. Bununla birlikte, uzun vadede, bu değişkenleri private yapmak için baskın bir neden yoktur. Hala public hale getirmenin kötü bir tarzı olduğunu düşünüyorum, ancak muhtemelen kötü bir tasarım değil. Kötü tarz olarak görüyorum çünkü uygun satır içi üye moetdları oluşturmak çok ucuz ve ucuz maliyet kesinlikle kapama sorunlarının ortaya çıkması riskine karşı korumaya değer.

Bu nedenle, açık-kapalı prensibinin ihlal edilmediği nadir durumlarda, public ve protected değişkenlerin yasaklanması, sağlamlılıktan ziyade stile bağlıdır.

No Global Variables -- Ever.
(Hiçbir zaman için Global Değişken kullanılmamalı)

Global değişkenlere karşı argüman, public değişkenlere karşı olan argümana benzer. Global değişkene bağlı hiçbir modül, bu değişkene yazabilecek diğer modüllere karşı kapatılamaz. Değişkeni diğer modüllerin beklemediği şekilde kullanan herhangi bir modül, diğer modülleri kıracaktır. Birçok modülün kötü davranmış bir modülün kaprisine maruz kalması çok risklidir.

Diğer taraftan, global bir değişkenin çok az bağımlısı olduğu veya tutarsız bir şekilde kullanılamadığı durumlarda, diğer moduller çok az zarar verirler. Tasarımcı, bir global için ne kadar kapatmanın feda edildiğini değerlendirmeli ve global değişken tarafından sunulan kolaylığın maliyete değip değmediğini belirlemelidir.

Yine, ortaya çıkan stil sorunları var. Globalleri kullanmanın alternatifleri genellikle çok ucuzdur. Bu gibi durumlarda, böyle bir risk taşımayan yöntemlere karşı çok az miktarda kapanma riski taşıyan bir teknik kullanmak kötü bir stildir. Bununla birlikte, global bir rahatlığın önemli olduğu durumlar vardır. Global değişkenler için cout ve cin yaygın örneklerdir. Bu gibi durumlarda, açık-kapalı prensibi ihlal edilmezse, kolaylık stil ihlaline değebilir.


RTTI is Dangerous.
(RTTI tehlikelidir)

Bir diğer çok yaygın yasak, dynamic_cast'e karşıdır. Genellikle dynamic_cast veya herhangi bir run time türü tanımlamasının (RTTI) kendiliğinden tehlikeli olduğu ve bundan kaçınılması gerektiği iddia edilir. Genellikle atıfta bulunulan durum, açık-kapalı prensibini açıkça ihlal eden Liste 9'a benzer. Ancak Liste 10, dynamic_cast kullanan ancak açık-kapalı ilkesini ihlal etmeyen benzer bir programı gösterir.

Bu ikisi arasındaki fark, yeni bir Shape türü elde edildiğinde  Liste 9'un değiştirilmesi gerektiğidir. (Sadece düpedüz saçma olduğunu söylememe gerek yok). Ancak, yeni bir Shape alt sınıfı oluşturulduğunda Liste 10'da hiçbir şey değişmez. Bu nedenle, Liste 10 açık-kapalı prensibini ihlal etmez. Genel bir kural olarak, RTTI kullanımı açık-kapalı prensibini ihlal etmiyorsa, güvenlidir.

Listing 9
RTTI violating the open-closed principle.
class Shape {};
class Square : public Shape
{
 private:
 Point itsTopLeft;
 double itsSide;
 friend DrawSquare(Square*);
};
class Circle : public Shape
{
 private:
 Point itsCenter;
 double itsRadius;
 friend DrawCircle(Circle*);
};
void DrawAllShapes(Set& ss)
{
 for (Iteratori(ss); i; i++)
 {
 Circle* c = dynamic_cast(*i);
 Square* s = dynamic_cast(*i);
 if (c)
 DrawCircle(c);
 else if (s)
 DrawSquare(s);
 }
}
Listing 10
RTTI that does not violate the open-closed Principle.
class Shape
{
 public:
 virtual void Draw() cont = 0;
};
class Square : public Shape
{
 // as expected.
};
void DrawSquaresOnly(Set& ss)
{
 for (Iteratori(ss); i; i++)
 {
 Square* s = dynamic_cast(*i);
 if (s)
 s->Draw();
 }
}

SONUÇ

Açık-kapalı prensibi hakkında söylenebilecek çok şey var. Birçok yönden bu ilke nesne yönelimli tasarımın merkezindedir. Bu prensibe uygunluk, nesne yönelimli teknoloji için talep edilen en büyük faydaları mevcuttur; ör: tekrar kullanılabilirlik ve sürdürülebilirlik. Ancak bu ilkeye uyum basitçe nesne yönelimli bir programlama dili kullanılarak elde edilemez. Aksine, tasarımcının, değişikliğe tabi olacağını düşündüğü programlara soyutlama uygulaması için bir özveri gerekmektedir.








Bonus :




Rastgele İçerik

DonanımHaber

© tüm hakları saklıdır
made with by templateszoo