Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 删除特定示例中的代码重复_Java_Code Duplication - Fatal编程技术网

Java 删除特定示例中的代码重复

Java 删除特定示例中的代码重复,java,code-duplication,Java,Code Duplication,我有三个重复代码的方法。 前两种方法几乎完全重复。第三个有点不同,因为对于火灾,应该绘制更多的信息 我想删除这个重复的代码,并考虑使用内部类的模板方法模式。这是正确的方法还是有更好的解决方案 private void drawWaterSupplies(Graphics g) { double hScale = getWidth() / (double) groundMap.getWidth(); double vScale = getHeight() / (double) gr

我有三个重复代码的方法。 前两种方法几乎完全重复。第三个有点不同,因为对于火灾,应该绘制更多的信息

我想删除这个重复的代码,并考虑使用内部类的模板方法模式。这是正确的方法还是有更好的解决方案

private void drawWaterSupplies(Graphics g) {
    double hScale = getWidth() / (double) groundMap.getWidth();
    double vScale = getHeight() / (double) groundMap.getHeight();

    int imageOffsetX = waterSupplyImage.getWidth() / 2;
    int imageOffsetY = waterSupplyImage.getHeight() / 2;
    for (Location l : groundMap.getWaterSupplyLocations()) {
        int x = (int) (l.getX() * hScale);
        int y = (int) (l.getY() * vScale);

        g.drawImage(waterSupplyImage, x - imageOffsetX, y - imageOffsetY,
                null);
    }
}

private void drawEnergySupplies(Graphics g) {
    double hScale = getWidth() / (double) groundMap.getWidth();
    double vScale = getHeight() / (double) groundMap.getHeight();

    int imageOffsetX = energySupplyImage.getWidth() / 2;
    int imageOffsetY = energySupplyImage.getHeight() / 2;
    for (Location l : groundMap.getEnergySupplyLocations()) {
        int x = (int) (l.getX() * hScale);
        int y = (int) (l.getY() * vScale);

        g.drawImage(energySupplyImage, x - imageOffsetX, y - imageOffsetY,
                null);
    }
}

private void drawFires(Graphics g) {
    double hScale = getWidth() / (double) groundMap.getWidth();
    double vScale = getHeight() / (double) groundMap.getHeight();

    int imageOffsetX = fireImage.getWidth() / 2;
    int imageOffsetY = fireImage.getHeight() / 2;
    for (Fire fire : groundMap.getFires()) {
        Location l = fire.getLocation();
        int x = (int) (l.getX() * hScale);
        int y = (int) (l.getY() * vScale);

        g.drawImage(fireImage, x - imageOffsetX, y - imageOffsetY, null);
        // TODO: draw status bar showing state of fire below
    }
}

在我看来,您收集的对象(
Fire
WaterSupply
等)并不像它们应该的那样聪明。理想情况下,你应该能够说:

for (Fire f : groundMap.getFires()) {
   f.draw(g);
}
而且每个对象都能够定位自身(使用其位置)、调整自身大小(因为
火灾
知道将使用
火灾图像
等)并将自身绘制到提供的图形对象上

为了更进一步,我希望将
图形
对象传递给您的地图集,因此:

groundMap.drawFires(g);

其思想是,在OO中,您不应该询问对象的详细信息,然后再做出决策。相反,您应该告诉对象为您做一些事情。

我将委托给另一个方法,并为火、水和能量创建一个超类。 这个超类将包含所有公共属性。例如
getLocation()

乙二醇


首先,似乎您可以有一个通用方法来接收
图形
、一个
列表
和一个图像,以便第一个和第二个方法可以提取该列表并调用

第三种方法可以提取火灾列表,然后创建相应的
列表
。然后使用新方法

private void drawImages(Graphics g, List<Location> where, Image imageToDraw) {
...
}
private void drawImages(图形g,列表位置,图像imageToDraw){
...
}

我认为一个简单的解决方案是使用一种方法并传递图形和位置集合。

您可以使用一种方法

private void drawImageAtLocations(Graphics g, Image image, List<Location> locations) {
    double hScale = getWidth() / (double) groundMap.getWidth();
    double vScale = getHeight() / (double) groundMap.getHeight();

    int imageOffsetX = image.getWidth() / 2;
    int imageOffsetY = image.getHeight() / 2;
    for (Location l : locations) {
        int x = (int) (l.getX() * hScale);
        int y = (int) (l.getY() * vScale);

        g.drawImage(image, x - imageOffsetX, y - imageOffsetY, null);
    }
}

private void drawWaterSupplies(Graphics g) {
    drawImageAtLocations(g, waterSupplyImage, groundMap.getWaterSupplyLocations());
}
private void drawImageAtLocations(图形g、图像图像、列表位置){
double hScale=getWidth()/(double)groundMap.getWidth();
double-vScale=getHeight()/(double)groundMap.getHeight();
int-imageOffsetX=image.getWidth()/2;
int-imageOffsetY=image.getHeight()/2;
对于(位置l:位置){
intx=(int)(l.getX()*hScale);
int y=(int)(l.getY()*vScale);
g、 drawImage(image,x-imageOffsetX,y-imageOffsetY,null);
}
}
专用排水系统(图g){
drawImageAtLocations(g,waterSupplyImage,groundMap.getWaterSupplyLocations());
}
那么:

private void drawImageAtLocations(Graphics g, Image i, Collection<Location> cl) {
    double hScale = getWidth() / (double) groundMap.getWidth();
    double vScale = getHeight() / (double) groundMap.getHeight();

    int imageOffsetX = i.getWidth() / 2;
    int imageOffsetY = i.getHeight() / 2;
    for (Location l : cl) {
        int x = (int) (l.getX() * hScale);
        int y = (int) (l.getY() * vScale);

        g.drawImage(i, x - imageOffsetX, y - imageOffsetY, null);
    }
}
第三个有点混乱,但仍然比原来的要短:

Set<Location> derp = new HashSet<Location>();
for (Fire fire : groundMap.getFires()) derp.add(fire.getLocation());
drawImageAtLocations(g, fireImage, derp);
// drawImageAtLocations(g, fireStatusBarImage, derp); // TODO blah blah
Set derp=new HashSet();
对于(Fire-Fire:groundMap.getFires())derp.add(Fire.getLocation());
drawImageAtLocations(g、fireImage、derp);
//drawImageAtLocations(g、fireStatusBarImage、derp);//托多废话

这就是我的主张

enum  Supplies {FIRE(fireImage), WATER(waterImage), ENERGY(energyImage); 
private Bitmap image;
Supplies(Bitmap image)
 {
  this.image = image
 }

 public getImage()
 {
  return image;
 }

} 

private void draw(Graphics g,Supplies supply) {
    double hScale = getWidth() / (double) groundMap.getWidth();
    double vScale = getHeight() / (double) groundMap.getHeight();

    int imageOffsetX = supply.getImage.getWidth() / 2;
    int imageOffsetY = supply.getImage.getHeight() / 2;
    for (Location location : groundMap.getLocations(supply)) {

        int x = (int) (location .getX() * hScale);
        int y = (int) (location .getY() * vScale);

        g.drawImage(supply.getImage, x - imageOffsetX, y - imageOffsetY, null);
    }
}
。。。。 你们可以在地图>(Map>)中保存火、水、能源等的所有位置,所以方法getLocations(supply)或多或少是这样的

List<Location> getLocations(Supplies supply)
{
return supplyMap.get(supply);
}
列出地点(供应品)
{
返回supplyMap.get(supply);
}

如果您想添加或删除供应品和事故,此解决方案为您提供了更大的灵活性

这不是最短的选择,但它使代码更干净,更易于扩展:

enum YourEnum {
    WATER,
    ENERGY,
    FIRE;
}

private void draw(Graphics g, YourEnum type) {
    Bitmap bitmap = getRightBitmap(type);
    double hScale = getWidth() / (double)groundMap.getWidth();
    double vScale = getHeight() / (double)groundMap.getHeight();

    int imageOffsetX = bitmap.getWidth() / 2;
    int imageOffsetY = bitmap.getHeight() / 2;
    for (Location l : getLocations(type)) {
        int x = (int)(l.getX() * hScale);
        int y = (int)(l.getY() * vScale);

        g.drawImage(bitmap, x - imageOffsetX, y - imageOffsetY,
                null);
    }
}



private Bitmap getRightBitmap(YourEnum type) {
    switch (type) {
        case WATER:
            return waterSupplyImage;
        case ENERGY:
            return waterSupplyImage;
        case FIRE:
            return fireImage;
    }
}

private Collection<Location> getLocations(YourEnum type) {
    switch (type) {
        case WATER:
            return groundMap.getWaterSupplyLocations();
        case ENERGY:
            return groundMap.getEnergySupCollections();
        case FIRE:
            Collection<Location> locations = new ArrayList<Location>();
            for (Fire fire : groundMap.getFires()) {
                locations.add(fire.getLocation());
            }
            return locations;
    }
}
enum YourEnum{
水,,
能量
火;
}
私有void draw(图形g,YourEnum类型){
位图位图=getRightBitmap(类型);
double hScale=getWidth()/(double)groundMap.getWidth();
double-vScale=getHeight()/(double)groundMap.getHeight();
int imageOffsetX=bitmap.getWidth()/2;
int-imageOffsetY=bitmap.getHeight()/2;
对于(位置l:getLocations(类型)){
intx=(int)(l.getX()*hScale);
int y=(int)(l.getY()*vScale);
g、 drawImage(位图,x-imageOffsetX,y-imageOffsetX,
无效);
}
}
私有位图getRightBitmap(您的枚举类型){
开关(类型){
案例水:
返回水源图像;
案例能量:
返回水源图像;
案例火灾:
返回图像;
}
}
私有集合getLocations(YourEnum类型){
开关(类型){
案例水:
返回groundMap.getWaterSupplyLocations();
案例能量:
返回groundMap.getEnergySupCollections();
案例火灾:
集合位置=新的ArrayList();
for(Fire-Fire:groundMap.getFires()){
add(fire.getLocation());
}
返回地点;
}
}

不应该是
列表吗?我也考虑过这一点,但对于火灾,应该绘制更多其他位置不可用的信息。抱歉,如果这不清楚,我编辑了我的问题。看起来不错。但这不违反了模型和表示的分离吗?@kobo-有趣的一点。为了完全实现这种分离,我想你必须研究双重分派/访问者模式,比如Fire对象(比如)和图形目的地在它们之间进行调解,以确定它们需要实现什么drawingokay,我试图弄清楚这是如何工作的。我会有一个带有方法的访问者界面:
visit(firef)
visit(WaterSupply w)
。。。然后,对于绘图,我将有一个
新的DrawingVisitor(Graphics g)
,它实现了访问者界面来绘制对象。这就是你刚才说的吗?
enum  Supplies {FIRE(fireImage), WATER(waterImage), ENERGY(energyImage); 
private Bitmap image;
Supplies(Bitmap image)
 {
  this.image = image
 }

 public getImage()
 {
  return image;
 }

} 

private void draw(Graphics g,Supplies supply) {
    double hScale = getWidth() / (double) groundMap.getWidth();
    double vScale = getHeight() / (double) groundMap.getHeight();

    int imageOffsetX = supply.getImage.getWidth() / 2;
    int imageOffsetY = supply.getImage.getHeight() / 2;
    for (Location location : groundMap.getLocations(supply)) {

        int x = (int) (location .getX() * hScale);
        int y = (int) (location .getY() * vScale);

        g.drawImage(supply.getImage, x - imageOffsetX, y - imageOffsetY, null);
    }
}
List<Location> getLocations(Supplies supply)
{
return supplyMap.get(supply);
}
enum YourEnum {
    WATER,
    ENERGY,
    FIRE;
}

private void draw(Graphics g, YourEnum type) {
    Bitmap bitmap = getRightBitmap(type);
    double hScale = getWidth() / (double)groundMap.getWidth();
    double vScale = getHeight() / (double)groundMap.getHeight();

    int imageOffsetX = bitmap.getWidth() / 2;
    int imageOffsetY = bitmap.getHeight() / 2;
    for (Location l : getLocations(type)) {
        int x = (int)(l.getX() * hScale);
        int y = (int)(l.getY() * vScale);

        g.drawImage(bitmap, x - imageOffsetX, y - imageOffsetY,
                null);
    }
}



private Bitmap getRightBitmap(YourEnum type) {
    switch (type) {
        case WATER:
            return waterSupplyImage;
        case ENERGY:
            return waterSupplyImage;
        case FIRE:
            return fireImage;
    }
}

private Collection<Location> getLocations(YourEnum type) {
    switch (type) {
        case WATER:
            return groundMap.getWaterSupplyLocations();
        case ENERGY:
            return groundMap.getEnergySupCollections();
        case FIRE:
            Collection<Location> locations = new ArrayList<Location>();
            for (Fire fire : groundMap.getFires()) {
                locations.add(fire.getLocation());
            }
            return locations;
    }
}