[英]Can I use a design pattern to solve this problem?
我正在根據屏幕分辨率向各種 GUI 屏幕添加行間隔。 當前,在各種 GUI 類中,調用了一個方法,該方法返回屏幕分辨率並根據屏幕分辨率添加新的間隔。 根據 class 類型,SpacerField 的值可以更改。 是否有一種設計模式可以用來重構代碼,以減少條件條件,並且更面向 object?
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);
}
}
}
像這樣的東西? 對於每個可能的間隔值,我需要添加一個新的實現,在這種情況下,我只有一個 - SpacerSmall。
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 類的對象。例如:
public interface SpacerWidthResolver {
public int getSpacerWidth(int resolution);
}
public class A implements SpacerWidthResolver {
public int getSpacerWidth(int resolution) {
int spacerWidth = -1;
switch (resolution) {
case 360: {
spacerWidth = 15;
break;
}
case 460: {
spacerWidth = 5;
break;
}
default: {
spacerWidth = -1;
break;
}
}
return spacerWidth;
}
}
public class B implements SpacerWidthResolver {
public int getSpacerWidth(int resolution) {
int spacerWidth = -1;
switch (resolution) {
case 360: {
spacerWidth = 35;
break;
}
case 460: {
spacerWidth = 15;
break;
}
default: {
spacerWidth = -1;
break;
}
}
return spacerWidth;
}
}
然后,稍后在您的 class 中,您有getScreenResolution
方法:
public void DoSomething(SpacerWidthResolver component) {
add(new SpacerField(component.getSpacerWidth(getScreenResolution())));
}
這可能不是最好的解決方案,但是(就 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;
}
}
您只需要一個 class。 類應該在行為而不是數據上有所不同,您甚至不應該根據不同的數據創建兩個不同的類。 這帶來了無用的 class 擴散。 可以在構造函數中提供不同的配置。
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);
}
}
這是配置,使用依賴注入框架創建這些實例並在必要時使用 setters 方法注入實例是一種很好的做法。
即使您不使用依賴注入框架,您現在也可以自己做,將來進行遷移。 方法如下:
public class AClassThatUseSpacer {
private Spacer spacer;
public void setSpacer(Spacer spacer) {
this.spacer = spacer;
}
}
當你使用它時:
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));
class A:
private static Map<Integer, Integer> spacerMap = new HashMap<Integer, Integer>() {{put(360, 15);put(460, 5);};};
...
add(new SpacerField(spacerMap.get(getScreenResolution())))
class B:
private static Map<Integer, Integer> spacerMap = new HashMap<Integer, Integer>() {{put(360, 35);put(460, 15);};};
...
add(new SpacerField(spacerMap.get(getScreenResolution())))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.