2016-09-18 3 views
1

이것은 내 처음 게시하지만 문제가 많이 발생합니다. 나는 현재 헤더와 함께 AbstractDevice 클래스가 있습니다 :자바 초록, Generics 및 빌더

public abstract class AbstractDevice<T extends AbstractDevice.Builder<T>> implements Device 

이 클래스는 헤더와 중첩 된 빌더 클래스가 있습니다

:

public static abstract class Builder<T> 

가 나는 또한 헤더와 AbstractPeripheral 클래스가를

public abstract class AbstractPeripheral<T extends AbstractPeripheral.Builder<T>> extends AbstractDevice<AbstractPeripheral.Builder> 

이 클래스에는 헤더가있는 자체 중첩 된 빌더 클래스가 있습니다.

public static abstract class Builder<T> extends AbstractDevice.Builder<Builder>. 

제 목표는 AbstractPeripheral이 AbstractDevice를 확장하고 AbstractPeripheral의 빌더가 AbstractDevice를 확장하는 것입니다. 컴파일 할 때 그러나, 나는이 오류가 무엇입니까 :

유형 인수 uxb.AbstractPeripheral.Builder가 어떤 도움에 감사드립니다 타입 변수 T.

의 범위 내에 있지 않습니다. 감사합니다 추상 장치 :

package uxb; 

import java.util.List; 
import java.util.Optional; 
import java.util.ArrayList; 
import java.math.BigInteger; 


public abstract class AbstractDevice<T extends AbstractDevice.Builder<T>>  
implements Device{ 

public static abstract class Builder<T>{ 

private Integer version; 

private Optional<Integer> productCode; 

private Optional<BigInteger> serialNumber; 

private List<Connector.Type> connectors; 

public Builder(Integer version){ 
    this.version = version; 
} //end constructor method 


public T productCode(Integer productCode){ 
    if(productCode != null){ 
    this.productCode = Optional.of(productCode); 
    } //end if statement 
    else{ 
    this.productCode = Optional.empty(); 
    } //end else statement 
    return getThis(); 
} //end method productCode() 

public T serialNumber(BigInteger serialNumber){ 
    if(serialNumber != null){ 
    this.serialNumber = Optional.of(serialNumber); 
    } //end if statement 
    else{ 
    /*Class has a static field for ZERO value*/ 
    this.serialNumber = Optional.empty(); 
    } //end else statement 
    return getThis(); 
} //end method serialNumber() 


public T connectors(List<Connector.Type> connectors){ 
this.connectors = connectors; 
return getThis(); 
} //end method connectors 


protected abstract T getThis(); 


protected List<Connector.Type> getConnectors(){ 
    return connectors; 
} //end method getConnectors() 


protected void validate(){ 
    if(version == null){ 
    throw new NullPointerException("Cannot be validated"); 
    } 
} //end method validate() 

} //end nested abstract class Builder 


private final Integer version; 

private final Optional<Integer> productCode; 


private final Optional<BigInteger> serialNumber; 

private final List<Connector.Type> connectors; 

private final List<Connector> connectorObjects; 


protected AbstractDevice(Builder<T> builder){ 
    this.version = builder.version; 
    this.productCode = builder.productCode; 
    this.serialNumber = builder.serialNumber; 
    this.connectors = builder.connectors; 
    ArrayList<Connector> temp = new ArrayList<Connector>(); 
    for(int i = 0; i < connectors.size(); i++){ 
    temp.add(new Connector(this, i, connectors.get(i))); 
    } //end for loop 
    connectorObjects = temp; 
} //end constructor method 



public Optional<Integer> getProductCode(){ 
return productCode; 
} //end method getProductCode() 


public Integer getConnectorCount(){ 
/*Not Implemented Yet*/ 
return 0; 
} //end method getConnectorCount() 



public Optional<BigInteger> getSerialNumber(){ 
return serialNumber; 
} //end method getSerialNumber() 


public Integer getVersion(){ 
return version; 
} //end method getVersion() 

public List<Connector> getConnectors(){ 
return new ArrayList<Connector>(connectorObjects); 
} //end method getConnectors() 


public Connector getConnector(int index){ 
    if(! getConnectors().isEmpty()){ 
    return getConnectors().get(index); 
} //end if statement 
else{ 
    return null; 
} //end else statement 
} //end method getConnector() 

} //end abstract class AbstractDevice 

추상 주변 : 패키지 uxb;

import java.util.List; 

public abstract class AbstractPeripheral<T extends 
AbstractPeripheral.Builder<T>> extends 
AbstractDevice<AbstractPeripheral.Builder>{ 

public static abstract class Builder<T> extends 
AbstractDevice.Builder<Builder>{ 

protected void validate(){ 
    super.validate(); 
    if(getConnectors().equals(null)){ 
    throw new IllegalStateException("Cannot be validated"); 
    } //end if statement 
    if(checkTypes(getConnectors())){ 
    throw new IllegalStateException("Cannot be validated"); 
    } //end if statement 
} //end method 

private boolean checkTypes(List<Connector.Type> types){ 
    for(Connector.Type type: types){ 
    if(type != Connector.Type.PERIPHERAL){ 
     return false; 
    } //end if statement 
    } //end for each loop 
    return true; 
} //end method checkTypes 

public Builder(Integer version){ 
    super(version); 
} //end constructor method 
} //end nested class Builder 

public AbstractPeripheral(Builder<T> builder){ 
super(builder); 
} 
} //end class AbstractPeripheral 

