Il modo migliore per invocare il "metodo setter" per il primo accesso e il "metodo getter" per il resto con il modello "getter setter"?

1

Ecco un json che viene visualizzato nella richiesta param. Sto costruendo una classe con getter e setter per accedere ai valori in json in modo che possa essere in grado di passare l'oggetto di classe a metodi diversi e in grado di accedere alle variabili membro in essi.

public class RequestParams {
    private String student_id;
    private String student_name;
    private String student_role_number;
    private String department_name;
    private String stream;

    private JSONObject studentDetails;

    public RequestParams(HttpServletRequest request) {
        this.studentDetails = request.getParameter(“studentdetails”);
    }

    public String getStudentId() {
        if(this.student_id == null) {
            this.setStudentId();
        }
        return this.student_id;
    }
    public String getStudentName() {
        if(this.student_name == null) {
            this.setStudentName();
        }
        return this.student_name;
    }
    public String getRoleNumber() {
        if(this.student_role_number == null) {
            this.setRoleNumber();
        }
        return this.student_role_number;
    }
    public String getDepartmentName() {
        if(this.department_name == null) {
            this.setDepartmentName();
        }
        return this.student_name;
    }
    public String getStream() {
        if(this.stream == null) {
            this.setStream();
        }
        return this.stream;
    }
    public void setStudentId() {
        this.student_id = this.studentDetails.getString("student_id");
    }
    public void setStudentName() {
        this.student_name = this.studentDetails.getString("student_name");
    }
    public void setRoleNumber() {
        this.student_role_number = this.studentDetails.getString("role_number");
    }
    public void setDepartmentName() {
        this.department_name = this.studentDetails.getString("department_name");
    }
    public void setStream() {
        this.stream = this.studentDetails.getString("stream");
    }
}

Hai i seguenti dubbi,

  1. Costruire come oggetto di classe per farvi riferimento da metodi diversi - È buono? Sto sbagliando?
  2. Come organizzare il mio setter getter in modo che solo il set venga chiamato solo per la prima volta e per le chiamate successive il valore venga restituito direttamente? Esiste un modo migliore per evitare il controllo Null ogni volta

if(this.student_id == null) {

this.setStudentId();

}

  1. C'è qualche vantaggio nell'accedere ai metodi e alle variabili all'interno della classe con this. ?

PS: non ho potuto richiamare inizialmente tutti i setter dal costruttore perché tutti i valori dichiarati nella classe non devono necessariamente essere presenti nel json. Quindi, ho pensato che sarebbe stato meglio se avessi potuto inizializzare la variabile membro con valore durante il primo accesso.

    
posta rm -rf star 18.03.2017 - 11:50
fonte

2 risposte

6

Le tue variabili membro sono ridondanti. Dovresti memorizzare JSONObject o String s ma non entrambi. Ciò eviterà problemi di coerenza.

Ecco un suggerimento:

public class RequestParams {
    private final String student_id;
    private final String student_name;
    private final String student_role_number;
    private final String department_name;
    private final String stream;

    public RequestParams(HttpServletRequest request) {
        JSONObject studentDetails = request.getParameter(“studentdetails”);
        this.student_id = studentDetails.getString("student_id");
        this.student_name = studentDetails.getString("student_name");
        this.student_role_number = studentDetails.getString("role_number");
        this.department_name = studentDetails.getString("department_name");
        this.stream = studentDetails.getString("stream");
    }

    public String getStudentId() {
        return this.student_id;
    }
    public String getStudentName() {
        return this.student_name;
    }
    public String getRoleNumber() {
        return this.student_role_number;
    }
    public String getDepartmentName() {
       return this.student_name;
    }
    public String getStream() {
        return this.stream;
    }
}

Si noti che le variabili membro possono essere fatte final e la classe è ora immutabile.

    
risposta data 18.03.2017 - 12:21
fonte
2

Tale approccio di inizializzazione è chiamato Inizializzazione pigra

lazy initialization is the tactic of delaying the creation of an object, the calculation of a value, or some other expensive process until the first time it is needed.

Alcune lingue / piattaforme forniscono un modo standard per esprimere un tale costrutto (come C # 's Lazy<T> classe), mentre in altri devi implementarlo tu stesso / trovare qualche soluzione di libreria di terze parti.

Per quanto posso vedere, non c'è implementazione standard di questo pattern in Java, quindi puoi creare un simple custom one , oppure usane uno da popolari librerie di terze parti .

Supponendo che l'implementazione lazy scelta sia chiamata Lazy<T> la tua classe sarà simile a:

public class RequestParams {
    private Lazy<String> student_id;

    private JSONObject studentDetails;

    public RequestParams(HttpServletRequest request) {
        this.studentDetails = request.getParameter(“studentdetails”);
        this.studentId = new Lazy<String>(() -> this.createStudentId());
    }

    public String getStudentId() {
        return this.student_id.value();
    }

    public String createStudentId() {
        return this.studentDetails.getString("student_id");
    }
}

PS: Non dimenticare che l'implementazione primitiva Lazy<T> personalizzata (come quella dietro questo collegamento ) non è thread-safe , che può essere o non essere accettabile.

PS1: Inoltre, non sono esattamente sicuro che sia una buona idea usare HttpServletRequest come parametro costruttore - si accoppia RequestParams con classi relative a http, che possono complicare leggermente la manutenzione e i test unitari e ridurre la possibilità di riutilizzo della classe.

PS2: Anche se l'approccio Lazy<T> è una soluzione generica corretta, in questo caso particolare, dove l'inizializzazione è in realtà relativamente economica, preferisco seguire il% h_file di @Frank Puffer ="https://softwareengineering.stackexchange.com/a/344430/136796"> suggerimento e inizializza completamente questa classe nel costruttore, rendendola così immutabile.

    
risposta data 18.03.2017 - 12:17
fonte