OPTIMIZACIONES DE DAO genéricos -- java camp codereview Relacionados El problema

Base generic DAO optimizations


6
vote

problema

Español

Tengo la base abstracta GenericDAO clase que ejecuta las operaciones de crud con diferentes tipos de objetos. Customer y Employee Las clases de POJO se utilizan en las clases específicas que extienden las clases que amplían la clase Genericdao. Desde MIS ANTERIOR RELACIONADO Pregunta Tengo algunos problemas no resueltos:

Preguntas:

  • ¿Cómo realizar objetos inmutables en GenericDAOImpl ?
  • es una buena idea o no separar el objeto (es decir, EmployeeSpecs , PersonalSpecs8 ) Propiedades en clase separada donde algunos de ellos son referidos a clases específicas de POJO? Lo hice para usar search()9 MÉTODO FÁCIL OBJETIVO DE SPEP DE PASO (NO POR UNA INTERRACIÓN DE CIERTOS DE OBJETIVO) A él.
  • ¿Cómo debo tratar con {-# OPTIONS_GHC -Wall #-} module SQMULID where import Data.Char import Data.List import Data.Maybe import Test.HUnit import Test.QuickCheck import Test.QuickCheck.Gen class Ring a where addId :: a -- additive identity addInv :: a -> a -- additive inverse mulId :: a -- multiplicative identity add :: a -> a -> a -- addition mul :: a -> a -> a -- multiplication -- | A datatype for storing and manipulating ring expressions. data RingExpr a = Lit a | AddId | AddInv (RingExpr a) | MulId | Add (RingExpr a) (RingExpr a) | Mul (RingExpr a) (RingExpr a) deriving (Show, Eq) instance Ring (RingExpr a) where addId = AddId addInv = AddInv mulId = MulId add = Add mul = Mul -- The canonical instance for integers: instance Ring Integer where addId = 0 addInv = negate mulId = 1 add = (+) mul = (*) 0 ? Debería ponerlo dentro 99887766555443311 que se extiende desde {-# OPTIONS_GHC -Wall #-} module SQMULID where import Data.Char import Data.List import Data.Maybe import Test.HUnit import Test.QuickCheck import Test.QuickCheck.Gen class Ring a where addId :: a -- additive identity addInv :: a -> a -- additive inverse mulId :: a -- multiplicative identity add :: a -> a -> a -- addition mul :: a -> a -> a -- multiplication -- | A datatype for storing and manipulating ring expressions. data RingExpr a = Lit a | AddId | AddInv (RingExpr a) | MulId | Add (RingExpr a) (RingExpr a) | Mul (RingExpr a) (RingExpr a) deriving (Show, Eq) instance Ring (RingExpr a) where addId = AddId addInv = AddInv mulId = MulId add = Add mul = Mul -- The canonical instance for integers: instance Ring Integer where addId = 0 addInv = negate mulId = 1 add = (+) mul = (*) 2 como ahora o puedo generificar 99887776655443313 en {-# OPTIONS_GHC -Wall #-} module SQMULID where import Data.Char import Data.List import Data.Maybe import Test.HUnit import Test.QuickCheck import Test.QuickCheck.Gen class Ring a where addId :: a -- additive identity addInv :: a -> a -- additive inverse mulId :: a -- multiplicative identity add :: a -> a -> a -- addition mul :: a -> a -> a -- multiplication -- | A datatype for storing and manipulating ring expressions. data RingExpr a = Lit a | AddId | AddInv (RingExpr a) | MulId | Add (RingExpr a) (RingExpr a) | Mul (RingExpr a) (RingExpr a) deriving (Show, Eq) instance Ring (RingExpr a) where addId = AddId addInv = AddInv mulId = MulId add = Add mul = Mul -- The canonical instance for integers: instance Ring Integer where addId = 0 addInv = negate mulId = 1 add = (+) mul = (*) 4 de alguna manera? ¿Cuál será la mejor manera en mi caso?
  • ¿Cómo puedo implementar {-# OPTIONS_GHC -Wall #-} module SQMULID where import Data.Char import Data.List import Data.Maybe import Test.HUnit import Test.QuickCheck import Test.QuickCheck.Gen class Ring a where addId :: a -- additive identity addInv :: a -> a -- additive inverse mulId :: a -- multiplicative identity add :: a -> a -> a -- addition mul :: a -> a -> a -- multiplication -- | A datatype for storing and manipulating ring expressions. data RingExpr a = Lit a | AddId | AddInv (RingExpr a) | MulId | Add (RingExpr a) (RingExpr a) | Mul (RingExpr a) (RingExpr a) deriving (Show, Eq) instance Ring (RingExpr a) where addId = AddId addInv = AddInv mulId = MulId add = Add mul = Mul -- The canonical instance for integers: instance Ring Integer where addId = 0 addInv = negate mulId = 1 add = (+) mul = (*) 5 MÉTODO INTERIOR {-# OPTIONS_GHC -Wall #-} module SQMULID where import Data.Char import Data.List import Data.Maybe import Test.HUnit import Test.QuickCheck import Test.QuickCheck.Gen class Ring a where addId :: a -- additive identity addInv :: a -> a -- additive inverse mulId :: a -- multiplicative identity add :: a -> a -> a -- addition mul :: a -> a -> a -- multiplication -- | A datatype for storing and manipulating ring expressions. data RingExpr a = Lit a | AddId | AddInv (RingExpr a) | MulId | Add (RingExpr a) (RingExpr a) | Mul (RingExpr a) (RingExpr a) deriving (Show, Eq) instance Ring (RingExpr a) where addId = AddId addInv = AddInv mulId = MulId add = Add mul = Mul -- The canonical instance for integers: instance Ring Integer where addId = 0 addInv = negate mulId = 1 add = (+) mul = (*) 6 {-# OPTIONS_GHC -Wall #-} module SQMULID where import Data.Char import Data.List import Data.Maybe import Test.HUnit import Test.QuickCheck import Test.QuickCheck.Gen class Ring a where addId :: a -- additive identity addInv :: a -> a -- additive inverse mulId :: a -- multiplicative identity add :: a -> a -> a -- addition mul :: a -> a -> a -- multiplication -- | A datatype for storing and manipulating ring expressions. data RingExpr a = Lit a | AddId | AddInv (RingExpr a) | MulId | Add (RingExpr a) (RingExpr a) | Mul (RingExpr a) (RingExpr a) deriving (Show, Eq) instance Ring (RingExpr a) where addId = AddId addInv = AddInv mulId = MulId add = Add mul = Mul -- The canonical instance for integers: instance Ring Integer where addId = 0 addInv = negate mulId = 1 add = (+) mul = (*) 7 Las clases que aprovecharán la oportunidad para recibir todas las especificaciones ( {-# OPTIONS_GHC -Wall #-} module SQMULID where import Data.Char import Data.List import Data.Maybe import Test.HUnit import Test.QuickCheck import Test.QuickCheck.Gen class Ring a where addId :: a -- additive identity addInv :: a -> a -- additive inverse mulId :: a -- multiplicative identity add :: a -> a -> a -- addition mul :: a -> a -> a -- multiplication -- | A datatype for storing and manipulating ring expressions. data RingExpr a = Lit a | AddId | AddInv (RingExpr a) | MulId | Add (RingExpr a) (RingExpr a) | Mul (RingExpr a) (RingExpr a) deriving (Show, Eq) instance Ring (RingExpr a) where addId = AddId addInv = AddInv mulId = MulId add = Add mul = Mul -- The canonical instance for integers: instance Ring Integer where addId = 0 addInv = negate mulId = 1 add = (+) mul = (*) 8 < / Código>, {-# OPTIONS_GHC -Wall #-} module SQMULID where import Data.Char import Data.List import Data.Maybe import Test.HUnit import Test.QuickCheck import Test.QuickCheck.Gen class Ring a where addId :: a -- additive identity addInv :: a -> a -- additive inverse mulId :: a -- multiplicative identity add :: a -> a -> a -- addition mul :: a -> a -> a -- multiplication -- | A datatype for storing and manipulating ring expressions. data RingExpr a = Lit a | AddId | AddInv (RingExpr a) | MulId | Add (RingExpr a) (RingExpr a) | Mul (RingExpr a) (RingExpr a) deriving (Show, Eq) instance Ring (RingExpr a) where addId = AddId addInv = AddInv mulId = MulId add = Add mul = Mul -- The canonical instance for integers: instance Ring Integer where addId = 0 addInv = negate mulId = 1 add = (+) mul = (*) 9 Si hablamos de GenericDAO0 clase) Aplicable para una cierta clase POJO?

nb! Si ve que se podría optimizar un poco de código, por favor llévame.

Interfaz Genericdao:

  GenericDAO1  

Implementación genericdao:

  GenericDAO2  

Interfaz de EmpleadoEEO:

  GenericDAO3  

Empleado
  GenericDAO4  

Interfaz de CustomerDAO:

  GenericDAO5  

CustomerDao Implementación:

  GenericDAO6  

Clase de personal de personal:

Esta clase agregada para tener una única entrada al empleado y el cliente Daos. Además, oculto toda la funcionalidad de Daos Thatstks a esta clase.

  GenericDAO7  

Clase de empleados:

  GenericDAO8  

Clase de clientes:

  GenericDAO9  

Clase de empleados:

  Customer0  

Clase de PERSONALES PECOS:

  Customer1  
Original en ingles

I have base abstract GenericDAO class that executes CRUD operations with different kind of objects. Customer and Employee POJO classes are used in specific DAO classes that extends GenericDAO class. From my previous related question I have some unresolved problems:

Questions:

  • How to realize immutable objects in GenericDAOImpl?
  • Is it a good idea or not to separate object(i.e. EmployeeSpecs, PersonalSpecs) properties in separate class where some of them are refereced to specific POJO classes? I did it to use search() method easier passing spec object(not by a certain object property) to it.
  • How should I deal with search() method? I should put it inside specific DAO which is extended from GenericDAO as it's now or I can generify search() method in GenericDAO somehow? What will be the best way in my case?
  • How can I implement getSpec() method inside Customer or Employee classes which will take the opportunity to receive all specs(PersonalSpecs, EmployeeSpecs if we talk about Employee class) applicable for a certain pojo class?

NB! If you see that some piece of code could be optimized, please take me know.

GenericDAO interface:

public interface GenericDAO<T> {     boolean add(T t);     boolean update(int index, T t);     boolean remove(T t);     T getByIndex(int index);     List<T> getAll();      // I want to add search method here if it's possible to search by any multiple object specs } 

GenericDAO implementation:

public abstract class GenericDAOImpl<T> implements GenericDAO<T> {      private static final Logger Logger = LoggerFactory.getLogger(GenericDAOImpl.class);      private Set<T> objects = new HashSet<T>();      @Override     public boolean add(T t) {         if (t != null && !objects.contains(t)) {             if (objects.add(t)) {                 Logger.info("Added new " + t.toString());                 return true;             }         }          return false;     }      @Override     public boolean update(int index, T t) {         if (index >= 0 && t != null) {             T obj = getByIndex(index);             if (obj != null) {                 if (objects.remove(obj) && objects.add(t)) {                     Logger.info("Updated " + obj.toString() + " to " + t.toString());                     return true;                 }             }         }         return false;     }      @Override     public boolean remove(T t) {         if (t != null && objects.contains(t)) {             if (objects.remove(t)) {                 Logger.info("Removed " + t.toString());                 return true;             }         }          return false;     }      @Override     public T getByIndex(int index) {         if (index >= 0 && index < objects.size()) {             return new ArrayList<T>(objects).get(index);         }          return null;     }      @Override     public List<T> getAll() {         return new ArrayList<T>(objects);     } } 

EmployeeDAO interface:

public interface EmployeeDAO {     List<Employee> search(PersonalSpecs personalSpecs, EmployeeSpecs employeeSpecs, boolean nameComparable); } 

EmployeeDAO implemenetation:

public class EmployeeDAOImpl extends GenericDAOImpl<Employee> implements EmployeeDAO {      @Override     public List<Employee> search(PersonalSpecs personalSpecs, EmployeeSpecs employeeSpecs, boolean nameComparable) {         if (personalSpecs != null || employeeSpecs != null) {             for (Employee employee : getAll()) {                 if (employee.getPersonalSpecs().matches(personalSpecs, nameComparable) || (!nameComparable && employee.getEmployeeSpecs().matches(employeeSpecs))) {                     add(employee);                 }             }         }          return getAll();     } } 

CustomerDAO interface:

public interface CustomerDAO {     List<Customer> search(PersonalSpecs personalSpecs, boolean nameComparable); } 

CustomerDAO implementation:

public class CustomerDAOImpl extends GenericDAOImpl<Customer> implements CustomerDAO {      @Override     public List<Customer> search(PersonalSpecs personalSpecs, boolean nameComparable) {         if (personalSpecs != null) {             for (Customer customer : getAll()) {                 if (customer.getPersonalSpecs().matches(personalSpecs, nameComparable)) {                     add(customer);                 }             }         }          return getAll();     } } 

StaffManagement class:

This class added to have a single entry to Employee and Customer DAOs. Moreover, I hide all functionality of DAOs thatnks to this class.

public class StaffManagement {      private CustomerDAOImpl customerDAO;     private EmployeeDAOImpl employeeDAO;      public StaffManagement() {         this.customerDAO = new CustomerDAOImpl();         this.employeeDAO = new EmployeeDAOImpl();     }      public StaffManagement(List<Customer> customers, List<Employee> employees) {         super();         addAllCustomers(customers);         addAllEmployees(employees);     }      public boolean addCustomer(Customer customer) {         return customerDAO.add(customer);     }      public boolean addEmployee(Employee employee) {         return employeeDAO.add(employee);     }      private boolean addAllCustomers(List<Customer> customers) {         if (customers == null) {             return false;         }          for (Customer customer : customers) {             if (!customerDAO.add(customer)) {                 return false;             }         }          return true;     }      private boolean addAllEmployees(List<Employee> employees) {         if (employees == null) {             return false;         }          for (Employee employee : employees) {             if (!employeeDAO.add(employee)) {                 return false;             }         }          return true;     }      public boolean removeCustomer(Customer customer) {         return customerDAO.remove(customer);     }      public boolean removeEmployee(Employee employee) {         return employeeDAO.remove(employee);     }      public Customer getCustomerByIndex(int index) {         return customerDAO.getByIndex(index);     }      public Employee getEmployeeByIndex(int index) {         return employeeDAO.getByIndex(index);     }      public List<Customer> getAllCustomers() {         return customerDAO.getAll();     }      public List<Employee> getAllEmployees() {         return employeeDAO.getAll();     }      public boolean updateEmployeeSpecs(Employee employee, PersonalSpecs personalSpecs, EmployeeSpecs employeeSpecs) {         boolean change = false;          if (employee != null) {              List<Employee> employees = getAllEmployees();             if (personalSpecs != null) {                 for (Employee existedEmployee : employees) {                     if (existedEmployee.getPersonalSpecs().matches(personalSpecs, true)) {                         return false;                     }                 }                  removeEmployee(employee);                 employee.setPersonalSpecs(personalSpecs);                 change = addEmployee(employee);             }              if (employeeSpecs != null) {                 removeEmployee(employee);                 employee.setEmployeeSpecs(employeeSpecs);                 change = addEmployee(employee);             }         }          return change;     }      public boolean updateCustomerSpecs(Customer customer, PersonalSpecs personalSpecs) {         boolean change = false;          if (customer != null) {              List<Customer> customers = getAllCustomers();             if (personalSpecs != null) {                 for (Customer existedCustomer : customers) {                     if (existedCustomer.getPersonalSpecs().matches(personalSpecs, true)) {                         return false;                     }                 }                  removeCustomer(customer);                 customer.setPersonalSpecs(personalSpecs);                 change = addCustomer(customer);             }         }          return change;     }      public List<Customer> searchCustomersBySpec(PersonalSpecs personalSpecs, boolean nameComparable) {         return customerDAO.search(personalSpecs, nameComparable);     }      public List<Employee> searchEmployeesBySpec(PersonalSpecs personalSpecs, EmployeeSpecs employeeSpecs, boolean nameComparable) {         return employeeDAO.search(personalSpecs, employeeSpecs, nameComparable);     } } 

Employee class:

public class Employee {  /** ** Is it a good idea or not to separate object properties in separate file to easy search any Employee objects by these specs? **/      private PersonalSpecs personalSpecs;     private EmployeeSpecs employeeSpecs;      public Employee(PersonalSpecs personalSpecs, EmployeeSpecs employeeSpecs) {         this.personalSpecs = personalSpecs;         this.employeeSpecs = employeeSpecs;     }      public PersonalSpecs getPersonalSpecs() {         return personalSpecs;     }      public void setPersonalSpecs(PersonalSpecs personalSpecs) {         this.personalSpecs = personalSpecs;     }      public EmployeeSpecs getEmployeeSpecs() {         return employeeSpecs;     }      public void setEmployeeSpecs(EmployeeSpecs employeeSpecs) {         this.employeeSpecs = employeeSpecs;     }      @Override     public int hashCode() {         return Objects.hash(this.personalSpecs.getName(), this.personalSpecs.getSurname());     }      @Override     public boolean equals(Object obj) {         // Not strictly necessary, but often a good optimization         if (this == obj) {             return true;         }          if (!(obj instanceof Employee)) {             return false;         }          Employee otherEmployee = (Employee) obj;         return (personalSpecs.getName().equals(otherEmployee.getPersonalSpecs().getName())                 && personalSpecs.getSurname().equals(otherEmployee.getPersonalSpecs().getSurname()));     }      @Override     public String toString() {         return "Employee:\n" +                 personalSpecs +                 "\n" +                 employeeSpecs;     } } 

Customer class:

public class Customer {  /** ** Is it a good idea or not to separate object properties in separate file to easy search any Employee objects by these specs? **/      private PersonalSpecs personalSpecs;     private int bonus;      public Customer(PersonalSpecs personalSpecs) {         this.personalSpecs = personalSpecs;     }      public Customer(PersonalSpecs personalSpecs, int bonus) {         this.personalSpecs = personalSpecs;         this.bonus = bonus;     }      public PersonalSpecs getPersonalSpecs() {         return personalSpecs;     }      public void setPersonalSpecs(PersonalSpecs personalSpecs) {         this.personalSpecs = personalSpecs;     }      public int getBonus() {         return bonus;     }      public void setBonus(int bonus) {         this.bonus = bonus;     }      @Override     public int hashCode() {         return Objects.hash(this.personalSpecs.getName(), this.personalSpecs.getSurname());     }      @Override     public boolean equals(Object obj) {         // Not strictly necessary, but often a good optimization         if (this == obj) {             return true;         }          if (!(obj instanceof Customer)) {             return false;         }          Customer otherCustomer = (Customer) obj;         return (personalSpecs.getName().equals(otherCustomer.getPersonalSpecs().getName())                 && personalSpecs.getSurname().equals(otherCustomer.getPersonalSpecs().getSurname()));     }      @Override     public String toString() {         return "Customer: " +                 personalSpecs +                 ", bonus=" + bonus;     } } 

EmployeeSpecs class:

public class EmployeeSpecs {     private EmployeeType type;     private String position;     private Date start;      public enum EmployeeType {         CONTRACTOR,         FULLTIME     }      public EmployeeSpecs(EmployeeType type, String position) {         this.type = type;         this.position = position;     }      public EmployeeType getType() {         return type;     }      public void setType(EmployeeType type) {         this.type = type;     }      public String getPosition() {         return position;     }      public void setPosition(String position) {         this.position = position;     }      public Date getStart() {         return start;     }      public void setStart(Date start) {         this.start = start;     }      public boolean matches(EmployeeSpecs employeeSpecs) {         if (employeeSpecs != null) {             if ((employeeSpecs.getType() == type)                     || (employeeSpecs.getPosition() != null && !employeeSpecs.getPosition().isEmpty() && employeeSpecs.getPosition().equals(position))                     || (employeeSpecs.getStart() != null && employeeSpecs.getStart().equals(start))) {                 return true;             }         }         return false;     }      @Override     public String toString() {         return "[" +                 "type=" + type +                 ", position='" + position + '\'' +                 ", start=" + start +                 ']';     } } 

PersonalSpecs class:

public class PersonalSpecs {      private String name;     private String surname;     private Sex sex;     private int age;      public enum Sex {MALE, FEMALE}      public PersonalSpecs(String name, String surname, Sex sex) {         this.name = name;         this.surname = surname;         this.sex = sex;     }      public PersonalSpecs(String name, String surname, Sex sex, int age) {         this.name = name;         this.surname = surname;         this.age = age;         this.sex = sex;     }      public String getName() {         return name;     }      public void setName(String name) {         this.name = name;     }      public String getSurname() {         return surname;     }      public void setSurname(String surname) {         this.surname = surname;     }      public Sex getSex() {         return sex;     }      public void setSex(Sex sex) {         this.sex = sex;     }      public int getAge() {         return age;     }      public void setAge(int age) {         this.age = age;     }      public boolean matches(PersonalSpecs personalSpecs, boolean strict) {         if (personalSpecs != null) {             if (strict) {                 // Check matches only by full name                 return (personalSpecs.getName() != null && !personalSpecs.getName().isEmpty() && personalSpecs.getName().equals(name))                         && (personalSpecs.getSurname() != null && !personalSpecs.getSurname().isEmpty() && personalSpecs.getSurname().equals(surname));             } else {                 // Check any matches                 return (personalSpecs.getName() != null && !personalSpecs.getName().isEmpty() && personalSpecs.getName().equals(name))                         || (personalSpecs.getSurname() != null && !personalSpecs.getSurname().isEmpty() && personalSpecs.getSurname().equals(surname))                         || (personalSpecs.getSex() == sex)                         || (personalSpecs.getAge() != 0 && personalSpecs.getAge() == age);             }         }         return false;     }      @Override     public String toString() {         return "[" +                 "name='" + name + '\'' +                 ", surname='" + surname + '\'' +                 ", sex=" + sex +                 ", age=" + age +                 ']';     } } 
  

Lista de respuestas

2
 
vote
  • ¿Cómo realizar objetos inmutables en GenericDaOImpl?

Al crear copias de los objetos que ingrese, en lugar de mantener las referencias a los objetos. Con genéricos, esto puede ser complicado, pero si T se extiende de manera clonable, al menos podría llamar clon () en él para crear un campo para la copia de campo. Esto no le conseguirá el control que tendría si supiera qué tipos usa, pero es algo al menos. Como salida (cuando se le solicite una propiedad), debe hacer una copia, para que nadie pueda alterar su estado interno. Regla básica del pulgar: No confíe en la entrada Usted puede no ser destruido, no confíe en la producción que le dé a permanecer sin ser defendido.

Su empleado DAO mantiene un conjunto interno de objetos (que está bien para una versión en memoria de un dao que supongo. Aunque no es "acceder" nada, pero es el mapa / lista internos.) Sin embargo, pareces ser Mezclando esto en tu búsqueda. En un DAO, esperaría que una búsqueda devolviera una lista de objetos sin cambiar su estado interno.

Sin embargo, en su caso, si lo hago: (excusa el final de los comentarios de la línea)

  EmployeeDao dao = (get from somewhere); dao.add(someEmployee); dao.add(otherEmployee); dao.getAll(); // returns someEmployee, otherEmployee;  // assume spec matches only otherEmployee // search returns someEmployee, otherEmployee dao.search(specX, specY);  // returns someEmployee, otherEmployee   

Podría estar malentendiendo el código anterior, pero creo que su búsqueda debe hacer:

  public List<Employee> search(PersonalSpecs personalSpecs, EmployeeSpecs employeeSpecs, boolean nameComparable) {     List<Employee> result = new ArrayList<Employee>();      if (personalSpecs == null && employeeSpecs == null) {         return result;     }      // there is actually something to search on.     for (Employee employee : getAll()) {         if (employee.getPersonalSpecs().matches(personalSpecs, nameComparable) || (!nameComparable && employee.getEmployeeSpecs().matches(employeeSpecs))) {             result.add(employee);         }     }      return result; }   

OFCURSO EN COMBINACIÓN CON EL CLONE: Resultados.add (empleado.clone ())

  • ¿Es una buena idea o no separar las propiedades de objetos (es decir, empleados, personas personales) en clase separada donde algunos de ellos son referidos a clases específicas de POJO? Lo hice para usar el método de búsqueda () un objeto de especificación más fácil de pasar (no por una propiedad de un objeto determinado).

Creo que está mejor que mantiene sus propiedades divididas por cómo se organiza su dominio en lugar de cómo una búsqueda ocurre que los necesita agrupados. Esto podría ser el mismo en este momento, pero puede cambiar. ¿Qué sucede si tiene 3 tipos de búsquedas más que funcionan en objetos superpuestos? Sin embargo, podría tener el objeto devolver una representación de sí misma si quiere hacerlo de esa manera. Esto permitirá que un objeto tenga todo tipo de propiedades organizadas de varias maneras, pero cuando necesita una versión de especificación de un conjunto de atributos, puede crear esto.

  // in Employee:  public final EmployeeSpec getEmployeeSpec() {     EmployeeSpec spec = new EmployeeSpec(this.xx, this.yy); }   

Esto todavía te limita hasta cierto punto. (Te lo atra a la especificación, debe agregarlo a todo lo que le gustaría buscar). Me estoy volviendo un poco fuera de mi profundidad aquí, pero podría tener una clase de "especificaciones" que hace algo así:

  // could call it specmatcher but I didn't want to make it look like it was still using spec. public interface Matcher<T> {      public boolean matches(T match);   }  // ofcourse implement this as you wish, in your case with strict/nonstrict. public static class EmployeeMatcher extends Matcher<Employee> {      private EmployeeType type;      public boolean matches(Employee match) {           if (type.equals(match.getType()) {                return true;           }      } }   

Debería modificar su método de búsqueda para hacer:

   public List<Employee> search(Matcher<Employee> matcher) {     List<Employee> result = new ArrayList<Employee>();     for (Employee employee : getAll()) {         if (matcher.matches(employee) {             result.add(employee);         }     }     return result; }   
  • ¿Cómo debo lidiar con el método de búsqueda ()? Debería ponerlo dentro de DAO específico que se extiende desde Genericdao, ya que ahora o puedo generificar el método de búsqueda () en Genericdao de alguna manera? ¿Cuál será la mejor manera en mi caso?

El siguiente código debe hacer eso (reemplazar al empleado con T)

  public List<T> search(Matcher<T> matcher) {     List<T> result = new ArrayList<T>();     for (T t : getAll()) {         if (matcher.matches(t) {             result.add(t);         }     }     return result; }   
  • ¿Cómo puedo implementar el método GETSPEC () dentro de las clases de clientes o empleados que aproveche la oportunidad de recibir todas las especificaciones (Personalspecs, empleados, si hablamos de clase de empleados) aplicable para una cierta clase POJO?

Dejaría las especificaciones por completo y usaría el coincidente. o mantenga las especificaciones al menos solo como formas de alimentar a los matrizadores.

de nuevo (la mencionó anteriormente) parte de esta es una conjetura educada. Espero haber entendido tu pregunta.

punteros (y por favor, si alguien no está de acuerdo, déjame un comentario):

  • La búsqueda y los métodos de búsqueda similares no deben mutilar su estado interno. Trabaje en la pila o rellene un objeto que recibe como parámetro en su lugar.

  • Si necesita tener una versión estricta y no estricta de un método, personalmente no usaría esto:

    Partidos booleanos públicos (PERSONALES PERSONALES PERSONALES, BOOLEAN STRICT)

pero yo usaría:

  public boolean matchesLoose(PersonalSpecs personalSpecs); public boolean matchesStrict(PersonalSpecs personalSpecs);       

Esto hará que su lógica interna sea más simple y reducirá la complejidad ciclomática. Por supuesto, esto no siempre va, pero los booleanos que se dividen entre 2, las rutas de código completamente separadas, realmente no agregan nada. Por supuesto si desea 1 punto de entrada, podría tener

  public boolean matches(PersonalSpecs personalSpecs, boolean strict) {     if (strict) {          return matchesStrict(personalSpecs);     } else {          return matchesLoose(personalSpecs);     } }  public boolean matchesLoose(PersonalSpecs personalSpecs); public boolean matchesStrict(PersonalSpecs personalSpecs);       
 
  • How to realize immutable objects in GenericDAOImpl?

By creating copies of the objects you get in, rather than keeping references to the objects. With generics this is may be tricky but if T extends Cloneable you could at least call clone() on it to create a field for field copy. This will not get you the control you would have if you knew which types you use but it is something at least. As output (when asked for a property) you should again make a copy, so that noone can alter your internal state. basic rule of thumb: don't trust input you get to be unmutated, don't trust output you give to stay unmutated.

Your employee DAO maintains an internal set of objects (which is fine for an in-memory version of a dao I suppose. though it's not "accessing" anything but it's internal map/list/set. ) However you seem to be mixing this up in your search. On a dao, I would expect a search to return a list of objects without changing it's internal state.

However in your case, if I do: (excuse the end of line comments)

EmployeeDao dao = (get from somewhere); dao.add(someEmployee); dao.add(otherEmployee); dao.getAll(); // returns someEmployee, otherEmployee;  // assume spec matches only otherEmployee // search returns someEmployee, otherEmployee dao.search(specX, specY);  // returns someEmployee, otherEmployee 

I might be misunderstanding the above code ofcourse, but I think your search should do:

public List<Employee> search(PersonalSpecs personalSpecs, EmployeeSpecs employeeSpecs, boolean nameComparable) {     List<Employee> result = new ArrayList<Employee>();      if (personalSpecs == null && employeeSpecs == null) {         return result;     }      // there is actually something to search on.     for (Employee employee : getAll()) {         if (employee.getPersonalSpecs().matches(personalSpecs, nameComparable) || (!nameComparable && employee.getEmployeeSpecs().matches(employeeSpecs))) {             result.add(employee);         }     }      return result; } 

ofcourse in combination with clone : result.add(employee.clone())

  • Is it a good idea or not to separate object(i.e. EmployeeSpecs, PersonalSpecs) properties in separate class where some of them are refereced to specific POJO classes? I did it to use search() method easier passing spec object(not by a certain object property) to it.

I think you are better off keeping your properties divided by how your domain is organized rather than how a search happens to need them grouped. This might be the same at the moment but it may change. What if you have 3 more types of searches that work on overlapping objects. However you could have the object return a representation of itself if you want to do it that way. This will allow an object to have all sorts of properties organized in a number of ways, but when you need a spec version of a set of attributes it can create this.

// in Employee:  public final EmployeeSpec getEmployeeSpec() {     EmployeeSpec spec = new EmployeeSpec(this.xx, this.yy); } 

This still limits you to some degree. (it ties you to the spec, you have to add it to every thing you would like to search for). I'm getting a little out of my depth here, but you could have a "Spec" class that does something like:

// could call it specmatcher but I didn't want to make it look like it was still using spec. public interface Matcher<T> {      public boolean matches(T match);   }  // ofcourse implement this as you wish, in your case with strict/nonstrict. public static class EmployeeMatcher extends Matcher<Employee> {      private EmployeeType type;      public boolean matches(Employee match) {           if (type.equals(match.getType()) {                return true;           }      } } 

You would need to alter your search method to do:

 public List<Employee> search(Matcher<Employee> matcher) {     List<Employee> result = new ArrayList<Employee>();     for (Employee employee : getAll()) {         if (matcher.matches(employee) {             result.add(employee);         }     }     return result; } 
  • How should I deal with search() method? I should put it inside specific DAO which is extended from GenericDAO as it's now or I can generify search() method in GenericDAO somehow? What will be the best way in my case?

The below code should do that (replace Employee with T)

public List<T> search(Matcher<T> matcher) {     List<T> result = new ArrayList<T>();     for (T t : getAll()) {         if (matcher.matches(t) {             result.add(t);         }     }     return result; } 
  • How can I implement getSpec() method inside Customer or Employee classes which will take the opportunity to receive all specs(PersonalSpecs, EmployeeSpecs if we talk about Employee class) applicable for a certain pojo class?

I would drop specs altogether and use matcher. or keep specs at least only as ways to feed matchers.

Again (mentioned it earlier) part of this is an educated guess. I'm hoping I've understood your question.

Pointers (and please if anyone disagrees, leave me a comment):

  • search and similar lookup methods should not mutate your internal state. work on the stack or fill in an object you receive as a parameter instead.

  • If you do need to have a strict and a nonstrict version of a method, I would personally not use this:

    public boolean matches(PersonalSpecs personalSpecs, boolean strict)

but I would use:

public boolean matchesLoose(PersonalSpecs personalSpecs); public boolean matchesStrict(PersonalSpecs personalSpecs);     

this will make your internal logic simpler and will reduce the cyclomatic complexity. Ofcourse this doesn't always go, but booleans that split between 2 entirely separate code paths don't really add anything. ofcourse if you want 1 entrypoint you could have

public boolean matches(PersonalSpecs personalSpecs, boolean strict) {     if (strict) {          return matchesStrict(personalSpecs);     } else {          return matchesLoose(personalSpecs);     } }  public boolean matchesLoose(PersonalSpecs personalSpecs); public boolean matchesStrict(PersonalSpecs personalSpecs);     
 
 

Relacionados problema

2  Fusionar la implementación de Sort Java  ( Merge sort java implementation ) 
¿Puede alguien revisar mi implementación de tipo de fusión en Java? ¿Es bueno / malo y puede mejorarse más? public class MyMergeSort { private int [] d...

6  Encontrar el siguiente palíndromo de una cadena de números  ( Finding the next palindrome of a number string ) 
Aquí está el problema: Un entero positivo se llama palíndromo si su representación en el El sistema decimal es el mismo cuando se lee de izquierda a dere...

2  Eliminación de un nodo en un árbol de búsqueda binario  ( Deletion of a node in a binary search tree ) 
Estoy buscando ver si mi implementación del método de eliminación / eliminación en un árbol de búsqueda binario es suficiente, legible y se ejecuta en un tiem...

17  Implementación vectorial (física)  ( Vector physics implementation ) 
Recientemente comencé a aprender Java, y decidí implementar un sistema de vectores básico para otro sistema de partículas que estaba construyendo. join()9 ...

2  Solucionador de rompecabezas de rascacielos en Java [cerrado]  ( Skyscraper puzzle solver in java ) 
cerrado. Esta pregunta es off-topic . Actualmente no está aceptando respuestas. ¿Quieres ...

34  Clon a todo color del juego de la vida de Conway, con una GUI decente  ( Full color clone of conways game of life with a decent gui ) 
Escribí esto para aprender Javafx, y como excusa para volver a hacer el juego de la vida. Esta es la gui más compleja que he escrito, así que me gustaría come...

5  Memoria / Performance of Merge Sort Code  ( Memory performance of merge sort code ) 
Escribí un código de tipo de combinación para un poco de bocadillo nocturno. Lo he puesto trabajando, pero solo estaba mirando a aprender si me faltaba algo e...

8  Simple GCD Utility en Java  ( Simple gcd utility in java ) 
i anteriormente discutido El rendimiento se refiere a diferentes algoritmos GCD. Escribí una simple clase de Java que implementa el algoritmo binario GCD. E...

1  Compruebe si dos cadenas son permutación entre sí  ( Check if two strings are permutation of each other ) 
private String sort(String word) { char[] content = word.toCharArray(); Arrays.sort(content); return new String(content); } private boolea...

5  Encuentre el próximo número Prime - Control de flujo de los bucles anidados 'para `  ( Find the next prime number flow control of nested for loops ) 
Este código funciona perfectamente, pero me molesta. Tener un bucle etiquetado y anidado Bucle, con un Enumerable<T>.Empty()0 Declaración, y un 9988777665...




© 2022 respuesta.top Reservados todos los derechos. Centro de preguntas y respuestas reservados todos los derechos