简体   繁体   中英

Is there a design pattern for methods that differ in structure, but do similar things?

Currently I'm working using OpenGLES 2.0 in Android, and I'm struggling to develop a flexible programming architecture to dynamically handle different shaders and different objects.

As an example, I have two classes: SimpleShader and ImageShader .

To draw a SimpleShader , it needs to have an array of vertices specified:

SimpleShader s = new SimpleShader;
s.draw(final FloatBuffer pFloatBuffer);

Similarly, for an ImageShader , it needs both a set of points and a texture to draw:

ImageShader i = new ImageShader;
i.draw(final FloatBuffer pFloatBuffer, final Texture pTexture);

My question is this; SimpleShader and ImageShader are both types of Shader . I'm looking for some kind of design pattern which would allow me to use an abstract draw() method. Can anyone make any recommendations? I'd imagine it has something to do with objects to draw inheriting a Shader -specific drawing interface?

First you will need a wrapper class as parameter. Such as:

public class ShaderParameter{
    public FloatBuffer PFloatBuffer;
}

Make it constructor injected if PFloatBuffer is required (mandatory).

Then again you can create a base class for drawing. Such as:

public abstract class Shader{
    public void Draw(ShaderParameter param);
}

Then you can inherit those class to meet your needs:

public class ImageShaderParameter extends ShaderParameter{
    public Texture PTexture;
}

public class ImageShaderWrapper extends Shader{
    public override void Draw(ShaderParameter param){
        ImageShaderParameter parameter = (ImageShaderParameter)param;
        ImageShader i = new ImageShader;
        i.draw(parameter.PFloatBuffer, parameter.PTexture);
    }
}

This can be enhanced more using generics to avoid parameter casting and strategy pattern. However that explanation is too long and suitable for other question.

(The code may be based by C# since my experience is more with C#)

You could try the Strategy pattern.

It focusses on different behaviour between entities. So you could have an abstract class "Shader", which has a specific draw-behaviour.

You could set the Texture as a property on the Shader and have a single-argument draw if that is applicable to your abstraction. Or you could generalize the Texture argument so that it becomes sensible to always pass it as a second argument to any Shader. Ie maybe it should extend a Paint interface like in java.awt. Or it could be part of a DrawContext with more properties, so you would always pass a DrawContext as a second argument to the draw method. Thirdly, you could look at java.awt.Graphics2D, which is like a DrawContext that also encapsulates the drawing target/surface. It would be the only argument to your draw method.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM