Home php教程 php手册 详细介绍优化函数的构成

详细介绍优化函数的构成

Jun 13, 2016 am 11:13 AM
extract method under introduce optimization several kinds function Discover constitute of explain detailed

下面介绍了几种优化函数

1. Extract Method (提炼函数)

解释:

如果发现一个函数的代码很长, 很可能的一种情况是这个函数做了很多事情, 找找看函数中有没有注释, 往往注释都是为了解释下面一块代码做的什么事情, 可以考虑将这块代码提炼(Extract)成一个独立的函数.

这样做的好处不言而喻, 是面向对象五大基本原则中的单一职责原则 (Single Responsibility Principle), 比较长的函数被拆分成一个个小函数, 将有利于代码被复用.

冲动前:

<ol class="dp-c">
<li class="alt"><span><span class="keyword">public</span><span> void Print(Employee employee)   </span></span></li>
<li><span>{   </span></li>
<li class="alt">
<span class="comment">//print employee's information  </span><span> </span>
</li>
<li>
<span>Console.WriteLine(</span><span class="string">"Name:"</span><span> + employee.Name);   </span>
</li>
<li class="alt">
<span>Console.WriteLine(</span><span class="string">"Sex:"</span><span> + employee.Sex);   </span>
</li>
<li>
<span>Console.WriteLine(</span><span class="string">"Age:"</span><span> + employee.Age);   </span>
</li>
<li class="alt">
<span class="comment">//print employee's salary  </span><span> </span>
</li>
<li>
<span>Console.WriteLine(</span><span class="string">"Salary:"</span><span> + employee.Salary);   </span>
</li>
<li class="alt">
<span>Console.WriteLine(</span><span class="string">"Bonus:"</span><span> + employee.Bonus);   </span>
</li>
<li><span>}  </span></li>
</ol>
Copy after login

冲动后:

<ol class="dp-c">
<li class="alt"><span><span class="keyword">public</span><span> void Print(Employee employee)   </span></span></li>
<li><span>{   </span></li>
<li class="alt">
<span class="comment">//print employee's information  </span><span> </span>
</li>
<li><span>PrintInfo(employee);   </span></li>
<li class="alt">
<span class="comment">//print employee's salary  </span><span> </span>
</li>
<li><span>PrintSalary(employee);   </span></li>
<li class="alt"><span>}   </span></li>
<li>
<span class="keyword">public</span><span> void PrintInfo(Employee employee)   </span>
</li>
<li class="alt"><span>{   </span></li>
<li>
<span>Console.WriteLine(</span><span class="string">"Name:"</span><span> + employee.Name);   </span>
</li>
<li class="alt">
<span>Console.WriteLine(</span><span class="string">"Sex:"</span><span> + employee.Sex);   </span>
</li>
<li>
<span>Console.WriteLine(</span><span class="string">"Age:"</span><span> + employee.Age);   </span>
</li>
<li class="alt"><span>}   </span></li>
<li>
<span class="keyword">public</span><span> void PrintSalary(Employee employee)   </span>
</li>
<li class="alt"><span>{   </span></li>
<li>
<span>Console.WriteLine(</span><span class="string">"Salary:"</span><span> + employee.Salary);   </span>
</li>
<li class="alt">
<span>Console.WriteLine(</span><span class="string">"Bonus:"</span><span> + employee.Bonus);   </span>
</li>
<li><span>}  </span></li>
</ol>
Copy after login

2. Inline Method (将函数内联)

解释:

有些函数很短, 只有一两行, 而且代码的意图也非常明显, 这时可以考虑将这个函数干掉, 直接使用函数中的代码.物件中过多的方法会让人感到不舒服, 干掉完全不必要的函数后代码会更简洁.

冲动前:

<ol class="dp-c">
<li class="alt"><span><span class="keyword">public</span><span> bool IsDeserving(int score)   </span></span></li>
<li><span>{   </span></li>
<li class="alt">
<span class="keyword">return</span><span> IsScoreMoreThanSixty(score);   </span>
</li>
<li><span>}   </span></li>
<li class="alt">
<span class="keyword">public</span><span> bool IsScoreMoreThanSixty(int score)   </span>
</li>
<li><span>{   </span></li>
<li class="alt">
<span class="keyword">return</span><span> (score > 60);   </span>
</li>
<li><span>}  </span></li>
</ol>
Copy after login

冲动后:

<ol class="dp-c">
<li class="alt"><span><span class="keyword">public</span><span> bool IsDeserving(int score)   </span></span></li>
<li><span>{   </span></li>
<li class="alt">
<span class="keyword">return</span><span> (score > 60) ;   </span>
</li>
<li><span>}  </span></li>
</ol>
Copy after login

3. Inline Temp (将临时变量内联)

解释:

如果有一个临时变量 (Temp)用来表示某个函数的返回值, 一般来说, 这样的做法挺好的. 但如果这个临时变量实在多余, 将这个临时变量内联之后毫不影响代码的阅读, 甚至这个临时变量妨碍了其它重构工作, 就应该将这个临时变量内联化.

把这个临时变量干掉的好处在于减少了函数的长度, 有时可以让其它重构工作更顺利的进行.

冲动前:

<ol class="dp-c">
<li class="alt"><span><span>int salary = employee.Salary;   </span></span></li>
<li>
<span class="keyword">return</span><span> (salary > 10000);  </span>
</li>
</ol>
Copy after login

冲动后:

<ol class="dp-c">
<li class="alt"><span><span class="keyword">return</span><span> (employee.Salary > 10000);   </span></span></li>
<li><span>Replace Temp With Query (用查询式代替临时变量) </span></li>
</ol>
Copy after login

解释:

程序中有一个临时变量(Temp)用来保存某个表达式的计算结果, 将这个计算表达式提炼(Extract)到一个独立的函数(即查询式Query)中, 将这个临时变量所有被调用的地方换成对新函数(Query)的调用, 新函数还可以被其它函数使用.

好处在于减少函数长度, 增加代码复用率, 有利于代码进一步的重构. 并且注意 Replace Temp With Query 往往是 Extract Method 之前必不可少的步骤, 因为局部变量会使代码不太容易被提炼, 所以在进行类似的重构前可以将它们替换成查询式.

下面的这个例子不是很有必要使用Replace Temp With Query, 主要展示如何 Replace Temp With Query. 试想"冲动前"函数中有很多个代码块都使用到 totalPrice, 突然有一天我发现这个函数太长, 我需要将这一块块的代码提炼成单独的函数, 这样就需要将 totalPrice = price * num; 放到每一个提炼出来的函数中. 而如果原来函数中使用的是查询式, 就不存在这个问题. 如果查询式中的计算量很大, 也不建议使用 Replace Temp With Query.

冲动前:

<ol class="dp-c">
<li class="alt"><span><span class="keyword">public</span><span> double FinalPrice(double price, int num)   </span></span></li>
<li><span>{   </span></li>
<li class="alt"><span>double totalPrice = price * num;   </span></li>
<li>
<span class="keyword">if</span><span> (totalPrice > 100)   </span>
</li>
<li class="alt">
<span class="keyword">return</span><span> totalPrice * 0.8;   </span>
</li>
<li>
<span class="keyword">else</span><span>   </span>
</li>
<li class="alt">
<span class="keyword">return</span><span> totalPrice * 0.9;   </span>
</li>
<li><span>}  </span></li>
</ol>
Copy after login

冲动后:

<ol class="dp-c">
<li class="alt"><span><span class="keyword">public</span><span> double FinalPrice(double price, int num)   </span></span></li>
<li><span>{   </span></li>
<li class="alt">
<span class="keyword">if</span><span> (TotalPrice(price, num) > 100)   </span>
</li>
<li>
<span class="keyword">return</span><span> TotalPrice(price, num) * 0.8;   </span>
</li>
<li class="alt">
<span class="keyword">else</span><span>   </span>
</li>
<li>
<span class="keyword">return</span><span> TotalPrice(price, num) * 0.9;   </span>
</li>
<li class="alt"><span>}   </span></li>
<li>
<span class="keyword">public</span><span> double TotalPrice(double price, int num)   </span>
</li>
<li class="alt"><span>{   </span></li>
<li>
<span class="keyword">return</span><span> price * num;   </span>
</li>
<li class="alt"><span>}  </span></li>
</ol>
Copy after login

