作为介绍,我想回顾
鲍勃叔叔的名言
您阅读本文的原因有两个。 第一个-您是程序员,第二个-您想成为最好的程序员。
假设您在图书馆里,正在寻找一些书籍。 如果图书馆是按类别分类的,那么您将很快找到所需的书籍。 此外,凉爽的室内设计和建筑将使您在此图书馆的住宿更加舒适。
与编写书籍一样,如果您想创建一些很棒的东西,那么您需要知道如何编写以及如何组织代码。 如果您有团队成员或其他拥有您(过时)代码的人,他们只需要查看变量名或包或类,他们将立即理解。 他们不需要在代码中说“ E ** l”,然后从头开始重新编写。
什么是清洁代码?

笔译亲爱的程序员:
当我编写此代码时,只有上帝和我知道它是如何工作的!
现在只有上帝知道这一点!
在尝试优化此例程之前,它不会导致成功(极有可能),请增加时间警告警告下一个开发人员
总花费时间:567
如您所见,仅仅完成开发还不够。 如果将来他们无法弄清楚该代码,那么它将也成为技术债。
如果团队中的每个成员都可以理解,则您的代码处于“纯”状态。 除原始作者外,任何开发人员都可以阅读和改进原始代码。 有了理解,就会出现可读性,可变性,可扩展性和可维护性。
我应该照顾这个吗?
之所以要关心代码的清洁度,是因为您向其他开发人员描述了自己的想法。 这就是为什么您应该注意代码更加优雅,简单和易读的原因。
清洁代码的迹象
- 您的代码应优雅:您的代码应使您像制作精美的音乐盒或设计精良的汽车一样微笑
- 您的代码应重点关注:每个函数,每个类,每个模块都实现一项任务,而该任务不会因周围的细节而分心和不受污染。
- 代码不包含重复项
- 成功通过所有测试
- 减少实体,方法,类等的数量
优秀的程序员与专业的程序员之间的区别在于,专业的程序员了解代码可理解性至关重要。 专业人士使用此功能来编写每个人都能理解的代码-Robert C. Martin
写出有意识的名字
选择一个好名字可能会花费很多时间,但是以后会节省更多。 变量,函数,类的名称应回答所有重要问题。 它应该告诉您它为什么存在,为什么需要它以及如何使用它。 如果名称需要注释,则名称不会显示其用途
简单的例子
类名
类和对象必须是名词,例如Custom,WikiPage,Account和AddressParser。 避免使用“经理”,“处理器”,“数据”或“信息”之类的词。 还要记住,类名不应该是动词。
方法名称
方法名称应为动词,例如postPayment,deletePage或save。 访问修饰符,谓词应按其值命名,并按JavaBean标准使用前缀get,set和set进行命名。
在继续之前,请稍事休息,购买咖啡和饼干。

