[供给侧]一个开源项目(xserver)18年前的一次重构

darkk
darkk体国经野 义尚光大 08月29日 字数 3343

(1) 这个项目的简要信息(参考)

=================================

维毒百科:

** Graphical User Interface **

The graphical user interface (GUI jee-you-eye or) is a form of user interface that allows users to interact with electronic devices through graphical icons and audio indicator such as primary notation, instead of text-based user interfaces, typed command labels or text navigation. GUIs were introduced in reaction to the perceived steep learning curve of command-line interfaces (CLIs), which require commands to be typed on a computer keyboard.

** X.Org Server **

X.Org Server is the free and open-source implementation of the X Window System display server stewarded by the X.Org Foundation. Implementations of the client side of the protocol are available e.g. in the form of Xlib and XCB.

简单来说, xserver 是开源业界广泛使用的一套图形用户界面解决方案,特别的,是一种广泛使用、历史悠久的基础设施级别的一个跨硬件、跨硬件体系架构、跨操作系统平台、面向不同的图形化用户应用程序的整体解决方式。

(2) 这次重构的相关代码

=========================

这里只讨论一点,即 mi/miinitext.c 中的 InitExtensions 函数的实现。

这次重构并没有改变 InitExtensions 的在C语言中的“声明”,仍然是:

void

InitExtensions(argc, argv)

int        argc;

char    *argv[];

但是他们具体的实现方式改变了。在重构之前:

https://gitlab.freedesktop.org/xorg/xserver/-/blob/9508a382f8a9f241dab097d921b6d290c1c3a776/mi/miinitext.c#L153

在重构之后:

https://gitlab.freedesktop.org/xorg/xserver/-/blob/d568221710959cf7d783e6ff0fb80fb43a231124/mi/miinitext.c#L507

具体是这样子的:

① 在重构之前, void InitExtensions(argc, argv) 的函数本体主要大概是这个样子的:

```

InitExtensions(argc, argv) {

#ifdef Extension_A_MACRO

Extension_A_Init();

#endif

#ifdef Extension_B_MACRO

Extension_B_Init();

#endif

...

}

```

这是“指令序列”(A series of Order)

② 重构之后:

重构引入了一个静态化的结构体数组 staticExtensions :

```

static ExtensionModule staticExtensions[] = {

#ifdef Extension_A_MACRO

{ Extension_A_Init_FUNPTR, "Extension_A_Named",  Extension_A_settings... },

#endif

#ifdef Extension_B_MACRO

{ Extension_B_Init_FUNPTR, "Extension_B_Named",  Extension_A_settings... },

#endif

...

}

```

并且通过迭代这个数组来具体调用 Extension_α_Init 了:

```

void

InitExtensions(argc, argv)

int        argc;

char    *argv[];

{

int i;

ExtensionModule *ext;

static Bool listInitialised = FALSE;

if (!listInitialised) {

/* Add built-in extensions to the list. */

for (i = 0; staticExtensions[i].name; i++)

LoadExtension(&staticExtensions[i], TRUE);

/* Sort the extensions according the init dependencies. */

LoaderSortExtensions();

listInitialised = TRUE;

}

for (i = 0; ExtensionModuleList[i].name != NULL; i++) {

ext = &ExtensionModuleList[i];

if (ext->initFunc != NULL &&

(ext->disablePtr == NULL ||

(ext->disablePtr != NULL && !*ext->disablePtr))) {

(ext->initFunc)();

}

}

}

```

是不是有点“多态”、“封装”的感觉?

这种实现方式实际上是通过定义一个声明式的链表,然后通过将这个链表作为数据结构,然后建立算法。

(3) 一些结论

==============

-- 这次重构将指令序列改成了声明式链表及相关函数

-- 这次重构之后代码更长了,但可读性提高了,而且函数中的“过程”被转化为了“数据结构”

我认为这个重构非常切合 xserver 这样子的软件,极大地提高了其可维护性。

堪称一次史诗级的重构!

SoftEng 软件工程