Java 如何在不修改元素的情况下将数据关联到集合中的元素?

Java 如何在不修改元素的情况下将数据关联到集合中的元素?,java,design-patterns,Java,Design Patterns,通常,当我进行OpenGL编程时,我有一个网格类,如下所示: public class Mesh { // General 3D stuff List<Vector3f> vertices = new ArrayList<>(); List<Vector3f> normals = new ArrayList<>(); List<Vector2f> texCoords = new ArrayList<

通常,当我进行OpenGL编程时,我有一个网格类,如下所示:

public class Mesh {

    // General 3D stuff
    List<Vector3f> vertices = new ArrayList<>();
    List<Vector3f> normals = new ArrayList<>();
    List<Vector2f> texCoords = new ArrayList<>();

    // OpenGL-specific stuff
    protected int vertices;
    protected boolean dirty;
    protected int vertexArrayID = -1;
    protected int vertexBufferID = -1;

    ...

}
public class Mesh {

    // General 3D stuff
    List<Vector3f> vertices = new ArrayList<>();
    List<Vector3f> normals = new ArrayList<>();
    List<Vector2f> texCoords = new ArrayList<>();
}

public class GlMesh {

    // OpenGL-specific stuff
    protected int vertices;
    protected boolean dirty;
    protected int vertexArrayID = -1;
    protected int vertexBufferID = -1;
}

Map<Mesh, GlMesh> meshToGlMesh = (whatever)
public class Mesh implements GlMeshSupplier{  
    private final List<Vector3f> vertices = new ArrayList<>();
    private final List<Vector3f> normals = new ArrayList<>();
    private final List<Vector2f> texCoords = new ArrayList<>();

    private GlMesh glMesh;

    @Override
    public GlMesh getGlMesh() {
        return glMesh;
    }

    public void createGlMesh(){
        glMesh = new GlMesh();
    }    

    public List<Vector3f> getVertices() {
        return vertices;
    }

    public List<Vector3f> getNormals() {
        return normals;
    }

    public List<Vector2f> getTexCoords() {
        return texCoords;
    }

    public class GlMesh extends Mesh{
        // OpenGL-specific stuff
        protected int ivertices;
        protected boolean dirty;
        protected int vertexArrayID = -1;
        protected int vertexBufferID = -1;

        private GlMesh(){}

        @Override
        public List<Vector3f> getVertices() {
            return Mesh.this.vertices;
        }

        @Override
        public List<Vector3f> getNormals() {
            return Mesh.this.normals;
        }

        @Override
        public List<Vector2f> getTexCoords() {
            return Mesh.this.texCoords;
        }
    }

}

public interface GlMeshSupplier {
    public GlMesh getGlMesh();
}
但是,现在渲染系统必须做大量的簿记,以将网格映射到相应的GlMesh,这只是自找麻烦


有什么好方法可以解决我所缺少的问题吗?

我不是OpenGL程序员,所以我不知道这方面的所有问题,因此可能会让你误入歧途,但根据你所描述的,听起来你在寻找工厂模式

如果您的
GLMesh
对象需要像使用
Mesh
一样使用,那么它显然需要扩展
Mesh
(或者需要在
GLMesh
前面有一个facade类,使其看起来像
Mesh

同时,您编写的代码知道需要使用
GLMesh
。该代码可以将
GLMesh工厂
传递给不知道要使用
GLMesh
但知道需要使用
Mesh
的代码。它将从
MeshFactory
获取其
Mesh
实例,通常是一个名为
getInstance()
的方法,使用您期望的任何
MeshFactory
参数返回实例(你需要提前考虑-最坏的情况是,你在最后传递一个
贴图
,除了你知道任何
网格
都需要的数据之外,还有任何额外的数据)


MeshFactory
可以生成
Mesh
实例,无论您现在以何种方式进行操作。
GLMeshFactory
只需反复返回相同的实例即可(您在注释中暗示,它们的创建成本很高)工厂通常被理解为在适当的时候返回共享实例。

类似这样的情况如何:

public class Mesh {

    // General 3D stuff
    List<Vector3f> vertices = new ArrayList<>();
    List<Vector3f> normals = new ArrayList<>();
    List<Vector2f> texCoords = new ArrayList<>();

    // OpenGL-specific stuff
    protected int vertices;
    protected boolean dirty;
    protected int vertexArrayID = -1;
    protected int vertexBufferID = -1;

    ...

}
public class Mesh {

    // General 3D stuff
    List<Vector3f> vertices = new ArrayList<>();
    List<Vector3f> normals = new ArrayList<>();
    List<Vector2f> texCoords = new ArrayList<>();
}

public class GlMesh {

    // OpenGL-specific stuff
    protected int vertices;
    protected boolean dirty;
    protected int vertexArrayID = -1;
    protected int vertexBufferID = -1;
}

Map<Mesh, GlMesh> meshToGlMesh = (whatever)
public class Mesh implements GlMeshSupplier{  
    private final List<Vector3f> vertices = new ArrayList<>();
    private final List<Vector3f> normals = new ArrayList<>();
    private final List<Vector2f> texCoords = new ArrayList<>();

    private GlMesh glMesh;

    @Override
    public GlMesh getGlMesh() {
        return glMesh;
    }

    public void createGlMesh(){
        glMesh = new GlMesh();
    }    

    public List<Vector3f> getVertices() {
        return vertices;
    }

    public List<Vector3f> getNormals() {
        return normals;
    }

    public List<Vector2f> getTexCoords() {
        return texCoords;
    }

    public class GlMesh extends Mesh{
        // OpenGL-specific stuff
        protected int ivertices;
        protected boolean dirty;
        protected int vertexArrayID = -1;
        protected int vertexBufferID = -1;

        private GlMesh(){}

        @Override
        public List<Vector3f> getVertices() {
            return Mesh.this.vertices;
        }

        @Override
        public List<Vector3f> getNormals() {
            return Mesh.this.normals;
        }

        @Override
        public List<Vector2f> getTexCoords() {
            return Mesh.this.texCoords;
        }
    }

}

public interface GlMeshSupplier {
    public GlMesh getGlMesh();
}
公共类Mesh实现GlMeshSupplier{
私有最终列表顶点=新ArrayList();
私有最终列表法线=新ArrayList();
私有最终列表texCoords=newarraylist();
私人GlMesh GlMesh;
@凌驾
公共GlMesh getGlMesh(){
返回网格;
}
public void createGlMesh(){
glMesh=新glMesh();
}    
公共列表getVertices(){
返回顶点;
}
公共列表getNormals(){
回归常态;
}
公共列表getTexCoords(){
返回texCoords;
}
公共类GlMesh扩展了Mesh{
//OpenGL特有的东西
受保护的国际河流;
保护布尔脏;
受保护的整数vertexArrayID=-1;
受保护的int vertexBufferID=-1;
私有GlMesh(){}
@凌驾
公共列表getVertices(){
返回Mesh.this.vertices;
}
@凌驾
公共列表getNormals(){
返回Mesh.this.normals;
}
@凌驾
公共列表getTexCoords(){
返回Mesh.this.texCoords;
}
}
}
公共接口供应商{
公共GlMesh getGlMesh();
}
网格和GlMesh之间的替代映射:

    //class Mesh
    public Mesh(){
        this.vertices = new ArrayList<>();
        this.normals = new ArrayList<>();
        this.texCoords = new ArrayList<>();
    }

    private Mesh(List<Vector3f> vertices, List<Vector3f> normals, List<Vector2f> texCoords){
        this.vertices = vertices;
        this.normals = normals;
        this.texCoords = texCoords;
    }

    //class GlMesh
    private GlMesh(){
        super(Mesh.this.vertices, Mesh.this.normals, Mesh.this.texCoords);
    }
//类网格
公共网格(){
this.vertices=新的ArrayList();
this.normals=新的ArrayList();
this.texCoords=new ArrayList();
}
私有网格(列出顶点、列出法线、列出纹理坐标){
这个。顶点=顶点;
this.normals=法线;
this.texCoords=texCoords;
}
//类GlMesh
私有GlMesh(){
超级(Mesh.this.vertices、Mesh.this.normals、Mesh.this.texCoords);
}
您的
Mesh
GlMesh
似乎彼此紧密相关,这可以证明这样的合成是合理的。
Mesh
可以独立于其
GlMesh
创建。创建
GlMesh
后,它将映射(也是
Mesh
)到封闭
网格的属性

方法
getVertices()
getNormals()
getExcoords()
只是通过网格方法从
Mesh
及其
GlMesh
访问相同属性的示例


如果要隐藏
Mesh
中不应映射到
GlMesh
中的功能,也可以使用供应商界面(如
GlMeshSupplier
)来屏蔽
Mesh
,那么在GlMesh构造函数中传递网格如何?这不太有效。渲染器会获得一个网格列表作为输入,并且必须找到GLMesh与其中的每个元素一起使用,以避免反复创建GLMesh。然而,您的建议是反向的,它允许您轻松找到网格。有趣的方法,我一定会尝试。是的,场景图中确实不可避免地包含某种GLMesh对象,但Factory似乎是最不坏的sol对它的理解。