5. Introduce Explaining Variable (引入可以理解的变量)

解释:

很多时候在条件逻辑表达式中, 很多条件令人难以理解它的意义, 为什么要满足这个条件? 不清楚. 可以使用Introduce Explaining Variable将每个条件子句提炼出来, 分别用一个恰当的临时变量名表示条件子句的意义.

好处在于增加了程序的可读性.

冲动前:

<ol class="dp-c">
<li class="alt"><span><span class="keyword">if</span><span>((operateSystem.Contains(</span><span class="string">"Windows"</span><span>))&&   (browser.Contatins(</span><span class="string">"IE"</span><span>)))     </span></span></li>
<li><span>{    </span></li>
<li class="alt">
<span> </span><span class="comment">//do something   </span><span> </span>
</li>
<li><span>} </span></li>
</ol>
Copy after login

冲动后:

<ol class="dp-c">
<li class="alt"><span><span>bool isWindowsOS = operateSystem.Contains(</span><span class="string">"Windows"</span><span>);   </span></span></li>
<li>
<span>bool isIEBrowser = browser.Contatins(</span><span class="string">"IE"</span><span>);   </span>
</li>
<li class="alt">
<span class="keyword">if</span><span> (isWindowsOS && isIEBrowser)   </span>
</li>
<li><span>{   </span></li>
<li class="alt">
<span class="comment">//do something  </span><span> </span>
</li>
<li><span>}  </span></li>
</ol>
Copy after login

6. Split Temporary Variable (撇清临时变量)

解释:

例如代码中有个临时变量在函数上面某处表示长方形周长, 在函数下面被赋予面积, 也就是这个临时变量被赋值超过一次, 且表示的不是同一种量. 应该针对每次赋值, 分配一个独立的临时变量.

一个变量只应表示一种量, 否则会令代码阅读者感到迷惑.

冲动前:

<ol class="dp-c">
<li class="alt"><span><span>double temp = (width + height) * 2;   </span></span></li>
<li>
<span class="comment">//do something  </span><span> </span>
</li>
<li class="alt"><span>temp = width * height;   </span></li>
<li>
<span class="comment">//do something </span><span> </span>
</li>
</ol>
Copy after login

冲动后:

<ol class="dp-c">
<li class="alt"><span><span>double perimeter = (width + height) * 2;   </span></span></li>
<li>
<span class="comment">//do something  </span><span> </span>
</li>
<li class="alt"><span>double area = width * height;   </span></li>
<li>
<span class="comment">//do something </span><span> </span>
</li>
</ol>
Copy after login

7. Remove Assignments to Parameters (消除对参数的赋值操作)

解释:

传入参数分"传值"和"传址"两种, 如果是"传址", 在函数中改变参数的值无可厚非, 因为我们就是想改变原来的值. 但如果是"传值", 在代码中为参数赋值, 就会令人产生疑惑. 所以在函数中应该用一个临时变量代替这个参数, 然后对这个临时变量进行其它赋值操作.

冲动前:

<ol class="dp-c">
<li class="alt"><span><span class="keyword">public</span><span> double FinalPrice(double price, int num)   </span></span></li>
<li><span>{   </span></li>
<li class="alt"><span>price = price * num;   </span></li>
<li>
<span class="comment">//other calculation with price  </span><span> </span>
</li>
<li class="alt">
<span class="keyword">return</span><span> price;   </span>
</li>
<li><span>}  </span></li>
</ol>
Copy after login

冲动后:

<ol class="dp-c">
<li class="alt"><span><span class="keyword">public</span><span> double FinalPrice(double price, int num)   </span></span></li>
<li><span>{   </span></li>
<li class="alt"><span>double finalPrice = price * num;   </span></li>
<li>
<span class="comment">//other calculation with finalPrice  </span><span> </span>
</li>
<li class="alt">
<span class="keyword">return</span><span> finalPrice;   </span>
</li>
<li><span>}  </span></li>
</ol>
Copy after login

