Jak powinien wyglądać układ i odpowiedzialność klas?

2015-04-29 08:50
davyd1
0

Potrzebuje podpowiedzi jak powinien wyglądać prawidłowo układ klas i ich odpowiedzialność.
Pierwsza klasa która chce stworzyć jest klasa MODEL. Umieszcze w niej pola oraz getery i setery.Bedzie to klasa na podstawie której stworze tabele do zapisu danych w mySQL.:


@Entity
public class Student 
{
private int id;

private String firstName;
private String lastName;
private Date birthDate;

public Student()
{

}

public Student(int id, String firstName, String lastName, Date birthDate) {
    super();
    this.id = id;
    this.firstName = firstName;
    this.lastName = lastName;
    this.birthDate = birthDate;
}

public int getId() {
    return id;
}
public void setId(int id) {
    this.id = id;
}
public String getFirstName() {
    return firstName;
}
public void setFirstName(String firstName) {
    this.firstName = firstName;
}
public String getLastName() {
    return lastName;
}
public void setLastName(String lastName) {
    this.lastName = lastName;
}
public Date getBirthDate() {
    return birthDate;
}
public void setBirthDate(Date birthDate) {
    this.birthDate = birthDate;
}

Druga klasa to klasa StudentService. Posiada zmienna student oraz wstrzyknięty obiekt klasy RepositoryStudent. Wrzuce i rozwinę w niej jedynie metody które sa związane z modelem student, tzn dodawanie, usuwanie, odnajdywanie w bazie itp.Nie wiem tylko co powinny zwracać metody w klasie service. Po każdej metodzie powinien być return tak jak w przypadku addStudent czy wystarcza metody takie jak deleteStudent bez return ? Jaka jest roznica w tych metodach ?

@Service
public class StudentService

{
private Student student;

@Inject
private StudentRepository studentRepository 

public StudentService{}

@Transactional
public Student addStudent()
{
    student = new Student();
    studentRepository.add(student);
    return student;
}

@Transactional      
public void deletStudent()
{
    student = new Student();
    studentRepository.delete(student);

}
}

Trzecia klasa to klasa StudentRepository gdzie będą wszystkie operacje związane z np. utworzeniem EntityFactory i EntityManagera. I nie rozwinięte metody typu:


@Repository
public class StudentRepository

private emf…
private em… 

public void add (Object object)
{
  em.getTransaction().begin();
  em.persist(object);
  em.getTransaction().commit();
}

}

Wiem, że brakuje bardzo duzo kodu do poprawnego dzialania ale nie o to chodzi chodzi o to czy takie rozwiązanie ma sens. Podpowiedzcie jak rozlozyc prawidłowo te klasy ?

Pozostało 580 znaków

2015-04-29 08:57
0

Nie, to co napisałeś nie ma sensu.

  1. Klasa DAO czyli twoje repository powinna mieć wstrzykniętego EntityManagerFactory skoro już masz podpięte jakieś DI.
  2. Po co ci tam jakieś otwieranie i zamykanie transakcji robione ręcznie? o_O Skoro wyżej widzę że umiesz użyć @Transactional. Przeczuwam bezmyślne kopiowanie z kilku różnych tutoriali...
  3. Transakcje lepiej wyciągać wysoko, więc na poziomie serwisów a nie DAO.
  4. To repozytorium to zrób albo za pomocą Spring Data (skoro już masz Springa...) albo przynajmniej w oparciu o jakieś GenericDao (http://www.ibm.com/developerworks/library/j-genericdao/) żebyś nie pisał 100 razy tego samego kodu.
  5. Skoro @Inject to czemu @Service zamiast @Named? :)
  6. Serwisy zwykle realizują logikę biznesową a nie mapują metody z DAO. Przecież to bez sensu. Serwis powinien udostępniać metody związane z tym co ta aplikacja robi.

Masz problem? Pisz na forum, nie do mnie. Nie masz problemów? Kup komputer...

Pozostało 580 znaków

2015-04-29 09:45
davyd1
0

