I have two enums describing two UML profiles (meaning they define stereotypes that the profiles contain).
I also have two utility classes featuring nearly identical methods working on each of the profiles.
Example:
public static List<Element> getStereotypedElements(final InsertProfileHere stereo, final Package pkg) {
List<Element> extendedElements = new ArrayList<Element>();
if (isProfileApplied(pkg)) {
if (hasStereotype(stereo, pkg)) {
extendedElements.add(pkg);
}
extendedElements.addAll(getStereotypedElements(stereo, pkg.allOwnedElements()));
}
return extendedElements;
}
,where InsertProfileHere can be replaced with each of the two profile enums.
If anyone is interested, this method uses the Eclipse Modeling Framework or rather the UML2 metamodel implementation in EMF.
Anyway, I want to merge the two utility classes to avoid redundant code.
I've tried:
- a super interface for the two profiles
- didn't work because of static methods
- an abstract class for the Utility classes
- didn't work because of static methods
- encapsulating the profile enums in a class
Each didn't work for one or another reason.
Anyone got any ideas?
EDIT:
An example for another utility method:
public static boolean hasStereotype(
final InsertProfileHere stereo, final Element elem) {
for (Stereotype appliedStereo : elem.getAppliedStereotypes()) {
if (stereo == null) {
if (InsertProfileHere.contains(appliedStereo)) {
return true;
}
} else if (stereo.isEqual(appliedStereo)) {
return true;开发者_如何学Go
}
}
return false;
}
EDIT2: And for good measure part of the implementation of the profile enum
public enum Profile1 {
STEREOTYPE1 ("readable stereotype1 name"),
STEREOTYPE2 ("readable stereotype2 name"),
STEREOTYPE3 ("readable stereotype3 name"),
public static final String PROFILE_NAME = "NameOfProfile";
private final String readableName;
private Profile1(final String newName) {
readableName = newName;
}
public static Profile1 getValue(final String name) {
for (Profile1 type : Profile1.values()) {
if (type.toString().equals(name)) {
return type;
}
}
return null;
}
public static boolean contains(Stereotype stereotype) {
return (stereotype.getProfile().
getDefinition().getNsURI().contains(PROFILE_NAME));
}
Let the two enums implement a common interface, and use this interface in the (now unified) utility class. Or, better yet, move the methods from the utility class to the interface.
interface Stereotype {
public boolean hasStereotype(Package pkg);
public List<Element> getStereotypedElementes(Package pkg);
}
enum Enum1 implements Stereotype {
FOO("com.foo"), BAR("com.bar");
Enum1(String packagename) {
this.packagename=packagename;
}
private String packagename;
@Override
public boolean hasStereotype(Package pkg) {
return pkg.getName().equals(packagename);
}
@Override
public List<Element> getStereotypedElementes(Package pkg) {
...
}
}
enum Enum2 implements Stereotype {
...
}
public class Foo {
static List<Element> getStereotypedElements(final Stereotype stereo, final Package pkg) {
List<Element> extendedElements = new ArrayList<Element>();
if (isProfileApplied(pkg)) {
if (stereo.hasStereotype(pkg)) {
extendedElements.add(pkg);
}
extendedElements.addAll(stereo.getStereotypedElements(pkg.allOwnedElements()));
}
return extendedElements;
}
}
Use common interface as in example below.
import java.awt.Color;
public class EnumeInteraceTest
{
public interface ICorolsEnum
{
public Color getColor();
}
public enum Colors1 implements ICorolsEnum
{
MAGENTA(Color.MAGENTA),
PINK(Color.PINK);
private Color color;
private Colors1(Color color)
{
this.color = color;
}
@Override
public Color getColor()
{
return color;
}
}
public enum Colors2 implements ICorolsEnum
{
GREEN(Color.GREEN),
BLUE(Color.BLUE);
private Color color;
private Colors2(Color color)
{
this.color = color;
}
@Override
public Color getColor()
{
return color;
}
}
public static void main(String[] args)
{
ICorolsEnum ice1 = Colors1.MAGENTA;
System.out.println(ice1.getColor());
ICorolsEnum ice2 = Colors2.GREEN;
System.out.println(ice2.getColor());
}
}
精彩评论