8. Replace Method with Method Object (用函数物件代替函数)

解释:

冲动的写下一行行代码后, 突然发现这个函数变得非常大, 而且由于这个函数包含了很多局部变量, 使得无法使用 Extract Method, 这时 Replace Method with Method Object 就起到了杀手锏的效果. 做法是将这个函数放入一个单独的物件中, 函数中的临时变量就变成了这个物件里的值域 (field).

冲动前:

<ol class="dp-c">
<li class="alt"><span><span class="keyword">class</span><span> Bill   </span></span></li>
<li><span>{   </span></li>
<li class="alt">
<span class="keyword">public</span><span> double FinalPrice()   </span>
</li>
<li><span>{   </span></li>
<li class="alt"><span>double primaryPrice;   </span></li>
<li><span>double secondaryPrice;   </span></li>
<li class="alt"><span>double teriaryPrice;   </span></li>
<li>
<span class="comment">//long computation  </span><span> </span>
</li>
<li class="alt"><span>...   </span></li>
<li><span>}   </span></li>
<li class="alt"><span>}  </span></li>
</ol>
Copy after login

冲动后:

<ol class="dp-c">
<li class="alt"><span><span class="keyword">class</span><span> Bill   </span></span></li>
<li><span>{   </span></li>
<li class="alt">
<span class="keyword">public</span><span> double FinalPrice()   </span>
</li>
<li><span>{   </span></li>
<li class="alt">
<span class="keyword">return</span><span> </span><span class="keyword">new</span><span> PriceCalculator(this).compute();   </span>
</li>
<li><span>}   </span></li>
<li class="alt"><span>}   </span></li>
<li>
<span class="keyword">class</span><span> PriceCalculator   </span>
</li>
<li class="alt"><span>{   </span></li>
<li><span>double primaryPrice;   </span></li>
<li class="alt"><span>double secondaryPrice;   </span></li>
<li><span>double teriaryPrice;   </span></li>
<li class="alt">
<span class="keyword">public</span><span> PriceCalculator(Bill bill)   </span>
</li>
<li><span>{   </span></li>
<li class="alt">
<span class="comment">//initial  </span><span> </span>
</li>
<li><span>}   </span></li>
<li class="alt">
<span class="keyword">public</span><span> double compute()   </span>
</li>
<li><span>{   </span></li>
<li class="alt">
<span class="comment">//computation  </span><span> </span>
</li>
<li><span>}   </span></li>
<li class="alt"><span>}  </span></li>
</ol>
Copy after login

9. Substitute Algorithm (替换算法)

解释:

有这么一个笑话:

某跨国日化公司, 肥皂生产线存在包装时可能漏包肥皂的问题, 肯定不能把空的肥皂盒卖给顾客, 于是该公司总裁命令组成了以博士牵头的专家组对这个问题进行攻关, 该研发团队使用了世界上最高精尖的技术 (如红外探测, 激光照射等), 在花费了大量美金和半年的时间后终于完成了肥皂盒检测系统, 探测到空的肥皂盒以后, 机械手会将空盒推出去. 这一办法将肥皂盒空填率有效降低至5%以内, 问题基本解决.

而某乡镇肥皂企业也遇到类似问题, 老板命令初中毕业的流水线工头想办法解决之, 经过半天的思考, 该工头拿了一台电扇到生产线的末端对着传送带猛吹, 那些没有装填肥皂的肥皂盒由于重量轻就都被风吹下去了...

这个笑话可以很好的解释 Substitute Algorithm, 对于函数中复杂的算法, 尽量想办法将这个算法简单化, 从而达到与之前同样甚至更好的效果.

本文链接:

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Tips for dynamically creating new functions in golang functions Tips for dynamically creating new functions in golang functions Apr 25, 2024 pm 02:39 PM

Go language provides two dynamic function creation technologies: closure and reflection. closures allow access to variables within the closure scope, and reflection can create new functions using the FuncOf function. These technologies are useful in customizing HTTP routers, implementing highly customizable systems, and building pluggable components.

