I choose to create another texture2d class just to be more structured. At graphics initialization, a pointer to d3d device is copied in initialize() method where gl implementation leaves it blank. At load time, texture data and sampler handle will be set in material ctor. At run time, texture is applied in setting material uniform function in material class by calling Texture2D::SetMaterial(size_t unit) where unit is unused by d3d implementation. Material class stores vector of textures of current material.
The following two figures are separately my d3d and gl screenshot:
Here's my executable