具有嵌套pojos

时间:2017-12-20 20:34:12

标签: java firebase firebase-realtime-database getter-setter

当pjo有一些原始字段而另一个字段是我创建的对象时,我应该添加firebase的setter / getter吗?

像这样的东西

class Run :
    long time
    long date
    Distance distance

class Distance :
    double distanceKm

Run将是我添加到数据库中的类。

如果我在time添加datedistancedistanceKmRun的设置者和获取者,请执行以下操作:

public double getDistanceKm(){
    return distance.getDistanceKm();
}

public void setDistanceKm(double x){
    distance.setDistanceKm(x);
}

启动应用程序时出现空指针崩溃,因为firebase首先调用这些方法而不调用setDistance(),因此距离为空并且崩溃。

如果我删除了那些getter和setter,并通过distanceKm做出getDistance().getDistanceKm()的唯一方法,那么它可以正常工作,但它会默默地输出如下的数十个警告:

W/ClassMapper: No setter/field for distanceKilometres found on class com.example.tobias.run.data.Run (fields/setters are case sensitive!)

如果有帮助,这是运行类的相关部分:

public class Run {

private Distance distance;
private long time;
private long date;
private int rating;
private long milePace;
private long kilometrePace;
private String id = null;

public Run(Distance distance, long time, long date, int rating) {
    this.distance = distance;
    this.time = time;
    this.date = date;
    this.rating = rating;
    this.kilometrePace = calculatePace(this.distance.getDistanceKm(), time);
    this.milePace = calculatePace(this.distance.getDistanceMi(), time);
}

@Deprecated
/**
 * This no-arg constructor is required and should only be used by firebase, never by a user,
 * because it will lead to the object being in an invalid state where no fields are initialized.
 */
public Run(){}

private long calculatePace(float distance, long time){
    //Period is inputted time in millis and converts it to hh:mm:ss
    Period period = new Period(time);
    float timeInSeconds = period.getHours() * 3600f + period.getMinutes() * 60f + period.getSeconds();
    float pace = timeInSeconds / distance;
    //Multiply pace by 1000 to convert it to millis from seconds.
    return (long) pace * 1000;
}


public float getDistanceKilometres(){
    return distance.getDistanceKm();
}

public float getDistanceMiles(){
    return distance.getDistanceMi();
}

public long getTime(){
    return time;
}

public long getDate(){
    return date;
}

public int getRating(){
    return rating;
}

public String getId(){ return id; }

public long getMilePace(){
    return milePace;
}

public long getKilometrePace() {
    return kilometrePace;
}

public Distance getDistance(){
    return distance;
}

public void setDistance(Distance distance){
    this.distance = distance;
    updatePace();
}

public void setTime(long time){
    this.time = time;
    updatePace();
}

public void setDate(long date){
    this.date = date;
}

public void setRating(int rating){
    this.rating = rating;
}

public void setId(String pushKey){
    id = pushKey;
}

@Deprecated
/**
 * Setter required for Firebase, should not be used by user as pace should never be set manually,
 * only computed off distance and time values, to avoid inconsistencies.
 */
public void setKilometrePace(long kmPace){
    this.kilometrePace = kmPace;
}

@Deprecated
/**
 * Setter required for Firebase, should not be used by user as pace should never be set manually,
 * only computed off distance and time values, to avoid inconsistencies.
 */
public void setMilePace(long milePace){
    this.milePace = milePace;
}

}

这是Distance类的相关部分:

public class Distance {

private float distanceKm;
private float distanceMi;

public enum Unit {
    KM("km"), MILE("mi");

    private String value;

    Unit(String value){
        this.value = value;
    }


    @Override
    public String toString() {
        return value;
    }
}

public Distance(float distance, Unit unit){
    roundNearestTenth(distance);

    if (unit == Unit.MILE){
        distanceMi = distance;
        distanceKm = mileToKm(distance);
    } else  {
        distanceKm = distance;
        distanceMi = kmToMile(distance);
    }
}

@Deprecated
/**
 * This no-arg constructor is required and should only be used by firebase, never by a user,
 * because it will lead to the object being in an invalid state where no fields are initialized.
 */
public Distance(){}

public float getDistanceKm() {
    return distanceKm;
}

public float getDistanceMi() {
    return distanceMi;
}

public void setDistanceKm(float distanceKm) {
    distanceKm = roundNearestTenth(distanceKm);
    this.distanceKm = distanceKm;
    this.distanceMi = kmToMile(distanceKm);
}

public void setDistanceMi(float distanceMi) {
    distanceMi = roundNearestTenth(distanceMi);
    this.distanceMi = distanceMi;
    this.distanceKm = mileToKm(distanceMi);
}

}

我的firebase控制台显示以下结构:

[pushKey]
    -date
    -id
    -kilometrePace
    -milePace
    -rating
    -time
    -distanceKm
    -distanceMi
    +distance
        -distanceKm
        -distanceMi

原因似乎是distanceKmdistanceMi字段重复。它们应该只在distance内还是这个预期的行为?我该怎么做才能删除那个警告呢?

谢谢(:

1 个答案:

答案 0 :(得分:1)

您的代码取决于调用setter的顺序,这并不好。你的pojo应该允许以任何顺序设置字段。正如你的建议,在Run和Distance之间重复可能不是一个好主意。作为一般规则,pojo对象应该更多地包含结构化数据,而不是依赖于对象字段状态的逻辑。