> 文章列表 > 有始有终的编码原则

有始有终的编码原则

有始有终的编码原则

基本情况

在程序员的修炼之道之中,说到:

这个建议能简单地应用到大多数场合。简单说就是,分配资源的函
数或对象,对释放资源应负有责任。

这其实就是我们常说的谁分配的就谁负责释放,这也是内存释放的一个原则,这一个原则,可以推而广之,就是谁分配的资源,就谁分配释放;这真是非常常用的东西,比如数据库存连接的分配与释放。

我写一个简单的例子说明这种情况,这一个例子就是单纯为了实现价格读出后,然后价格更改,再写入:

void Market::readCustomer()
{fopen_s(&m_pf, "test.txt", "r+");if (m_pf != nullptr){CUSTOMER p = {0};fscanf(m_pf, "%s %d", p.name, &p.price);printf("%s %d\\n", p.name, p.price);}
}void Market::writeCustomer()
{if (m_pf != nullptr){CUSTOMER p = { "zhangsan", m_money };fprintf(m_pf, "%s %d\\n", p.name, p.price);printf("%s %d\\n", p.name, p.price);fclose(m_pf);m_pf = nullptr;}
}void Market::updateCustomer(int money)
{this->readCustomer();m_money = money;this->writeCustomer();}

为了清楚其见,写下头文件的部分代码

typedef struct Customer
{char name[10];int price;}CUSTOMER;private:FILE* m_pf;int m_money;

上面代码updateCustomer,看着是没问题的,但发现其耦合了变量 m_pf,从函数角度来看,的确是耦合这一个变量,不是一个好事;

后来加了些需要,要求100元以上,才更改价格,程序员,可能更改成下面这个样子:

void Market::updateCustomer(int money)
{this->readCustomer();m_money = money;if(m_money > 100){this->writeCustomer();}}

运行代码,不一会,就提示打开的文件过多,原来,那些小于100的客户,只打开了文件的链接,没有关闭文件链接,与是可能更改如下:

void Market::updateCustomer(int money)
{this->readCustomer();m_money = money;if(m_money > 100){this->writeCustomer();}else{fclose(m_pf);}}

现在问题是解决了,但是出现一个变量的三处耦合,最严重的是文件的状态变得混乱。

程序员修炼这样描述这种问题:

这个问题已修复——如果不考虑新的平衡,文件现在的确关闭了。
但是,这个修复方案意味着,三个例程因为共享变量m_pf耦合
在了一起,而且对文件何时是打开状态、何时是关闭状态的跟踪开始变
得混乱。我们正掉入一个陷阱,如果继续走这条路,情况将开始迅速恶
化。这是不平衡的!

那么,如果用有始有终的原则,则更改如下:

void Market::readCustomer(FILE *pf)
{if (pf != nullptr){CUSTOMER p = {0};fscanf(pf, "%s %d", p.name, &p.price);printf("%s %d\\n", p.name, p.price);}
}void Market::writeCustomer(FILE *pf)
{if (pf != nullptr){CUSTOMER p = { "zhangsan", m_money };fprintf(pf, "%s %d\\n", p.name, p.price);printf("%s %d\\n", p.name, p.price);}
}void Market::updateCustomer(int money)
{   FILE *pf;fopen_s(&pf, "test.txt", "r+");this->readCustomer(pf);m_money = money;this->writeCustomer(pf);fclose(pf);pf = nullptr;
}

这样代码就清晰了很多:

我们修改了代码,将文件引用通过参数传进去,而不是在内部持有
引用[5]。现在,关于该文件的所有职责都在 updateCustomer例程中。
它打开文件,再(有始有终地)在返回之前关闭它。例程保持了文件使
用的平衡:打开和关闭在同一个位置,而且非常明显的是,每次对文件
的打开操作都有一个对应的关闭操作。重构还删除了一个丑陋的共享变
量。

总结

代码中时时处处都在遵守这一原则,代码才能清晰,代码才能简单。
有始有终的编码原则