Skip to content

8. [TD]: [metier] katmanı

Anahtar kelimeler: çok katmanlı mimari, Spring, bağımlılık enjeksiyonu.

8.1. Support

 

[support / chap-08] klasörü, bu bölümün Eclipse projesini içerir.

8.2. Maven Yapılandırması

  

[elections-metier-dao-jdbc] projesi, [elections-dao-jdbc-01] projesini temel alacaktır. Bu son projenin jar dosyasını yerel Maven deposuna yükleyeceğiz:

 

Bu işlem tamamlandıktan sonra, Eclipse projesi [elections-metier-dao-jdbc]'in Maven yapılandırması şu şekildedir:

  

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>istia.st.elections</groupId>
    <artifactId>elections-metier-dao-jdbc</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.2.7.RELEASE</version>
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <!-- DAO -->
        <dependency>
            <groupId>istia.st.elections</groupId>
            <artifactId>elections-dao-jdbc-01</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
        <!-- Spring Boot -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- Spring Boot Test -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <!-- eklentiler -->
    <build>
        <plugins>
            <plugin>
                <artifactId>maven-assembly-plugin</artifactId>
                <configuration>
                    <archive>
                        <manifest>
                            <mainClass>config.AppConfig</mainClass>
                        </manifest>
                    </archive>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                </configuration>
            </plugin>
            <!-- proje artefaktının yerel Maven deposuna yüklenmesi için -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.18.1</version>
            </plugin>
        </plugins>
    </build>
</project>
  • 21-25. satırlar: [elections-jdbc-01] projesinin jar dosyasına olan bağımlılık. Bu satırları, içe aktarmak istediğimiz projenin [pom.xml] dosyasından doğrudan alıyoruz:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>istia.st.elections</groupId>
    <artifactId>elections-dao-jdbc-01</artifactId>
    <version>0.0.1-SNAPSHOT</version>
...
  • 26-37. satırlar: Testler için gerekli bağımlılıklar. Bunlar, [elections-jdbc-01] projesinin [pom.xml] dosyasında mevcut olsa da, [<scope>test</scope>] özniteliği nedeniyle yerel Maven deposuna eklenen JAR dosyasına dahil edilmedikleri için bunları yeniden eklememiz gerekiyor;

8.3. Spring Yapılandırması

  

package elections.metier.config;

import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Import;

@Import({ elections.dao.config.AppConfig.class })
@EnableCaching
@ComponentScan(basePackages = { "elections.metier.service" })
public class MetierConfig {
}
  • 7. satır: [DAO] katmanında tanımlanan tüm bean'leri içe aktarıyoruz;
  • 8. satır: önbellek etkinleştirilir. [CacheManager] bean'i yeniden tanımlanmaz, çünkü bu bean [DAO] katmanında zaten tanımlanmıştır;
  • 9. satır: [métier] katmanı, [elections.metier.service] paketinde yeni bean'ler tanımlar;

8.4. [IElectionsMetier] arayüzü

  

[metier] katmanı, 4.2. paragrafta sunulan arayüze sahip olacaktır. Bunu tekrar hatırlatmak gerekirse:


public interface IElectionsMetier {

    public ListeElectorale[] getListesElectorales();

    public int getNbSiegesAPourvoir();

    public double getSeuilElectoral();

    public void recordResultats(ListeElectorale[] listesElectorales);

    public ListeElectorale[] calculerSieges(ListeElectorale[] listesElectorales);

}

8.5. [ElectionsMetier] uygulama sınıfı

  

Bu sınıf, [IElectionsMetier] arayüzünü uygular. Önerilen uygulama aşağıdaki yapıya sahip olacaktır:


package elections.metier.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Component;

import elections.dao.entities.ListeElectorale;
import elections.dao.service.IElectionsDao;

@Component
public class ElectionsMetier implements IElectionsMetier {

    // [Spring] tarafından örneklendirilen [dao] katmanına erişim noktası
    @SuppressWarnings("unused")
    @Autowired
    private IElectionsDao electionsDao;

    // kazanılan koltuk sayısının hesaplanması
  @Override
    public ListeElectorale[] calculerSieges(ListeElectorale[] listesElectorales) {
        throw new RuntimeException("[calculerSieges] not yet implemented");
    }

    // yarışan listeler
  @Override
    public ListeElectorale[] getListesElectorales() {
        throw new RuntimeException("[getListesElectorales] not yet implemented");
    }

    // sonuçların kaydedilmesi
  @Override
    public void recordResultats(ListeElectorale[] listesElectorales) {
        throw new RuntimeException("[recordResultats] not yet implemented");
    }

    // doldurulacak sandalye sayısı
    @Override
    public int getNbSiegesAPourvoir() {
        throw new RuntimeException("[getNbSiegesAPourvoir] not yet implemented");
    }

