Java 我可以使用设计模式来解决这个问题吗?

Java 我可以使用设计模式来解决这个问题吗?,java,design-patterns,Java,Design Patterns,我将根据屏幕分辨率向各种GUI屏幕添加一个行间隔符。目前,在各种GUI类中都有对方法的调用,该方法返回屏幕分辨率,并根据屏幕分辨率添加新的间隔符。根据类类型,“间隔器”字段的值可以更改。是否有一种设计模式可以用来重构代码,从而减少条件,使其更加面向对象 Class A: if(getScreenResolution() == 360){ add(new SpacerField(15)); }

我将根据屏幕分辨率向各种GUI屏幕添加一个行间隔符。目前,在各种GUI类中都有对方法的调用,该方法返回屏幕分辨率,并根据屏幕分辨率添加新的间隔符。根据类类型,“间隔器”字段的值可以更改。是否有一种设计模式可以用来重构代码,从而减少条件,使其更加面向对象

Class A:
            if(getScreenResolution() == 360){
                add(new SpacerField(15));   
            }

            if(getScreenResolution() == 460){
                add(new SpacerField(5));    
            }


Class B:
            if(getScreenResolution() == 360){
                add(new SpacerField(35));   
            }

            if(getScreenResolution() == 460){
                add(new SpacerField(15));   
            }
可能的解决方案-

add(new SpacerUtils.getSpacerField(this));

public static SpacerUtils {
    static {
        int screenRes  = getScreenRes();
    }

    public static SpacerField getSpacerField(Object obj) {

        if(obj instanceof GuiScreen1 && screenRes == 360){
            return new SpacerField(25);
        }
        else  if(obj instanceof GuiScreen2 && screenRes == 360){
            return new SpacerField(35);
        }

    }
}
像这样的? 对于每个可能的间隔值,我需要添加一个新的实现,在本例中,我只有一个-spacesmall

Caller - 
                    Spacer spacer  = new SpacerSmall();

                    if(resolution == 360){
                    add(new SpacerField(0 , spacer.getSpacerValue()));  
                    }


Interface -                 
                    public interface Spacer {

        public int getSpacerValue();

    }

Implementation - 
    public class SpacerSmall implements Spacer{

        public int getSpacerValue() {
            return 15;
        }

    }

在第二个示例中,您正在应用。如果您所需要的一切都是将应用程序组合到模式集合中,那么您就走上了正确的道路。但是,如果您想使代码易于理解,那么最好将间隔宽度检测委托给类A和B的对象。例如:

公共接口解析程序{ 公共整数分辨率; } 公共类A实现了一个冲突解决程序{ 公共整数获取整数分辨率{ 整数间隔宽度=-1; 开关分辨率{ 案例360:{ 间隔宽度=15; 打破 } 案例460:{ 间隔宽度=5; 打破 } 默认值:{ 间隔宽度=-1; 打破 } } 返回间隔宽度; } } 公共类B实现了一个冲突解决程序{ 公共整数获取整数分辨率{ 整数间隔宽度=-1; 开关分辨率{ 案例360:{ 间隔宽度=35; 打破 } 案例460:{ 间隔宽度=15; 打破 } 默认值:{ 间隔宽度=-1; 打破 } } 返回间隔宽度; } } 然后,在稍后的课程中,您有了getScreenResolution方法:

public void DoSomethingSpacerWidthResolver组件{ 添加新的SpacerFieldcomponent.GetSpacerWidthGetScreenSolution; } 这可能不是最好的解决方案,但就OO范式而言,它比第一次和第二次尝试中建议的要好


请注意@eznme如何回答您的问题。他的想法可能更适合你的问题。

在你申请的第二个例子中。如果您所需要的一切都是将应用程序组合到模式集合中,那么您就走上了正确的道路。但是,如果您想使代码易于理解,那么最好将间隔宽度检测委托给类A和B的对象。例如:

公共接口解析程序{ 公共整数分辨率; } 公共类A实现了一个冲突解决程序{ 公共整数获取整数分辨率{ 整数间隔宽度=-1; 开关分辨率{ 案例360:{ 间隔宽度=15; 打破 } 案例460:{ 间隔宽度=5; 打破 } 默认值:{ 间隔宽度=-1; 打破 } } 返回间隔宽度; } } 公共类B实现了一个冲突解决程序{ 公共整数获取整数分辨率{ 整数间隔宽度=-1; 开关分辨率{ 案例360:{ 间隔宽度=35; 打破 } 案例460:{ 间隔宽度=15; 打破 } 默认值:{ 间隔宽度=-1; 打破 } } 返回间隔宽度; } } 然后,在稍后的课程中,您有了getScreenResolution方法:

public void DoSomethingSpacerWidthResolver组件{ 添加新的SpacerFieldcomponent.GetSpacerWidthGetScreenSolution; } 这可能不是最好的解决方案,但就OO范式而言,它比第一次和第二次尝试中建议的要好


请注意@eznme如何回答您的问题。他的想法可能更适合您的问题。

