이제 생성자는 비공개가 됐다. 그리고 동반 객체에 있는 invoke 함수가 operator로 선언되어 있고, 그 안에 검증 코드가 들어 있다. invoke라는 이름은 plus나 times처럼 연산자를 오버라이드할 때 쓸 수 있는 특별한 역할을 하는 이름이므로 operator 키워드를 붙인다.
여기서 오버라이드할 연산은 함수 호출에 해당하는 ()이다. 그 결과 팩터리 함수를 마치 생성자처럼 호출할 수 있다. 한편 실제 생성자는 이제 비공개다. 동반 객체의 invoke 함수에서는 비공개 생성자로 객체를 생성해 반환할 수 있다. 그리고 fold에 사용할 identity 값을 만들 때도 비공개 생성자를 사용한다. 다음은 이 모든 내용을 적용해 만든 최종 Store 클래스 코드다.
object Store { @JvmStatic fun main(args: Array<String>) { val toothPaste = Product("Tooth paste", Price(1.5), Weight(0.5)) val toothBrush = Product("Tooth brush", Price(3.5), Weight(0.3)) val orderLines = listOf( OrderLine(toothPaste, 2), OrderLine(toothBrush, 3)) val weight: Weight = orderLines.fold(Weight.identity) { a, b -> a + b.weight() } val price: Price = orderLines.fold(Price.identity) { a, b -> a + b.amount() } println("Total price: $price") println("Total weight: $weight") } }