Swift中的声明式编程

最近,一系列文章—在Swift中构建声明性动画框架引起了我的注意。 John指出了在iOS中实现动画的问题,这是我们在动画中添加的步骤越多,代码就变得越复杂和难读。 因此,他创建了一种声明性的方式来处理动画,这确实使我们的代码更加简洁易读。 如果您还没有阅读那些文章,我强烈建议您访问它。

为什么要进行声明式编程

作为开发人员,我们不仅致力于实现可行的功能,而且还尝试增加代码的维护性。 为了保持代码的健壮性,至关重要的是在编程过程中保持高水平的表现力。 据说声明式编程可用于实现我们的目标,因为它的基本概念之一是描述开发人员的意图。 此外,如果我们以声明性的方式编写代码,那么我们将获得真正的关注点分离,因此将带来可测试性。 总体而言,声明式编程是一个有用的想法,值得一试。

实作

在本文中,我想演示一个声明式编程的简单示例,该示例可以在UIView实例中创建不同的形状。 此外,我利用CAShapeLayer的优势来实现矩形,椭圆形,三角形和直线等形状。

首先,让我们集中精力创建矩形并编写CAShapeLayer的扩展,如下所示。

extension CAShapeLayer { 
static func rectangle(roundedRect: CGRect, cornorRadius: CGFloat, color: UIColor) -> CAShapeLayer {
let path = UIBezierPath(roundedRect: roundedRect, cornerRadius: cornorRadius)
let shape = CAShapeLayer()
shape.path = path.cgPath
shape.fillColor = color.cgColor
  return shape 
}
}

其次,为了在UIView实例中显示矩形,有必要编写UIView的另一个扩展。

 extension UIView { 
func draw(_ shapes: CAShapeLayer...) {
for shape in shapes {
layer.addSublayer(shape)
}
}
}

上面的draw方法采用可变数量的参数而不是数组。 因此,编译器可以根据参数自动构造一个数组,从而使我们的语法更加简洁。

然后,让我们将它们放在一起并查看结果。

 let containFrame = CGRect(x: 0, y: 0, width: 500, height: 500) 
let containView = UIView(frame: containFrame)
containView.backgroundColor = .white
 let roundedRect = containFrame.insetBy(dx: 100, dy: 100) 
containView.draw(
.rectangle(roundedRect: roundedRect, cornorRadius: 16, color: .red)
)

现在,我们可以创建具有相同图案的椭圆形,三角形和直线。 将以下代码添加到CAShapeLayer扩展名中。

 extension CAShapeLayer { 
// ...
  static func oval(in rect: CGRect, color: UIColor) -> CAShapeLayer { 
let path = UIBezierPath(ovalIn: rect)
let shape = CAShapeLayer()
shape.path = path.cgPath
shape.fillColor = color.cgColor
  return shape 
}
  static func triangle(_ point1: CGPoint, _ point2: CGPoint, _ point3: CGPoint, color: UIColor) -> CAShapeLayer { 
let path = UIBezierPath()
path.move(to: point1)
path.addLine(to: point2)
path.addLine(to: point3)
path.close()
  let shape = CAShapeLayer() 
shape.path = path.cgPath
shape.fillColor = color.cgColor
  return shape 
}
  static func line(start: CGPoint, end: CGPoint, width: CGFloat, color: UIColor) -> CAShapeLayer { 
let path = UIBezierPath()
path.move(to: start)
path.addLine(to: end)
  let shape = CAShapeLayer() 
shape.path = path.cgPath
shape.lineWidth = width
shape.strokeColor = color.cgColor
  return shape 
}
}

最后,绘图代码将如下所示。

 // ... 
 containView.draw( 
.rectangle(roundedRect: roundedRect, cornorRadius: 16, color: .red),
.oval(in: roundedRect.insetBy(dx: 20, dy: 30), color: .blue),
.triangle(CGPoint(x: 10, y: 10), CGPoint(x: 10, y: 150), CGPoint(x: 150, y: 10), color: .brown),
.line(start: CGPoint(x: 480, y: 10), end: CGPoint(x: 480, y: 300), width: 6, color: .green)
)

结论

这确实是一个幼稚的例子,但是我希望它可以提供声明式编程的味道。

随着Swift的不断发展,越来越多的新功能可以帮助描述编程过程中开发人员的意图。 因此,在Swift中采用声明式编程将更加直接。 不用说,使用这种方法对我们的代码库以及我们的生产力都有巨大的影响。 因此,下次尝试以声明方式思考问题!

欢迎任何评论和反馈,请分享您的想法。 谢谢!