Considerations for parameter order in C++ function naming Considerations for parameter order in C++ function naming Apr 24, 2024 pm 04:21 PM

In C++ function naming, it is crucial to consider parameter order to improve readability, reduce errors, and facilitate refactoring. Common parameter order conventions include: action-object, object-action, semantic meaning, and standard library compliance. The optimal order depends on the purpose of the function, parameter types, potential confusion, and language conventions.

Complete collection of excel function formulas Complete collection of excel function formulas May 07, 2024 pm 12:04 PM

1. The SUM function is used to sum the numbers in a column or a group of cells, for example: =SUM(A1:J10). 2. The AVERAGE function is used to calculate the average of the numbers in a column or a group of cells, for example: =AVERAGE(A1:A10). 3. COUNT function, used to count the number of numbers or text in a column or a group of cells, for example: =COUNT(A1:A10) 4. IF function, used to make logical judgments based on specified conditions and return the corresponding result.

C++ program optimization: time complexity reduction techniques C++ program optimization: time complexity reduction techniques Jun 01, 2024 am 11:19 AM

Time complexity measures the execution time of an algorithm relative to the size of the input. Tips for reducing the time complexity of C++ programs include: choosing appropriate containers (such as vector, list) to optimize data storage and management. Utilize efficient algorithms such as quick sort to reduce computation time. Eliminate multiple operations to reduce double counting. Use conditional branches to avoid unnecessary calculations. Optimize linear search by using faster algorithms such as binary search.

How to write efficient and maintainable functions in Java? How to write efficient and maintainable functions in Java? Apr 24, 2024 am 11:33 AM

The key to writing efficient and maintainable Java functions is: keep it simple. Use meaningful naming. Handle special situations. Use appropriate visibility.

C++ Function Exception Advanced: Customized Error Handling C++ Function Exception Advanced: Customized Error Handling May 01, 2024 pm 06:39 PM

Exception handling in C++ can be enhanced through custom exception classes that provide specific error messages, contextual information, and perform custom actions based on the error type. Define an exception class inherited from std::exception to provide specific error information. Use the throw keyword to throw a custom exception. Use dynamic_cast in a try-catch block to convert the caught exception to a custom exception type. In the actual case, the open_file function throws a FileNotFoundException exception. Catching and handling the exception can provide a more specific error message.

Introduction to the online score checking platform (convenient and fast score query tool) Introduction to the online score checking platform (convenient and fast score query tool) Apr 30, 2024 pm 08:19 PM

A fast score query tool provides students and parents with more convenience. With the development of the Internet, more and more educational institutions and schools have begun to provide online score check services. To allow you to easily keep track of your child's academic progress, this article will introduce several commonly used online score checking platforms. 1. Convenience - Parents can check their children's test scores anytime and anywhere through the online score checking platform. Parents can conveniently check their children's test scores at any time by logging in to the corresponding online score checking platform on a computer or mobile phone. As long as there is an Internet connection, whether at work or when going out, parents can keep abreast of their children's learning status and provide targeted guidance and help to their children. 2. Multiple functions - in addition to score query, it also provides information such as course schedules and exam arrangements. Many online searches are available.

Detailed introduction of Samsung S24ai functions Detailed introduction of Samsung S24ai functions Jun 24, 2024 am 11:18 AM

2024 is the first year of AI mobile phones. More and more mobile phones integrate multiple AI functions. Empowered by AI smart technology, our mobile phones can be used more efficiently and conveniently. Recently, the Galaxy S24 series released at the beginning of the year has once again improved its generative AI experience. Let’s take a look at the detailed function introduction below. 1. Generative AI deeply empowers Samsung Galaxy S24 series, which is empowered by Galaxy AI and brings many intelligent applications. These functions are deeply integrated with Samsung One UI6.1, allowing users to have a convenient intelligent experience at any time, significantly improving the performance of mobile phones. Efficiency and convenience of use. The instant search function pioneered by the Galaxy S24 series is one of the highlights. Users only need to press and hold

See all articles