1 i 4.Ok zrobie interfejs do DAO(add,delete) nastepnie klase StudentRepository ktora to implementuje, wstrzykne Entity i tam umieszcze juz rozwiniete metody add,delete student.
2 i 3.Racja bede uzywał tylko adnotacji @Transactional w klasie StudentService.
5.Wlasnie ktore adnotacje sa bardziej uzywane. @Service,@Repository i np @Controler łatwo pokazuja co jest czym.

  1. Czyli jezeli w klasie StudentRepository mam metode ktora dodaje studenta od poczatku do konca (czyli tworzy new Student, i cały proces dodawania) to w StudentService powinienem miec co ?
    Nie moge złapać tej roznicy. Wszystko co zwiazane z zapisywaniem w bazie bede mial w klasie StudentRepository czyli w klasie StudentService bede miał metode ktora zwraca tego nowego studenta? :

public Student addStudent()
{
studentRepository.add();
return  ????
}

Pozostało 580 znaków

2015-04-29 09:58
0

A co ta aplikacja robi? Bo przecież nie zajmuje się tylko dodawaniem i wczytywaniem wpisów z/do bazy...
Załóżmy że piszesz aplikację dla centrum sterowania statkami kosmicznymi. DAO będzie zapisywało dane ze statku kosmicznego w bazie i wczytywało je jeśli użytkownik będzie chciał przeglądać archiwalne dane. A serwisy będą zajmować się przetwarzaniem i dekodowaniem danych oraz przygotowywaniem ich do prezentacji użytkownikom.
W efekcie repozytorium będzie po prostu zapisywało dane w bazie, kontroler będzie wywoływał odpowiednią metodę z serwisy i wybierał odpowiedni widok, a cała reszta (dekodowanie, przygotowywanie wykresów, aproksymacje i obliczanie parametrów etc) będzie właśnie w warstawie serwisów.


Masz problem? Pisz na forum, nie do mnie. Nie masz problemów? Kup komputer...

Pozostało 580 znaków

2015-04-29 10:56
davyd1
0

ok tak najprosciej jak sie da to bedzie aplkacja ktora bedzie miała dwa modele. Uzytkownik i ZadaniaDoWykonania. Tworzysz nowego uzytkownika logujesz sie i mozesz dodawac zadania(nazwa,obrazek,opis) do wspolnej bazy.Nastepnie mozesz pobierac zadania do jakiejs kolekcji , wybrac jedno albo osiem wcisnac ptrzycisk start i wlaczyc licznik ktory bedzie mierzyl czas wykonywania danego zadania,mozesz rowniez sprawdzic ktore zadanie najdluzej wykonywales. Potrzebuje funkcjonalnosci,zapis,odczyt,modyfkacja, jakies zapytania np pobieranie po imie itp.

@Shalom podrzuć podpowiedz jak bys ta funkcjonalnosc rozbił na klasy . Bede miał wtedy jasny przykład co gdzie powinno byc w takich apkach.

Pozostało 580 znaków

2015-04-30 08:13
0

Zrobiłem to w ten sposób - chciałbym tylko wiedzieć czy tak jest ok i mogę dalej rozbudowywac apke ?

Klasa model:


@Entity
public class User {

@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private long id;    
private String login;
private int age;
private String email;

public User() {

}

public String getLogin() {
    return login;
}

public void setLogin(String login) {
    this.login = login;
}

public int getAge() {
    return age;
}

public void setAge(int age) {
    this.age = age;
}

public String getEmail() {
    return email;
}

public void setEmail(String email) {
    this.email = email;
}

}

Interfejs repository:


package pl.konrad.apk.repository;

import java.util.List;

import pl.konrad.apk.model.User;

public interface DefaultUserRepository {

public abstract void save(User user);
public abstract void delete(User user);
public abstract List<Object> findAll();

}

Klasa repsository:


package pl.konrad.apk.repository;

import java.util.List;

import javax.inject.Named;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import pl.konrad.apk.model.User;

@Named
public class UserRepository implements DefaultUserRepository {

@PersistenceContext 
private EntityManager entityManager;     

    @Override
    public void delete(User user) {
        // TODO Auto-generated method stub

    }

    @Transactional(propagation=Propagation.REQUIRED, readOnly=true)
    public List<Object> findAll() {
        // TODO Auto-generated method stub
        return null;
    }

    @Transactional(propagation=Propagation.REQUIRED)
    public void save(User user) {
        entityManager.persist(user);

    }

}

Klasa service:


package pl.konrad.apk.service;

import javax.inject.Inject;
import javax.inject.Named;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import pl.konrad.apk.model.User;
import pl.konrad.apk.repository.UserRepository;

@Named
public class UserService 
{

@Inject
private UserRepository userRepository;  

public void addTask()
{
User user = new User();
user.setLogin("davyd");
user.setAge(30);
user.setEmail("[email protected]");

userRepository.save(user);

System.out.println("Dodano uzytkownika");
}

}
                     masz tutaj trochę białych znaków, powklejaj odpowiednio bo nie można patrzeć na ten płaski kod. - spartanPAGE 2015-04-30 08:45
rozwiń o o Ci chodzi... - davyd 2015-04-30 09:38
Tzw wcięcia kreaowane przez odpowiednie ilości białych znaków. Poczytaj na ten temat - spartanPAGE 2015-04-30 09:41

Pozostało 580 znaków

2015-04-30 09:02
0

Nie rozumiem czemu List<Object> findAll(); a nie List<User> poza tym lepiej użyć generycznego dao...


Masz problem? Pisz na forum, nie do mnie. Nie masz problemów? Kup komputer...

Pozostało 580 znaków

2015-04-30 14:11
0

Zrobiłem coś takiego ale czy to przypomina generyczne Dao ??? :

//INTERFACE DAO

package pl.konra.dao;

import java.io.Serializable;
import java.util.List;

public interface GenericDao<T> {

    T save(T entity);

    T update(T entity);

    void delete(T entity);

    List<T> findAll();

    void flush();

}

//CLASS DAO

package pl.konra.dao;

import java.io.Serializable;
import java.util.List;

import javax.inject.Inject;
import javax.inject.Named;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.springframework.transaction.annotation.Transactional;

@Named
public abstract class GenericJpaDao<T> implements GenericDao<T>

{
    private Class<T> persistentClass;

    @Inject
    private EntityManager entityManager;

    protected EntityManager getEntityManager() {
        return entityManager;
    }

    @PersistenceContext
    public void setEntityManager(EntityManager entityManager) {
        this.entityManager = entityManager;
    }

    public GenericJpaDao(Class<T> persistentClass) {
        this.persistentClass = persistentClass;
    }

    public Class<T> getPersistentClass() {
        return persistentClass;
    }

    @SuppressWarnings("unchecked")
    @Transactional(readOnly = true)
    public List<T> findAll() {

        return getEntityManager().createQuery(
                "select x from" + getPersistentClass().getSimpleName() + "x")
                .getResultList();

    }

    public T save(T entity) {
        getEntityManager().persist(entity);
        return entity;
    }

    public T update(T entity) {

        T mergegEntity = getEntityManager().merge(entity);
        return mergegEntity;
    }

    public void delete(T entity) {

        getEntityManager().remove(entity);

    }
}

//SERVICE

package pl.konrad.apk.service;

import javax.inject.Inject;
import javax.inject.Named;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import pl.konra.dao.GenericJpaDao;
import pl.konrad.apk.model.User;
import pl.konrad.apk.repository.UserRepository;

@Named
public class UserService {

    @Inject
    private GenericJpaDao genericJpaDao;

    public void addTask() {
        User user = new User();
        user.setLogin("davyd");
        user.setAge(30);
        user.setEmail("[email protected]");

        // userRepository.save(user);
        genericJpaDao.save(user);
        System.out.println("Dodano uzytkownika");
    }
}
edytowany 3x, ostatnio: davyd, 2015-05-01 06:22
Przecież nakopiowałem Ci białych znaków, mozesz ich uzywac do woli - w razie brakow zrobie wiecej - spartanPAGE 2015-04-30 14:19
ok to sie wiecej nie powtórzy bede ich uzywał :) - davyd 2015-04-30 14:44
To zedytuj ładnie kod dodając formatowanie <sup>.</sup> - spartanPAGE 2015-04-30 14:57
Brawo masz dar przekonywania a teraz pomóż rozwikłać mój problem ;P - davyd 2015-05-01 06:13

Pozostało 580 znaków

2015-05-01 06:22
0

Proszę o podpowiedz co powinienem dorzucić to powyższego kodu żeby to chodziło jak należy.

Pozostało 580 znaków

Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0