    // seçim barajı
    @Override
    public double getSeuilElectoral() {
        throw new RuntimeException("[getSeuilElectoral] not yet implemented");
    }

}
  • 10. satır: [ElectionsMetier] sınıfı bir Spring bileşenidir;
  • 11. satır: [ElectionsMetier] sınıfı, [IElectionsMetier] arayüzünü uygular;
  • satır 15-16: [DAO] katmanına bir referansın Spring enjeksiyonu;
  • 37. ve 44. satırlar: doldurulacak koltuk sayısı ve seçim barajı önbelleğe alınır;

Yapılması gereken iş: [ElectionsMetier] sınıfını yazın. Varsa yorumlardan yararlanacağız. [DAO] katmanından gelen [ElectionsException] türündeki istisnaları durdurmaya (try / catch) çalışmayacağız. Bunların [UI] katmanına kadar yükselmesine izin vereceğiz. [ElectionsException] sınıfı kontrol edilemeyen bir istisna türü olduğundan, bunu (try / catch) ile yönetme zorunluluğu yoktur.


8.6. Test sınıfı

  

JUnit test sınıfı aşağıdaki gibi olacaktır:


package tests;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import dao.config.AppConfig;
import dao.entities.ElectionsException;
import metier.service.IElectionsMetier;

@SpringApplicationConfiguration(classes = MetierConfig.class)
@RunWith(SpringJUnit4ClassRunner.class)
public class Test01 {

    // [métier] katmanı
    @Autowired
    static private IElectionsMetier electionsMetier;

    /**
     * vérification 1 : méthode de calcul des sièges on fixe en dur les listes
     */
    @Test
    public void calculSieges1() {
        // 7 aday listesinin tablosu oluşturulur (ad, oy sayısı)

        // her listenin koltuk sayısı hesaplanıyor

        // sonuçlar kontrol edilir (koltuk sayısı, oy sayısı, elenenler)

        // geçici
        throw new RuntimeException("[calculSieges1] not yet implemented");
    }

    /**
     * vérification 2 : méthode de calcul des sièges on demande les listes à la
     * couche [metier] puis on fixe en dur les voix
     */
    @Test
    public void calculSieges2() {
        // 7 aday listesinin tablosu veritabanına aktarılır

        // oylar sabitlenir

        // her bir listenin kazandığı sandalye sayısı hesaplanıyor

        // sonuçlar kontrol edilir (koltuklar, oylar, elenenler)

        // geçici
        throw new RuntimeException("[calculSieges2] not yet implemented");
    }

    /**
     * vérification 3 méthode de calcul des sièges on provoque une exception
     */
    @Test(expected = ElectionsException.class)
    // [ElectionsException] türünde bir istisna oluşturan bir test yazılır
    public void calculSieges3() {
        // her biri 1 oy alan 25 aday listesinden oluşan bir dizi oluşturulur
        // 25 listenin hepsi aynı sayıda oy alacak (%4)

        // koltuk hesaplaması - normalde şu sonuç çıkmalıdır: ElectionsException
        // %5'lik seçim barajı ile

        // geçici
        throw new RuntimeException("[calculSieges3] not yet implemented");
    }

    /**
     * enregistrement des résultats de l'élection
     */
    @Test
    public void ecritureResultatsElections() {
        // 7 aday listesinin tablosu oluşturulur

        // oylar sabitleniyor

        // her listenin kazandığı sandalye sayısı hesaplanıyor

        // sonuçlar veritabanına kaydediliyor

        // veritabanındaki listeler yeniden okunur

        // sonuçlar kontrol edilir (koltuklar, oylar, elenenler)

        // geçici
        throw new RuntimeException("[ecritureResultatsElections] not yet implemented");
    }
}

Yapılması gereken iş: Açıklamalardan yararlanarak dört test yöntemini yazın. Bu yöntemler çalıştırıldığında, 19. satırdaki [electionsMetier] alanının önceden başlatılmış olduğunu unutmayın. JUnit testinin başarılı olduğunu kontrol edin.


8.7. [metier] katmanının arşivinin oluşturulması

[DAO] katmanında yapıldığı gibi, [elections-metier-dao-jdbc] projesinin arşivini yerel Maven deposuna ekliyoruz:

 

Not: Eclipse projeniz JDK (Java Development Kit) yerine JRE (Java Runtime Environment) ile ilişkilendirilmişse bu işlem başarısız olabilir. Bunu öğrenmek için 3.1. paragrafında belirtilen adımları izleyin. JDK yerine JRE kullandığınızı fark ederseniz, bu paragrafta belirtildiği gibi projenizi bir JDK ile ilişkilendirin.

8.8. Conclusion

Şu anda oluşturmakta olduğumuz [Elections] uygulamasının genel mimarisini hatırlayalım:

[metier] ve [dao] katmanlarını oluşturduk. Şimdi [ui] katmanını oluşturacağız. Bu katman için iki farklı uygulama önereceğiz:

  • bir "konsol" uygulaması
  • grafik arayüzlü bir uygulama