2015-10-19 22 views
5

tôi đang tìm kiếm thông qua các bên trong của Pharo và nhận thấy rằng định nghĩa của số học + và - trông rất giống nhau:Tại sao định nghĩa Pharo về số học + và - về cơ bản là mã trùng lặp?

+ aNumber 
"Refer to the comment in Number + " 
aNumber isInteger ifTrue: 
    [self negative == aNumber negative 
     ifTrue: [^ (self digitAdd: aNumber) normalize] 
     ifFalse: [^ self digitSubtract: aNumber]]. 
aNumber isFraction ifTrue: 
    [^Fraction numerator: self * aNumber denominator + aNumber numerator denominator: aNumber denominator]. 
^ aNumber adaptToInteger: self andSend: #+ 

- aNumber 
"Refer to the comment in Number - " 
aNumber isInteger ifTrue: 
    [self negative == aNumber negative 
     ifTrue: [^ self digitSubtract: aNumber] 
     ifFalse: [^ (self digitAdd: aNumber) normalize]]. 
aNumber isFraction ifTrue: 
    [^Fraction numerator: self * aNumber denominator - aNumber numerator denominator: aNumber denominator]. 
^ aNumber adaptToInteger: self andSend: #- 

Như tôi đã nhìn thấy nó, điều này là hoàn toàn so với OO cách thiết kế mọi thứ và nói chung là xấu. Tại sao không ai tìm được giải pháp tốt hơn?

Trả lời

4

Điều đơn giản nhất tôi có thể nghĩ đến là:

- aNumber 
    ^self + aNumber negated 

Tuy nhiên, điều này sẽ có chi phí:

  • tạo khác LargeInteger trung gian, hoặc Phân
  • thêm hai thông điệp gửi đến thực hiện thao tác -

Những gì chúng ta thấy ở đây là một cống nạp cho opti mization. Không tối ưu hóa sớm, đây là một hoạt động cấp thấp được sử dụng rộng rãi.

Có những thứ khác trong mã này mà không phải là hoàn hảo:

  • sử dụng isInteger và isFraction cũng có thể được thay thế bằng một số loại double-dispatching
  • các phương pháp digitAdd: và digitSubtract: công việc cho các số nguyên được lưu trữ dưới dạng ký hiệu - độ lớn thay vì 2-bổ sung mà không phải là chi tiết thực hiện hoàn toàn rõ ràng và đáng được nhận xét - hoặc có thể nên đổi tên thành digitAddMagnitude: digitSubtractMagnitude:
0

Đó là không chống lại OO - hành vi được đóng gói, ẩn hành vi phức tạp đằng sau một API đơn giản. (hoặc giao thức tin nhắn, như chúng ta muốn gọi nó trong Smalltalk).

Có rất nhiều sự sao chép mã. Nó sẽ có thể đặt một lớp của indirection trong, và giữ cho mã ở một nơi phổ biến - nhưng đây là một ví dụ về hy sinh compactness cho tốc độ - kinh doanh ra dấu chân bộ nhớ cho tốc độ. Nó cũng giao dịch tốc độ với chi phí của OnceAndOnlyOnce mà tôi tin là mối quan tâm nguyên tắc của bạn.

Trong Smalltalk đầu tiên tôi đã sử dụng, LearningWorks, (dựa trên triển khai ParcPlace, iirc) chức năng - đơn giản là phủ nhận đối số và sau đó gọi hàm +. Điều này làm cho hoạt động - chậm hơn hoạt động +.

Có rất nhiều sự cân bằng và tối ưu hóa tiềm năng trong phát triển phần mềm - những cái chính là tốc độ cho bộ nhớ (và ngược lại), tốc độ thực hiện cho tốc độ phát triển (và ngược lại). làm việc ngay bây giờ so với dễ dàng giữ cho nó hoạt động và tinh chỉnh trong một thời gian dài.

Phát triển OO thường được tối ưu hóa xung quanh tối ưu hóa tốc độ phát triển với chi phí tốc độ thực thi, sử dụng các ngôn ngữ cấp cao phát triển nhanh hơn nhưng chạy chậm hơn; tối ưu hóa cho khả năng bảo trì lâu dài qua nhanh chóng; và sử dụng rất nhiều bộ nhớ để vắt kiệt hiệu suất ra khỏi mã chậm hơn một cách tự nhiên nhất có thể.

Tuy nhiên, đây là những khái quát chung. Có những ví dụ phản đối cho tất cả chúng, tôi khá chắc chắn.

Các vấn đề liên quan