허브 : 패키지 uxb;

public class Hub extends AbstractDevice<Hub.Builder>{ 

    public static class Builder extends AbstractDevice.Builder<Builder>{ 

public Builder(Integer version){ 
    super(version); 
} //end constructor method 

public Hub build(){ 
validate(); 
return new Hub(getThis()); 
} //end method build() 

protected Builder getThis(){ 
    return this; 
} //end method getThis() 

protected void validate(){ 
    super.validate(); 
    if(!(super.getConnectors().contains(Connector.Type.COMPUTER))){ 
    throw new IllegalStateException("Cannot be validated"); 
    } //end if statement\ 
    if(!(super.getConnectors().contains(Connector.Type.PERIPHERAL))){ 
    throw new IllegalStateException("Cannot be validated"); 
    } //end if statement 
} //end validate() 
} //end nested class Builder 

private Hub(Builder builder){ 
super(builder); 
} //end constructor method 

public DeviceClass getDeviceClass(){ 
return DeviceClass.HUB; 
} //end method getDeviceClass() 


} //end class Hub 
+0

실제 코드를 게시 할 수 있습니까? – nitinsh99

+0

추상적 인 오버 플로우 –

+0

가'에 대한 당신의 의도가 무엇입니까 내가 함께 생각하는' – Kelvin

답변

1

당신은 정말 빌더에 매개 변수로, 두 클래스, 빌더를 구축하고 사용해야합니다. 빌드중인 오브젝트는 이 아니지만,은 빌더에 대해 알아야 할 필요가 없으므로 매개 변수로 필요하지 않습니다.

Apache Brooklyn 및 jclouds를 비롯한 여러 오픈 소스 프로젝트에서이 패턴 또는 약간의 변형을 사용했습니다. 다음과 같이

따라서, 귀하의 예제에서, 부모 클래스를 변경 : 나는 내장 개체를 반환 할뿐만 아니라, 추상적 인 build() 방법을 추가

public abstract class AbstractDevice implements Device { 
    public static abstract class Builder<T, B> { 
     public abstract B self(); 
     public abstract T build(); 
     public B example(String value) { 
      // do something with value 
      return self(); 
     } 
    } 
} 

참고. 빌더 메소드가 this을 리턴 할 경우 잘못된 유형을 가지기 때문에 self() 메소드가 필요합니다. 대신, 각 빌더 메소드는 표시된 example(String value) 메소드의 경우와 같이 return self();으로 끝나야합니다. 그리고 아이가된다 :

public abstract class AbstractPeripheral extends AbstractDevice { 
    public static abstract class Builder<T, B> extends AbstractDevice.Builder<T, B> { 
    } 
} 

당신은 TB 일반적인 매개 변수는 클래스의 종류와 각각 빌더의 유형을 가리키는 데 사용되는 것을 볼 수 있습니다.그래서, 이들을 사용하는 구체적인 클래스를 만들기 위해이 같은 작성해야 :

public class Hub extends AbstractPeripheral { 
    public static class Builder extends AbstractPeripheral.Builder<Hub, Builder> { 
     public static final Builder builder() { 
      return new Builder(); 
     } 
     public Builder self() { 
      return this; 
     } 
     public Hub build() { 
      return new Hub(); 
     } 
    } 
} 

이것은 또한 올바른 Builder 클래스의 인스턴스를 반환하는 정적 builder() 방법을 가지고 있습니다를, 당신은 또한 직접 생성자를 호출 할 수 네가 원한다면. build() 메서드는 단순히 concrete 클래스를 만들고 반환하며 self() 메서드는 여기에을 반환하여 올바른 형식의 this을 반환합니다.

함께 최선을 다하는, 다음과 같이 우리는 Hub 개체를 만드는 데 이것을 사용할 수 있습니다 : 실제로 Hub#self()를 호출하기 때문에 AbstractDevice.Builder#example(String) 방법은 올바른 형식을 반환

Hub hub = Hub.Builder.builder() 
     .example("something") 
     .build(); 

참고하고, build()Hub의 구체적인 인스턴스를 반환 예상대로

이 문제를 해결하고 반복되는 상용구를 제거하려면 Google AutoValue 프로젝트를 사용해보세요. 지금은 jclouds로 전환 중입니다.

+0

많은 도움을 주셔서 감사합니다 !!! –

+0

타입 매개 변수는 빌드 될 클래스가 아니라 빌더로 갈 필요가 있음을 유의하십시오. – grkvlt