如果您想要易于扩展的东西,例如添加更多具有不同值的类,如A和B,您可以这样做:

    class Z {
            abstract int small();
            abstract int large();
            void doSomething() {
                    if(getScreenResolution() == 360){
                            add(new SpacerField(this.small()));   
                    }
                    if(getScreenResolution() == 460){
                            add(new SpacerField(this.large));    
                    }
            }
    }
    class A extends Z {
            int small() {
                    return 15;
            }
            int large() {
                    return 5;
            }
    }
    class B extends Z {
            int small() {
                    return 35;
            }
            int large() {
                    return 15;
            }
    }

如果您想要易于扩展的东西,例如添加更多具有不同值的类,如A和B,您可以这样做:

    class Z {
            abstract int small();
            abstract int large();
            void doSomething() {
                    if(getScreenResolution() == 360){
                            add(new SpacerField(this.small()));   
                    }
                    if(getScreenResolution() == 460){
                            add(new SpacerField(this.large));    
                    }
            }
    }
    class A extends Z {
            int small() {
                    return 15;
            }
            int large() {
                    return 5;
            }
    }
    class B extends Z {
            int small() {
                    return 35;
            }
            int large() {
                    return 15;
            }
    }

你只需要一节课。类应该在行为上而不是在数据上有所不同,您甚至不应该基于不同的数据创建两个不同的类。这带来了无用的类增殖。可以在构造函数中提供不同的配置

public interface Spacer {

    public SpacerField getSpacer(int resolution);

}

public class MySpacer implements Spacer {

    private Map<Integer, Integer> spacerSize;

    public MySpacer(Map spacerSize<Integer, Integer>) {
        this.spacerSize = spacerSize;
    }

    public SpacerField getSpacer(int resolution) {
        Integer size = spacerSize.get(resolution);
        if (size == null) {
            throw new IllegalArgumentException("Invalid resolution: " 
                            + resolution);
        }
        return new SpacerField(size);
    }

}
当你使用它时:

AClassThaUseSpacer anInstance = new AClassThatUseSpacer();
Map<Integer, Integer> spacerSize = new HashMap<Integer, Integer>();
spacerSize.put(360, 15);
spacerSize.put(460, 5);
anInstance.setSpacer(new MySpacer(spacerSize));

你只需要一节课。类应该在行为上有所不同,而不是在数据上,你不应该 甚至根据不同的数据创建两个不同的类。这带来了无用的类增殖。可以在构造函数中提供不同的配置

public interface Spacer {

    public SpacerField getSpacer(int resolution);

}

public class MySpacer implements Spacer {

    private Map<Integer, Integer> spacerSize;

    public MySpacer(Map spacerSize<Integer, Integer>) {
        this.spacerSize = spacerSize;
    }

    public SpacerField getSpacer(int resolution) {
        Integer size = spacerSize.get(resolution);
        if (size == null) {
            throw new IllegalArgumentException("Invalid resolution: " 
                            + resolution);
        }
        return new SpacerField(size);
    }

}
当你使用它时:

AClassThaUseSpacer anInstance = new AClassThatUseSpacer();
Map<Integer, Integer> spacerSize = new HashMap<Integer, Integer>();
spacerSize.put(360, 15);
spacerSize.put(460, 5);
anInstance.setSpacer(new MySpacer(spacerSize));

你可以用任何方法来解决这个问题。你不应该盲目地依赖设计模式来让一切都对你有利。想想你自己。让他们来做这项工作。@Vlad好的,我添加了一个可能的解决方案,你觉得怎么样?它包含很多条件,这是一种糟糕的设计模式?@user470184:首先,为了避免使用instanceof,我将它分成两个实现相同接口的类。其次,我将尝试不检查特定的分辨率,而是根据分辨率计算空间量,因此代码将更通用。我认为这个想法背后没有模式。@user470184:我会这样定义接口:public interface Spacer{public int getSpacerValueint resolution;}。因此,调用代码应该是'Spacer=new-Spacer-small;addnew SpacerField0,spacer.getSpacerValueresolution;}你可以用任何方法来解决这个问题。你不应该盲目地依赖设计模式来让一切都对你有利。想想你自己。让他们来做这项工作。@Vlad好的,我添加了一个可能的解决方案,你觉得怎么样?它包含很多条件,这是一种糟糕的设计模式?@user470184:首先,为了避免使用instanceof,我将它分成两个实现相同接口的类。其次,我将尝试不检查特定的分辨率,而是根据分辨率计算空间量,因此代码将更通用。我认为这个想法背后没有模式。@user470184:我会这样定义接口:public interface Spacer{public int getSpacerValueint resolution;}。因此,调用代码应该是'Spacer=new-Spacer-small;addnew SpacerField0,spacer.getSpacerValueresolution;}所以要访问间隔区,我可以使用-this.Spacer.getSpacergetResolution?是,或者简单地说是spacer.getspaceResolution;假设分辨率是一个保持当前分辨率的变量,那么要访问间隔区,我可以使用-this.Spacer.getSpacergetResolution?是,或者简单地说是spacer.getspaceResolution;假设分辨率是保持当前分辨率的变量。