'Luật của Demeter' có thể áp dụng cho chữ ký phương thức công khai / API không?


10

Do các thay đổi đối với chữ ký API / phương thức công khai nên ở mức tối thiểu để ngăn chặn việc phá vỡ các mã máy khách sử dụng các phương thức này, tôi đã tự hỏi liệu Luật của Demeter có ít áp dụng cho các mã này không.

Một ví dụ đơn giản:

class Account() {
   double balance;
   public void debit(Transaction t) {
      balance -= t.getAmount();
   }
}

Lưu ý rằng phương thức ghi nợ vượt qua đối tượng Giao dịch thay vì chỉ gấp đôi số tiền ('Luật của Demeter', theo tôi hiểu, sẽ nói chỉ chuyển thông tin bắt buộc, trong trường hợp này chỉ là số tiền, không phải đối tượng Giao dịch ... ). Lý do đằng sau điều này là bởi vì phương thức trong tương lai có thể yêu cầu một số thuộc tính Giao dịch khác ngoài số tiền. Từ những gì tôi hiểu, điều này sẽ ngăn việc phá vỡ chữ ký phương thức bằng cách thêm một tham số mới trong tương lai.

Điều này làm cho nó một sự lựa chọn hợp lý sau đó? Hay tôi đang thiếu một cái gì đó?

Câu trả lời:


3

Nhưng điều này không vi phạm Luật Demeter.

Chính thức hơn, Luật Demeter cho các hàm yêu cầu một phương thức M của một đối tượng O chỉ có thể gọi các phương thức của các loại đối tượng sau:

  • Ôi chính nó
  • Thông số của M
  • bất kỳ đối tượng nào được tạo / khởi tạo trong M
  • Đối tượng thành phần trực tiếp của O
  • một biến toàn cục, có thể truy cập bằng O, trong phạm vi của M

Wikipedia: Luật của Demeter

Giao dịch là một đối số cho phương thức ghi nợ, vì vậy gọi t.getAmount () là tốt.

Chỉnh sửa: Đọc sai rằng, bạn đang nói LoD sẽ cho bạn vượt qua số tiền của giao dịch, không phải là một đối tượng Giao dịch. Nếu đó là trường hợp thì có, tôi nghĩ rằng đây là một nơi tốt để phá vỡ nó, biết rằng bạn sẽ cần nhiều hơn từ đối tượng Giao dịch trong tương lai. Ngoài ra, đóng gói các nguyên thủy trong các đối tượng cấp miền là một thực hành lập trình tốt khác.

Chỉnh sửa 2: Đã đọc có thể cần nhiều hơn trong tương lai, người ta cũng có thể thấy đây là mạ vàng không cần thiết. Cung cấp một phương thức mất gấp đôi bây giờ (hoặc tốt hơn là một lớp Tiền) là đủ. Nếu sau này bạn cần một đối số Giao dịch thì sẽ không có gì xấu khi cung cấp chữ ký thứ hai thực hiện Giao dịch, nhưng tiếp tục hỗ trợ chữ ký gốc. Không giống như bạn sẽ thực hiện hai phương thức, một phương thức sẽ gọi phương thức kia.


Cảm ơn vì đầu vào của bạn. Tôi đồng ý về các nguyên thủy đóng gói trong các đối tượng miền. Tuy nhiên, chỉ là điểm của bạn trong Chỉnh sửa 2, bạn nói rằng không phải là thảm họa khi thêm chữ ký thứ 2 mới, nhưng điều đó có nghĩa là thay đổi mã thành mã máy khách hiện phải truyền 2 tham số thay vì một tham số. Đó là điểm thứ 2, tôi không ngần ngại đồng ý ...
Carlos Jaime C. De Leon

Chỉnh sửa 2 là chủ quan, tôi đồng ý.
Sean

0

Nếu bạn dự định mở rộng Accountlớp học trong tương lai, tôi sẽ nói rằng đây là một tình huống làm cho Transactionđối tượng có mục đích chung hơn sẽ là một sự bẻ cong tốt các quy tắc của Luật.

Ví dụ:

public class Amount {

    public void process( Transaction t ) {
        ....
    }
}

public abstract class Transaction {

    public String getType();

}

Tôi nghĩ rằng tôi đang đi lạc từ câu hỏi ban đầu, nhưng quan điểm của tôi là trong khi bạn có thể lo lắng rằng bạn đang đi lạc từ Luật của Demeter, thì những lợi thế của việc làm này vượt xa những tiêu cực.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.