Swift下的如何编写漂亮的代码

Swift下的如何编写漂亮的代码_第1张图片

编写漂亮的代码作用经常被低估,初学者更是很少重视。其主要的原因在于编写漂亮的代码耗时太长,短时间看收益甚微。

何为漂亮的代码

漂亮的代码是干净的、组织良好、易升级、易于阅读,理解和定位。为了创建和维护这样的代码,笔者遵循以下八个简单的原则。

1.有编码标准

编码标准是一组编码规则。没有通用的编码标准,每个开发团队都可能有自己的书面和不成文规则。而我一般会从以下方面去考虑,有些可以参考官方文档。

  • 命名变量和命名方法,
  • 如何分组方法以及如何对类进行分组,
  • 方法顺序的安排,
  • 如何导入依赖项,
  • 如何存储数据

当你查看团队中其他开发人员的代码但无法识别是谁编写的代码时,您就知道要有良好的编码规范的重要性了。

规范的代码更容易理解。代码规范可以使你在所有正在工作的项目中保持一致。如果你是第一次查看公司的某个项目,您将知道在哪里搜索您需要的内容。从长远来看,代码规范可以为您节省大量时间 ——从查看代码到升级以前没有使用过的功能,因为您知道会发生什么。

让我们看一下命名变量和方法的一些好的和坏的例子:

// MARK: - Do
var cellEstimateHight =  152
var shouldReloadData =  false
var itemsPerPage =  10
var currentPage =  0

// MARK: - Don't
var a =  152
var b =  false
var c =  10
var p =  0
// MARK: - Do
func calculateHypotenuse(sideA: Double, sideB: Double) -> Double {
  return sqrt(sideA*sideA + sideB*sideB)
}

// MARK: - Don't
func calculate(a: Int, b: Int) -> Int {
  return sqrt(a*a + b*b)
}

对方法进行分组,相关方法的放在同个区域,方便查找。

// MARK: - Do
override func viewDidLoad() {
  super.viewDidLoad()
  self.prepareCollectionView()
  self.addLongPressGesture()
  self.continueButton.enable()
}

override func viewDidAppear(_ animated: Bool) {
  super.viewDidAppear(animated)
  self.showAlertDialogueIfNeeded()
}

private func prepareCollectionView() {
    self.collectionView.register(UINib(nibName: "PhotoCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: "PhotoCollectionViewCell")
    self.collectionView.allowsSelection = false
}
    
private func addLongPressGesture() {
   self.longPressGesture = UILongPressGestureRecognizer(target: self, action: #selector(self.handleLongGesture(gesture:)))
   self.collectionView.addGestureRecognizer(longPressGesture)
}

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
  return self.selectedAssets.count
}
    
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
  let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "PhotoCollectionViewCell", for: indexPath) as? PhotoCollectionViewCell
    
  return cell!
}

// MARK: - Don't
override func viewDidLoad() {
  super.viewDidLoad()
  self.prepareCollectionView()
  self.addLongPressGesture()
  self.continueButton.enable()
}

private func prepareCollectionView() {
    self.collectionView.register(UINib(nibName: "PhotoCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: "PhotoCollectionViewCell")
    self.collectionView.allowsSelection = false
}

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
  return self.selectedAssets.count
}
    
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
  let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "PhotoCollectionViewCell", for: indexPath) as? PhotoCollectionViewCell
    
  return cell!
}
    
