簡體   English   中英

Java接口:根據對象類型調用實現類

[英]Java interface : Calling an implementation class based on object types

我有一個接口,它的2個實現說:

public interface ObjectProcessor {
  public void process(List<String> objectNames);
}

public CarImpl implements ObjectProcessor {
@override 
public void process(List<String> carNames){
//car logic
} }

public VanImpl implements ObjectProcessor {
@override 
public void process(List<String> vanNames){
//van logic
}
}

現在使用此接口的呼叫者如下所示:

public void caller(VehicleType vehicleType, List<String> vehicleNames ) {
ObjectProcessor processor = null ;
 if (VehicleType == VehicleType.CAR) {
      processor = new CarImpl();
      processor.process(vehicleNames);
}
}

VehicleType是一個ENUM,可以正常工作。 但是無論如何我可以動態調用接口而無需
添加if語句。 將來,如果我要支持其他車輛,則需要添加if語句以及該接口的新實現。 如何避免這種情況?

像這樣在枚舉中覆蓋抽象工廠方法。

public enum VehicleType {
    Car {
        @Override
        public ObjectProcessor createImpl() {
            return new CarImpl();
        }
    },
    Van {
        @Override
        public ObjectProcessor createImpl() {
            return new VanImpl();
        }
    };
    public abstract ObjectProcessor createImpl();
}

public void caller(VehicleType vehicleType, List<String> vehicleNames ) {
    ObjectProcessor processor = vehicleType.createImpl();
    processor.process(vehicleNames);
}

VechicleType將枚舉與工廠結合在一起。

或者,您可以像這樣遍歷枚舉中的所有邏輯。

public enum VehicleType {
    Car {
        @Override
        public ObjectProcessor createImpl() {
            return new ObjectProcessor() {

                @Override
                public void process(List<String> objectNames) {
                    // car logic
                }

            };
        }
    },
    Van {
        @Override
        public ObjectProcessor createImpl() {
            return new ObjectProcessor() {

                @Override
                public void process(List<String> objectNames) {
                    // van logic
                }

            };
        }
    };
    public abstract ObjectProcessor createImpl();
}

在這種情況下,您不再需要實現類(CarImpl,VanImpl等)。

使用工廠模式。 使用它有一些好處: http : //javarevisited.blogspot.com/2011/12/factory-design-pattern-java-example.html#ixzz3ueUdV947

1)工廠方法設計模式將調用類與目標類解耦,從而導致耦合性和內聚性較低的代碼?

2)Java中的工廠模式使子類能夠提供對象的擴展版本,因為在工廠內部創建對象比直接在客戶端中創建對象更靈活。 由於客戶端可以隨時在接口級別上工作,因此您可以增強實施並從Factory返回。

3)在Java中使用Factory設計模式的另一個好處是,由於每次使用Factory而不是在不同的客戶端使用不同的構造函數創建對象時,它都鼓勵代碼中的一致性。

4)使用Java中的Factory設計模式編寫的代碼也易於調試和故障排除,因為您擁有集中的對象創建方法,並且每個客戶端都從同一位置獲取對象

您基本上要實現的是類似於其他答案中所建議的Factory模式。 但是最后,您將必須編寫“ if”或“ switch”語句來選擇以更正枚舉值的實現(或策略)。 但是就像您自己提到的那樣,無論何時添加或刪除枚舉值,都必須擴展此選擇模式。 您可以使用如下地圖來規避此問題:

public class ProcessorSelector {

    private final Map<VehicleType, ObjectProcessor> processors;

    public ProcessorSelector(Map<VehicleType, ObjectProcessor> processors) {
        this.processors = processors;
    }

    public void process(VehicleType type, List<String> input) {
        processors.get(type).process(input);
    }
}

然后,您可以通過傳遞映射,將所有處理器實現映射到正確的枚舉值來配置ProcessorSelector(注意,我使用guava的ImmutableMap方便地構造了哈希圖:

new ProcessorSelector(ImmutableMap.of(
    VehicleType.CAR, new CarImpl(),
    VehicleType.VAN, new VanImpl());

您無需再更改ProcessorSelector,只需更改類的構造/配置即可。 實際上,您可以說我們只是在這里實施了策略模式。 這些選擇器類非常常見,如果您覺得自己經常實現它們,甚至可以使用更通用的實現,我最近在博客中對此進行了描述: https ://hansnuttin.wordpress.com/2015/12/03/functionselector /

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM