2009-11-17 70 views
1

我们在此界面中使用make java.util.UUID中的大量使用在我们的项目,以确定ojbects和做他们操作,如:“类型安全”UUID?

List<UUID> searchPerson(String text); 
Person fetchPerson(UUID personUUID); 

List<UUID> searchAdress(String text); 
Person fetchAdress(UUID adressUUID); 

但现在什么都有可能发生,而且是运行时错误的根源,是开发人员意外地将一个personUUID传递给了fetchAdress方法,该方法不应该发生。

有什么办法让这种“类型安全”的帽子,他不能通过fetchAdress方法personUUID?也许有一种方法可以用泛型来做到这一点?

回答

5

好,因为所有你需要的是一个键入 UUID你可以简单地使用泛型创建一个接口。

package com.stackoverflow.q1747780; 

public interface UUIDTyped<T> 
{ 
    public UUID value(); 
} 

现在假设Person和Address的UUID是从不同的源创建您可以为每个类,实现该接口。

package com.stackoverflow.q1747780; 

import java.util.UUID; 

public class UUIDFactory 
{ 
    public static class PersonUUID implements UUIDTyped<Person>{ 

     /* (non-Javadoc) 
     * @see com.stackoverflow.q1747780.UUIDTyped#value() 
     */ 
     @Override 
     public UUID value() { 
     return UUID.randomUUID(); 
     }}; 


    public static class AddressUUID implements UUIDTyped<Address>{ 


     /* (non-Javadoc) 
     * @see com.stackoverflow.q1747780.UUIDTyped#value() 
     */ 
     @Override 
     public UUID value() { 
     return UUID.randomUUID(); 
     }}; 


    public <T> UUIDTyped<T> newUUID() { 
    return new UUIDTyped<T>() 
    {   
     /** 
     * There is no difference on how Person and Address UUIDs are generated 
     */ 
     @Override 
     public UUID value() { 
     return UUID.randomUUID(); 
     } 
    };   
    } 

    public UUIDTyped<Person> newPersonUUID(){ 
    return new PersonUUID(); 
    } 

    public UUIDTyped<Address> newAddressUUID(){ 
    return new AddressUUID(); 
    } 
} 

概念

package com.stackoverflow.q1747780; 

import junit.framework.Assert; 

import org.junit.Test; 


public class UUIDFactoryTest 
{ 
    @Test 
    public void testPersonUUID() 
    { 
     UUIDFactory uuidFactory = new UUIDFactory(); 

     UUIDTyped<Person> newUUID = uuidFactory.newPersonUUID(); 

     Assert.assertNotNull(newUUID.value()); 
    } 

    @Test 
    public void testAddressUUID() 
    { 
     UUIDFactory uuidFactory = new UUIDFactory(); 

     UUIDTyped<Address> newUUID = uuidFactory.newAddressUUID(); 

     Assert.assertNotNull(newUUID.value()); 
    } 
} 

否则证明你可以逃脱只是虚拟接口。概念

package com.stackoverflow.q1747780; 

import junit.framework.Assert; 

import org.junit.Test; 

public class UUIDFactoryTest 
{ 
    @Test 
    public void testNewUUID() 
    { 
     UUIDFactory uuidFactory = new UUIDFactory(); 

     UUIDTyped<Person> newUUID = uuidFactory.newUUID();   
     UUIDTyped<Address> addressUUID = uuidFactory.newUUID(); 

     Assert.assertNotNull(newUUID.value()); 
     Assert.assertNotNull(addressUUID.value()); 
    }  
} 

最后证明你的服务就会像

package com.stackoverflow.q1747780; 

import java.util.List; 

public interface Service<T> 
{ 
    public List< UUIDTyped<T> > search(String text); 

    public T fetch(UUIDTyped<T> uuid); 
} 

与PersonService类

package com.stackoverflow.q1747780; 

import java.util.List; 

public class PersonService implements Service<Person> 
{ 

    /* (non-Javadoc) 
    * @see com.stackoverflow.q1747780.Service#fetch(com.stackoverflow.q1747780.UUIDTyped) 
    */ 
    @Override 
    public Person fetch(UUIDTyped<Person> uuid) { 
    return null; 
    } 

    /* (non-Javadoc) 
    * @see com.stackoverflow.q1747780.Service#search(java.lang.String) 
    */ 
    @Override 
    public List< UUIDTyped<Person> > search(String text) { 
    return null; 
    } 
} 

和AddressService类

package com.stackoverflow.q1747780; 

import java.util.List; 


public class AddressService implements Service<Address> 
{ 

    /* (non-Javadoc) 
    * @see com.stackoverflow.q1747780.Service#fetch(com.stackoverflow.q1747780.UUIDTyped) 
    */ 
    @Override 
    public Address fetch(UUIDTyped<Address> uuid) { 
     // TODO Auto-generated method stub 
     return null; 
    } 

    /* (non-Javadoc) 
    * @see com.stackoverflow.q1747780.Service#search(java.lang.String) 
    */ 
    @Override 
    public List<UUIDTyped<Address>> search(String text) { 
     // TODO Auto-generated method stub 
     return null; 
    } 

} 

测试正确类型PersonService

package com.stackoverflow.q1747780; 

import java.util.List; 

import org.junit.Test; 



public class PersonServiceTest 
{ 
    @Test 
    public void testFetch() 
    { 
     UUIDFactory uuidFactory = new UUIDFactory(); 
     PersonService service = new PersonService(); 

     Person person = service.fetch(uuidFactory.newPersonUUID());   
    } 

    @Test 
    public void testSearch() 
    { 
     PersonService service = new PersonService(); 

     List< UUIDTyped<Person> > uuidList = service.search("foo");   
    } 
} 

测试正确类型AddressService

package com.stackoverflow.q1747780; 

import java.util.List; 

import org.junit.Test; 

public class AddressServiceTest 
{ 
    @Test 
    public void testFetch() 
    { 
     UUIDFactory uuidFactory = new UUIDFactory(); 
     AddressService service = new AddressService(); 

     Address address = service.fetch(uuidFactory.newAddressUUID());   
    } 

    @Test 
    public void testSearch() 
    { 
     AddressService service = new AddressService(); 

     List< UUIDTyped<Address> > uuidList = service.search("foo");   
    } 
} 
9

通过编写构建一个包含UUID功能的类,然后为每个需要的UUID的“类型”进行子类化。

如果您不需要/需要您的子类中的完整UUID API,那么您可能会特别懒,只需将其包装即可。事情是这样的:

public class MyUUID { 
    private UUID uuid; 
    public MyUUID() { 
     uuid = UUID.randomUUID(); 
    } 

    public UUID getUUID() { 
     return uuid; 
    } 
} 

public class PersonUUID extends MyUUID { } 
public class AddressUUID extends MyUUID { } 

如果手动展开来获得UUID对象惹恼了你,只是落实MyUUID全UUID API和委托每次调用的uuid成员。

2

据我所知,没有真正的方法来使用'类型安全的'UUID。有一件事要尝试创建一个空的人物对象并设置其UUID值。所以,你的签名可能是这样的:

Person fetchAdress(Person personWithOnlyUUIDSet); 

的取机制将负责填充与数据存储正确的值传送来的Person对象。

+0

我第二此选项。 +1 – 2009-11-17 10:51:45