本文主要是介绍代码重构 —— 化繁为简,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
本文涉及 KISS原则,DRY原则
1 设计层面
1.1 保持架构的一致性,不要另辟新径
比如渲染场景管理中,最扁平的架构:manager / scener / object 三层。
- 都是1对N的关系
- 一个mgr管理一群scener,一个scener下面N个object,
一些新手会把object搞成一个,在object下面搞一层 layer,最终object的含义非常不同了,
让我也“眼前一亮”,居然还能这么扩展
1.2 coding的时候,多想一步,不要无脑的直接干
比如类或者结构体,业务A一个struct,业务B一个struct。
好处:物理隔离 没有风险,不会出错,
坏处:代码碰撞,结构体膨胀,
不够简洁,同时触犯了DRY,do not repeat yourself,
2 实战
拿RHI模块来说。见过撇足的设计,耦合了大量的业务类。RHI定义了一层shader,业务模块中又大量的派生,定义出来
XXXShader : public RHI::shader {}
YYYShader : public RHI::shader {}
不止shader,program,renderer都是配套的,无谓的封装导致结构体膨胀,代码大量冗余。一个业务3个类,N个业务 3*N的增长。
如何解决呢?
结构体本质是不同类型的集合,采用反射的形式进行抽象和提炼。
1)函数的形式:
setUniform1f("key", v1f)
setUniform4f("key", v4f)
setUniformMat44("mvp", mat)
2)静态存储的形式
map< std::key, std::any> ,类似lua的metatable,
any在c++17之后采用,自己网上找一个就行。
3 推广
同样的道理,JNI的交互也经常遇到这类问题。
不好的设计,Java中的一个类,为了对应c++的一个类,硬生生的在JNI层又搞了一个类JXXX 类管理反射相关的信息。
class GuideAreaLayerConfig
{
public:std::string day_tex;std::string night_tex;float erase_dis;
}class JGuideAreaLayerConfig {
public:static jobject ToJavaObject(JNIEnv* env, const GuideAreaLayerConfig& layer_config);static GuideAreaLayerConfig Parse(JNIEnv* env, jobject obj);static void RegisterMe(JNIEnv* env);
public:static jclass clazz;static jfieldID textureDay;static jfieldID textureNight;static jfieldID eraseDis;
};
class GuideAreaLayerConfig extends LayerBaseConfig {public GuideAreaLayerConfig() {}public float eraseDis = 3;public String textureDay = "";public String textureNight = "";
}
也可以利用反射的形式,采用map进行抽象管理,大幅度压缩代码。JNI的类型setter和getter 自有一套。
这篇关于代码重构 —— 化繁为简的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!