开发者

Design pattern code for conditional code scattered across multiple classes

Some code needs to be refactored in approx 10 classes, of these classes there are conditionals scattered throughout the classes painting text onto the screen where appropriate. I want to add all this code conditional/painting code into one centralised location. Is there a design pattern appropriate for this ?

if (fontWidth == 100) {
    fontSize = large;
} else {
    fontSize = small;
}

if (fontWidth == 100) {
    graphics.drawText("100", xVal, yVal);
} else {
    xText = Utils.calculateXText(param1, param2);
    graphics.drawText("200", xVal, yVal);
}

For delegation does it mean I need to write defferent wrapper objects, one for setting the font size and one for drawing the text based on above code ?

public void paint(Graphics graphics){

    super.paint(graphics);
    Font font;


    if(ScreenDimension.getFontWidth() == 320){
        font = Font.getDefault().derive(Font.PLAIN,10,Ui.UNITS_pt);
    }
    else {
        font = Font.getDefault().derive(Font.PLAIN,12,Ui.UNITS_pt);
    }

String strScore = String.valueOf(score);
    graphics.setFont(font); 
    int pixelWidth = font.getAdvance(strScore);


    if(ScreenDimension.getFontWidth() == 320){
        graphics.drawText(strScore, (int) (this.backgroundBitmap.getWidth() * 0.50) - (pixelWidth/2), 10);
    }
    else {
        graphics.drawText(strScore, (int) (this.backgroundBitmap.getWidth() * 0.50) - (pixelWidth/2), 20);
    }

    if(ScreenDimension.getFontWidth() == 320){
        font = Font.getDefault().derive(Font.PLAIN,6,Ui.UNITS_pt);
    }
    else {
        font = Font.getDefault().derive(Font.PLAIN,8,Ui.UNITS_pt);
    }

    int namePixelWidth = font.getAdvance(judgeName);
    graphics.setFont(font);

if(ScreenDimension.getFontWidth() == 320){
    graphics.drawText(judgeName, (int) (this.backgroundBitmap.getWidth() * 0.50) - (namePixelWidth/2), this.backgroundBitmap.getHeight() - font.getHeight() - 2);
}
    else {
        graphics.drawText(judgeName, (int) (this.backgroundBitmap.getWidth() * 0.50)开发者_如何学Python - (namePixelWidth/2), this.backgroundBitmap.getHeight() - font.getHeight() - 15);
    }
}


You could use a delegate object that would inspect your 10 classes to draw the text appropriately.

You could also simply make a static helper function to execute that code (simple and easy way).

In fact it is hard to give a proper opinion without seeing more code.


You possibly want to use a Strategy pattern, defining something like

/**
 * Strategy to render some text, of two size variants, centered horizontally
 * at a specified position.
 */
public interface TextRenderer {
    public enum FontSize { LARGE, SMALL };
    public void render(String text, int x, int y, FontSize size);
}

/**
 * TextRenderer Factory that uses the ScreenDimension to determine sizes of LARGE
 * and SMALL fonts to use.
 */
public class ScreenDimensionAwareTextRendererFactory {
    public static TextRenderer getTextRenderer(Graphics gc) {
        Font baseFont = Font.getDefault();
        int fontWidth = ScreenDimension.getFontWidth();
        return fontWidth == 320
                ? new DefaultTextRenderer(gc, baseFont.derive(Font.PLAIN,10,Ui.UNITS_pt), baseFont.derive(Font.PLAIN,6,Ui.UNITS_pt))
                : new DefaultTextRenderer(gc, baseFont.derive(Font.PLAIN,12,Ui.UNITS_pt), baseFont.derive(Font.PLAIN,8,Ui.UNITS_pt));
    }
}

public class DefaultTextRenderer implements TextRenderer {
    protected Map<FontSize,Font> fontSizeMap = new HashMap<FontSize,Font>();
    protected Graphics gc;
    public DefaultTextRenderer(Graphics gc, Font largeFont, Font smallFont) {
        this.gc = gc;
        fontSizeMap.put(LARGE, largeFont);
        fontSizeMap.put(SMALL, smallFont);        
    }
    public void render(String text, int x, int y, FontSize size) {
        Font font = fontSizeMap.get(size)
        int pixelWidth = font.getAdvance(text);
        gc.setFont(font);

        // TODO: note here I'm not dealing with the vertical offsets you're using
        // which are dependent upon the font size. It would be possible, but
        // I suspect what you really ought to be doing is consistently rendering
        // text on a baseline.
        // The way you could adjust this to closer match what you appear to be doing
        // would be to have arguments to render() which indicate vertical alignment.
        // something like 
        // TextRenderer.VerticalAlignment = enum { BASELINE, TOP, BOTTOM }
        // and based on something like that you could compute here the y offset
        // based on the selected font.
        // I can't do that now because you're "magic numbers" hard coded don't explain
        // what they're trying to do
        gc.drawText(text, Math.round(x - (pixelWidth / 2)), y);
    }
}

// your example
public void paint(Graphics graphics) {
    super.paint(graphics);

    String strScore = String.valueOf(score);
    TextRenderer textRenderer = ScreenDimensionAwareTextRendererFactory.getTextRenderer(graphics);
    int middleX = Math.round(this.backgroundBitmap.getWidth() / 2);
    textRenderer.render(strScore, middleX, 10, TextRenderer.TextSize.LARGE);
    textRenderer.render(judgeName, middleX, this.backgroundBitmap.getHeight(), TextRenderer.TextSize.SMALL);
}


If the conditionals don't vary, you could use the Servant design pattern.

http://en.wikipedia.org/wiki/Design_pattern_Servant

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