官术网_书友最值得收藏!

Applying functional programming to the ReactiveCalculator class

So, now, after trying to understand the ReactiveCalculator class from the previous chapter, we will try to optimize the code as well. Let's first take a look at the init block of the ReactiveCalculator class:

    init{ 
      nums = Pair(a,b) 
 
      subjectAdd.map({ it.first+it.second }).subscribe({println
("Add = $it")} )//1 subjectSub.map({ it.first-it.second }).subscribe({println
("Substract = $it")} ) subjectMult.map({ it.first*it.second }).subscribe
({println("Multiply = $it")} ) subjectDiv.map({ it.first/(it.second*1.0) }).subscribe
({println("Divide = $it")} ) subjectCalc.subscribe({ with(it) { calculateAddition() calculateSubstraction() calculateMultiplication() calculateDivision() } }) subjectCalc.onNext(this) }

So, now, with the knowledge of functional programming, we can easily say that the map and subscribe methods are high-order functions that take function as parameter. However, do you really think that many subject and subscriber are required? Shouldn't subscriber on the class be sufficient to accomplish the job itself? Let's try to modify and optimize the following piece of code:

    class ReactiveCalculator(a:Int, b:Int) { 
      val subjectCalc: io.reactivex.subjects.Subject
<ReactiveCalculator> =
io.reactivex.subjects.PublishSubject.create() var nums:Pair<Int,Int> = Pair(0,0) init{ nums = Pair(a,b) subjectCalc.subscribe({ with(it) { calculateAddition() calculateSubstraction() calculateMultiplication() calculateDivision() } }) subjectCalc.onNext(this) } inline fun calculateAddition():Int { val result = nums.first + nums.second println("Add = $result") return result } inline fun calculateSubstraction():Int { val result = nums.first - nums.second println("Substract = $result") return result } inline fun calculateMultiplication():Int { val result = nums.first * nums.second println("Multiply = $result") return result } inline fun calculateDivision():Double { val result = (nums.first*1.0) / (nums.second*1.0) println("Multiply = $result") return result } inline fun modifyNumbers (a:Int = nums.first, b:
Int = nums.second) { nums = Pair(a,b) subjectCalc.onNext(this) } fun handleInput(inputLine:String?) { if(!inputLine.equals("exit")) { val pattern: java.util.regex.Pattern =
java.util.regex.Pattern.compile
("([a|b])(?:\\s)?=(?:\\s)?(\\d*)"); var a: Int? = null var b: Int? = null val matcher: java.util.regex.Matcher =
pattern.matcher(inputLine) if (matcher.matches() && matcher.group(1) != null &&
matcher.group(2) != null) { if(matcher.group(1).toLowerCase().equals("a")){ a = matcher.group(2).toInt() } else if(matcher.group(1).toLowerCase().equals("b")){ b = matcher.group(2).toInt() } } when { a != null && b != null -> modifyNumbers(a, b) a != null -> modifyNumbers(a = a) b != null -> modifyNumbers(b = b) else -> println("Invalid Input") } } } }

So, we have removed all other subscriber and are doing the job with only one. And here's the output:

Initial Output with a = 15, b = 10
Add = 25
Substract = 5
Multiply = 150
Multiply = 1.5
Enter a = <number> or b = <number> in separate lines
exit to exit the program
a = 6
Add = 16
Substract = -4
Multiply = 60
Multiply = 0.6
b=4
Add = 10
Substract = 2
Multiply = 24
Multiply = 1.5
exit
  

We subscribe to the class object itself; so, whenever its variables get changed, we get notified, and we perform all the tasks right there in the subscribe method. Moreover, as we have made the functions inline, they'll also help in the optimization of performance.

主站蜘蛛池模板: 建德市| 三门峡市| 绍兴县| 徐闻县| 泗洪县| 清新县| 吐鲁番市| 平和县| 长寿区| 潞西市| 磴口县| 通化县| 城固县| 如皋市| 沭阳县| 旌德县| 威海市| 茶陵县| 宕昌县| 辽宁省| 额济纳旗| 衢州市| 哈尔滨市| 远安县| 札达县| 马关县| 绥阳县| 泾川县| 洛浦县| 曲阜市| 辽宁省| 余庆县| 兴国县| 开原市| 呈贡县| 新民市| 乐安县| 盈江县| 南和县| 茶陵县| 青河县|