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

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 ?

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.
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.
6. 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  ????
}
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.

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.

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");
}

}
0

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

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");
	}
}
0

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

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