好的,现在让我们继续SOLID原则。
编写遵循SOLID原则的代码
这些原则由Bob叔叔开发,SOLID是一种缩写,描述了一组旨在编写良好代码的原则。
单一责任原则(S)
这意味着每个班级应该只承担一个责任。 更改班级的理由不应超过一个。 无需仅仅因为可以做到就将所有内容添加到您的课程中。 将大班分成小班,避开上帝的班。
一个例子:
我们在onBindViewHolder内部有一个带有业务逻辑的RecyclerView.Adapter
class MyAdapter(val friendList: List<FriendListData.Friend>) : RecyclerView.Adapter<CountryAdapter.MyViewHolder>() { inner class MyViewHolder(view: View) : RecyclerView.ViewHolder(view) { var name: TextView = view.findViewById(R.id.text1) var popText: TextView = view.findViewById(R.id.text2) } override fun onBindViewHolder(holder: MyViewHolder, position: Int) { val friend = friendList[position] val status = if(friend.maritalStatus == "Married") { "Sold out" } else { "Available" } holder.name.text = friend.name holder.popText.text = friend.email holder.status.text = status } override fun getItemCount(): Int { return friendList.size } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder { val view = LayoutInflater.from(parent.context).inflate(R.layout.item_friendlist, parent, false) return MyViewHolder(view) } }
这使得RecyclerView.Adapter不完全负责,因为它在onBindViewHolder内部包含业务逻辑。 此方法仅负责将数据插入视图中。
开闭原理(O)
软件实体必须打开才能进行扩展,但必须关闭才能进行修改。 这意味着如果您正在开发A类,而您的同事将要更改该类内部的功能。 他们可以通过扩展此类而无需更改类本身来轻松地做到这一点。
一个简单的示例是RecyclerView.Adapter类。 您可以轻松地扩展它并创建具有非标准行为的自己的适配器,而无需修改RecyclerView.Adapter本身。
class FriendListAdapter(val friendList: List<FriendListData.Friend>) : RecyclerView.Adapter<CountryAdapter.MyViewHolder>() { inner class MyViewHolder(view: View) : RecyclerView.ViewHolder(view) { var name: TextView = view.findViewById(R.id.text1) var popText: TextView = view.findViewById(R.id.text2) } override fun onBindViewHolder(holder: MyViewHolder, position: Int) { val friend = friendList[position] holder.name.text = friend.name holder.popText.text = friend.email } override fun getItemCount(): Int { return friendList.size } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder { val view = LayoutInflater.from(parent.context).inflate(R.layout.item_friendlist, parent, false) return MyViewHolder(view) } }
芭芭拉·里斯克(Barbara Lisk)换人原则(L)
子类应补充父类,而不要对其进行更改。 这意味着子类必须覆盖不违反该父类功能的父方法。 例如,我们创建一个具有onClick()侦听器的类接口,然后在MyActivity中应用该侦听器,并在调用onClick()时为其提供Toast操作。
interface ClickListener { fun onClick() } class MyActivity: AppCompatActivity(), ClickListener {
接口分离原理
该原则指出,客户端不应依赖于他不使用的方法。
这意味着如果您要编写类A并向其添加另一个类B的功能,则无需在类B中重新定义所有类A。
示例:在我们的活动中,我们需要实现SearchView.OnQueryTextListener(),但是我们只需要onQuerySubmit()方法。
mSearchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener{ override fun onQueryTextSubmit(query: String?): Boolean {
我们该怎么做? 容易! 只需创建一个回调和一个扩展SearchView.OnQueryTextListener()的类
interface SearchViewQueryTextCallback { fun onQueryTextSubmit(query: String?) } class SearchViewQueryTextListener(val callback: SearchViewQueryTextCallback): SearchView.OnQueryTextListener { override fun onQueryTextSubmit(query: String?): Boolean { callback.onQueryTextSubmit(query) return true } override fun onQueryTextChange(query: String?): Boolean { return false } }
因此,我们将其添加到视图中
val listener = SearchViewQueryTextListener( object : SearchViewQueryTextCallback { override fun onQueryTextSubmit(query: String?) {
或者在Kotlin中使用扩展功能
interface SearchViewQueryTextCallback { fun onQueryTextSubmit(query: String?) } fun SearchView.setupQueryTextSubmit (callback: SearchViewQueryTextCallback) { setOnQueryTextListener(object : SearchView.OnQueryTextListener{ override fun onQueryTextSubmit(query: String?): Boolean { callback.onQueryTextSubmit(query) return true } override fun onQueryTextChange(query: String?): Boolean { return false } }) }
val listener = object : SearchViewQueryTextCallback { override fun onQueryTextSubmit(query: String?) {
依赖倒置原则
依赖抽象,不依赖特定的东西。
对Bob叔叔的依赖反转的定义包含两个概念。
上级模块不应依赖于下级模块。 两者都应与抽象联系在一起。 抽象不应依赖细节。 细节应取决于抽象。 实现复杂逻辑的高级模块应该易于重用,而无需更改低级模块。 为此,您需要输入一个抽象,将上层和下层的模块彼此分开。
这个MVP模式的简单示例。 您有一个接口对象,可以帮助您与特定的类进行通信。 含义-UI类(活动性/片段)不需要知道presenter方法的实际实现。 因此,如果您在演示者内部进行更改,则UI类不必担心这些更改。
让我们看一个例子
interface UserActionListener { fun getUserData() } class UserPresenter : UserActionListener() {
现在在活动
class UserActivity : AppCompatActivity() {
通过这种方式,我们创建了一个抽象演示者实现的接口,并且我们的视图类维护了对PresenterInterface的引用。