private func addLongPressGesture() {
   self.longPressGesture = UILongPressGestureRecognizer(target: self, action: #selector(self.handleLongGesture(gesture:)))
   self.collectionView.addGestureRecognizer(longPressGesture)
}

override func viewDidAppear(_ animated: Bool) {
  super.viewDidAppear(animated)
  self.showAlertDialogueIfNeeded()
}

此外,在谈论代码规范时,不要忘记工作区的代码文件的组织规范。要快速定位代码,在创建项目时代码文件的存放同样需要些规范比如:创建彼此相关的文件组、为所有项目保持相同的组织。那样的话如果您处理多个项目,你同样能很快的找到所需的资源。


Swift下的如何编写漂亮的代码_第2张图片

2.使用自定义的符号

这也可以是编码标准,但我想指出一些关于这个概念的事情。

首先,您清楚地了解什么是全局,什么是当前范围的局部变量。虽然Xcode为全局变量设置了不同的颜色,但这对我来说并不是很好。使用自定义的符号时,识别它会容易得多。

另一方面,如果你有许多处理程序的代码,你必须在其中使用自定义的符号。在处理程序之外使用它也可以使代码统一。

3.使用MARK标记

// MARK 用于将方法划分为有意义且易于导航的部分。在使用和不使用短划线( - )的时候,预览方面有两种类型的标记。带有短划线( - )MARK标记的前面会有一个水平分隔符。

Swift下的如何编写漂亮的代码_第3张图片
// MARK: -

// MARK: A

// MARK: B

如上,我们可以使用// MARK: -用于大块的划分,// MARK: A这种用于子块的注释。
相较于右边的图片,左边图片的代码更易于理解,导航和查看。在我们进行代码review时。如果
没有// MARK: -或方法的代码放在错误的// MARK: -下,应该重新打回修改后提交审核。

4.常量

你的类中不应该有任何字符常量或任何其他常量。常量是没有太大价值的信息,所以你不应该注意它。而且,它们可能命名很长使得你的代码可读性下降。

您应该做的是创建一个包含常量的文件,为命名常量创建代码规范,使用MARK标记对它们进行分组,然后在类中使用它们。这样的常量的另一个好处就是你可以重用它们,如果需要改变,那么只在一个地方修改即可。

5.类的规模

根据您正在进行的项目,您应该预先确定类的规模。理想情况下,一个类不应该超过300行,不包含注释,规模小的类会更容易理解,管理和迭代。但当然会有例外。

要先把握类的规模,你必须从架构上考虑。在标准MVC中,控制器的代码要小于300行是很难的。这就是为什么你应该尝试其他类型的架构,如MVVM或Viper。在那里,控制器的代码量不会那么庞大,因为它们只负责表示逻辑。业务逻辑被转移到了其他文件中。
但是,请注意。代码可读性的优先级是高于类的规模。与此同时您的函数也应该控制行数,便于代码的阅读和理解。你应该规定一个函数的最大行数,如果函数超过你既定的最大函数行时,你应该重构它:

// MARK: - Do
override func viewDidLoad() {
  super.viewDidLoad()
  self.setupTextFields()
  self.setupTableView()
  self.bindUI()
}

private func setupTableView() {
  self.view.backgroundColor = .red
  self.tableView.dataSource = self
  self.tableView.delegate = self
  self.tableView.register(UINib(nibName: "MealTableViewCell", bundle: nil), forCellReuseIdentifier: "MealTableViewCell")
  self.tableView.separatorStyle = .none
  self.tableView.backgroundColor = .blue
  self.tableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 80, right: 0)
}

private func setupTextFields() {
  self.emailTextField.delegate = self
  self.fullNameTextField.delegate = self
  self.passwordTextField.delegate = self
  self.passwordTextField.isSecureTextEntry = true
  self.confirmPasswordTextField.delegate = self
  self.confirmPasswordTextField.isSecureTextEntry = true
  self.userRoleTextField.delegate = self
}

// MARK: - Don't
override func viewDidLoad() {
  super.viewDidLoad()
  self.emailTextField.delegate = self
  self.fullNameTextField.delegate = self
  self.passwordTextField.delegate = self
  self.passwordTextField.isSecureTextEntry = true
  self.confirmPasswordTextField.delegate = self
  self.confirmPasswordTextField.isSecureTextEntry = true
  self.userRoleTextField.delegate = self
  self.view.backgroundColor = .red
  self.tableView.dataSource = self
  self.tableView.delegate = self
  self.tableView.register(UINib(nibName: "MealTableViewCell", bundle: nil), forCellReuseIdentifier: "MealTableViewCell")
  self.tableView.separatorStyle = .none
  self.tableView.backgroundColor = .blue
  self.tableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 80, right: 0)
  self.bindUI()
}

6.创建重用组件

为获得代码量更少,更易于理解的类的另一个技巧是创建具有以下特征的可重用组件,该组件有一下特征:

  1. 它处理业务流程
  2. 它可以访问另一个组件
  3. 它相对独立于软件
  4. 它只有一个责任

7.使用设计模式

为了解决问题,我们会引入一些现存的解决方案 - 设计模式。每个模式都像一个蓝图,您可以自定义以解决代码中的特定问题,经过一些练习后,很容易理解和实现。设计模式使开发人员之间的通信更有效。资深的开发人员在参考用于解决特定问题的模式名称时,可以立即在其头脑里有个大概的一个伪代码的实现。
每个应用程序都需要一组不同的模式,但每个应用程序都应该实现常见的模式 - 委托,观察者,工厂,依赖注入。

8.代码审查

虽然代码审查的主要目的应该是在功能上,但我们还需要注意代码的可读性和组织。如果代码没有遵守这些原则,则打回重写修改提交审核。

有些工具可以帮助您进行代码审查,如:SwiftLint或Tailor等来减轻我们代码审查的工作量,因此我强烈建议您使用。

代码审查可能需要一些时间,但它们是对未来的投资。新开发人员将通过查看代码并获取有关他们的反馈来了解这些原则。此外,干净的代码将节省您几个月后回来更改功能的时间。

在审核代码时要严格审核包括自己的代码。如果代码审核的力度太轻,慢慢的代码的审核会越来越随意。你会创造一个可以犯错的氛围。如果代码存在缺陷,请不要合并代码。不然可能在合并代码后忘记解决它们。

结论

代码的功能方面是开发应用程序的重要部分。但是,要轻松维护和升级应用程序,代码必须干净,有条理,易于阅读,理解和定位,或者我们在这里称之为漂亮。

这些是我用来使代码变得美丽的原则。它肯定需要更多的时间来编写和审查,但它将在未来为您节省更多。

原文地址:Beautiful Code Principles

你可能感兴趣的:(Swift下的如何编写漂亮的代码)