Moin,
wie in einem anderen Thread (Konzept gesucht: Elternklasse erweitern) angedeutet habe ich ein bisschen mit dem Decorator Pattern gespielt.
Der Ansatz war es, ein bestimmtes Objekt zu erweitern ohne es subclassen zu müssen.
Im Endeffekt stelle ich fest, dass es vermutlich sinnvoller gewesen wäre, den Decorator gegen eine abstrakte Klasse oder ein Interface zu erstellen. Schließlich werde ich nur eine android.location.Location bekommen. Nichts desto trotz hoffe ich, dass der Ansatz klar wird.
Er besteht aus zwei Komponenten: dem Interface des Decorators und einer konkreten Implementierung.
// LocationStringDecorator.java
public interface LocationStringDecorator {
public String locationString();
public double getLatitude();
public double getLongitude();
}
// LocationDecorator.java
import android.location.Location;
import java.security.InvalidParameterException;
public class LocationDecorator implements LocationStringDecorator {
private Location decoratedLocation;
public LocationDecorator(Location locationToDecorate) throws InvalidParameterException {
if(locationToDecorate == null) {
throw new InvalidParameterException("The given location must not be null in order to get a working decorator!");
}
decoratedLocation = locationToDecorate;
}
@Override
public double getLatitude() {
return decoratedLocation.getLatitude();
}
@Override
public double getLongitude() {
return decoratedLocation.getLongitude();
}
@Override
public String locationString() {
String resultString = stringForDegreeAsLatitude(getLatitude(), true);
resultString += "; ";
resultString += stringForDegreeAsLatitude(getLongitude(), false);
return resultString;
}
private String stringForDegreeAsLatitude(double locationDegree, boolean isLatitude) {
if(!isDegreeValidAsLatitude(locationDegree, isLatitude)) {
return "Degree "+locationDegree+" is invalid!";
}
String resultString = orientationStringForDegreeAsLatitude(locationDegree, isLatitude);
// We need to calculate with positive numbers so we'll need the absolute value first.
locationDegree = Math.abs(locationDegree);
double degree = Math.floor(locationDegree);
resultString += (int)degree+"° ";
double x = (locationDegree - degree) * 60.0;
double minute = Math.floor(x);
resultString += (int)minute+"' ";
double second = Math.floor((x - minute) * 60.0);
resultString += (int)second+'"';
return resultString;
}
private boolean isDegreeValidAsLatitude(double degree, boolean isLatitude) {
if(isLatitude) {
return isLatitudeValid(degree);
}
else {
return isLongitudeValid(degree);
}
}
private boolean isLatitudeValid(double degree) {
return (degree >= -90 && degree <= 90);
}
private boolean isLongitudeValid(double degree) {
return (degree >= -180 && degree <= 180);
}
private String orientationStringForDegreeAsLatitude(double degree, boolean isLatitude) {
if(isLatitude) {
return orientationStringForLatitude(degree);
}
else {
return orientationStringForLongitude(degree);
}
}
private String orientationStringForLatitude(double latitude) {
if(latitude >= 0) {
return "N";
}
else {
return "S";
}
}
private String orientationStringForLongitude(double longitude) {
if(longitude >= 0) {
return "W";
}
else {
return "E";
}
}
}
Alles anzeigen
Das Einsatzgebiet sieht wie folgt aus: (Unit Tests scheinen unter Android Studio 0.3.6 defekt, deshalb via Activity)
import android.app.Activity;
import android.os.Bundle;
import android.location.Location;
import android.util.Log;
import LocationDecorator;
public class TestActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Location testLocation = new Location("manual");
testLocation.setLatitude(52.12525);
testLocation.setLongitude(-13.76584);
LocationDecorator decorator = new LocationDecorator(testLocation);
Log.e("INFO", decorator.locationString());
testLocation.setLatitude(110);
testLocation.setLongitude(-911);
LocationDecorator newDecorator = new LocationDecorator(testLocation);
Log.e("INFO", newDecorator.locationString());
}
}
Alles anzeigen
ZitatOutput
11-29 12:48:24.768 E/INFO﹕ N52° 7' 30"; E13° 45' 57"
11-29 12:48:24.768 E/INFO﹕ Degree 110.0 is invalid!; Degree -911.0 is invalid!