Có bất kỳ nhược điểm thực tế nào đối với phương pháp tự tham chiếu không?


14

Gần đây tôi đã đề xuất một phương thức xâu chuỗi được triển khai cho một lớp nhất định trong một dự án nhất định để khả năng đọc mã có thể được cải thiện. Tôi đã nhận được một "giao diện trôi chảy không nên được thực hiện chỉ để thuận tiện, nhưng cho ngữ nghĩa" và đã gợi ý của tôi bị từ chối. Tôi trả lời rằng tôi không đề xuất một giao diện trôi chảy mà là phương thức tự xâu chuỗi (cả hai có thể bị nhầm lẫn với nhau, đọc ở phía dưới) để cải thiện khả năng đọc và thoải mái mã hóa, đề nghị lại bị bắn hạ.

Dù sao đi nữa, điều này khiến tôi nghĩ rằng có lẽ tôi có thể phải gánh chịu một thực tiễn tồi tệ bằng cách luôn trả lại "cái này" trong các phương thức không được phép trả lại bất cứ thứ gì (ví dụ: setters).

Câu hỏi của tôi là: có thể áp dụng quy ước trước đây được coi là thực hành xấu hoặc lạm dụng?, Tại sao?. Tôi không nghĩ rằng có bất kỳ nhược điểm hiệu suất, hoặc là có?.


2
Nhìn vào câu hỏi này để có một lập trình viên
tốt.stackexchange.com/questions/48419/iêu

@KeesDijk Cảm ơn, tôi đã chỉnh sửa câu hỏi của mình một chút để nó không giống với câu hỏi đó, vì tôi quan tâm nhiều hơn đến trường hợp các phương thức xâu chuỗi từ cùng một lớp
dukeofgaming

1
tại SO, họ nói với tôi rằng, chuỗi không dành cho C ++ - stackoverflow.com/questions/5760551/ Ấn - bạn nghĩ gì về điều này?
kagali-san

1
@mhambra Có vẻ như bạn chỉ cần cẩn thận khi thực hiện phương pháp xâu chuỗi và xác định các tiêu chuẩn rõ ràng cho điều đó.
dukeofgaming

Câu trả lời:


10

Không

Như Kent Beck chỉ ra, mã được đọc thường xuyên hơn nhiều so với nó được viết.

Nếu chuỗi phương thức làm cho mã của bạn dễ đọc hơn, thì hãy sử dụng phương thức chuỗi.


1
Cuốn sách tuyệt vời .. +1
Rein Henrichs

5
NHƯNG , điều gì sẽ xảy ra nếu bạn là người duy nhất tìm ra phương pháp dễ đọc hơn? Nếu đây là vấn đề của sytilistic, thì bạn sẽ tuân theo một tập hợp các quy ước mã hóa: điều này có nghĩa là, viết theo cùng một kiểu với mã hiện có, để thống nhất.
coredump

@coredump Nghe có vẻ như OP đã được yêu cầu làm điều đó, nhưng tôi nghĩ Steven chỉ nói điều này nếu chuỗi phương thức làm cho nó dễ đọc hơn.
Panzercrisis

1
@Panzercrisis OP được yêu cầu kiềm chế sử dụng phương pháp xâu chuỗi do sự thuận tiện so với ngữ nghĩa. Về cơ bản, câu trả lời của Steven nói "hãy làm điều đó" và chỉ xem xét khả năng đọc mã của OP mà không xem xét ý kiến ​​hay tính nhất quán của nhóm. Điều gì sẽ xảy ra nếu OP muốn viết lại mọi lớp hiện có trong dự án sao cho phù hợp với sở thích của anh ấy về khả năng đọc mã? Đó là cách tôi hiểu đối số thuận tiện / ngữ nghĩa: cần có một lý do "kỹ thuật" để có chuỗi phương thức (btw, đối số đó cũng nghe như thể người khác đang tạo ra một lý do cho sở thích của riêng mình)
coredump

9

Vâng, có những hạn chế

Mã dễ đọc là tốt, nhưng cũng hãy cẩn thận với những gì mã được truyền đạt . Khi các phương thức của đối tượng luôn trả về đối tượng, nó sẽ truyền đạt một vài điều:

  1. Tôi yêu cầu cấu hình nâng cao không nhất thiết phải rõ ràng theo thứ tự nên được đặt hoặc định cấu hình
  2. Mỗi cuộc gọi phương thức tiếp theo được xây dựng trên lần cuối cùng

Trường hợp sử dụng hợp lệ: Truy vấn cơ sở dữ liệu Ad Hoc

Các thư viện lớp tồn tại trong hầu hết mọi ngôn ngữ cho phép bạn truy vấn cơ sở dữ liệu mà không cần dùng đến SQL được mã hóa cứng. Lấy khung thực thể cho .NET làm ví dụ:

DBContext db = new DBContext();
List<Post> posts = db.Posts
    .Where(post => post.Title.Contains("Test"))
    .OrderBy(post => post.DateCreated)
    .ToList();

Đây là một giao diện trôi chảy trong đó mỗi cuộc gọi phương thức tiếp theo sẽ được xây dựng trên giao diện trước đó. Đọc các cuộc gọi này một cách hợp lý trong bối cảnh truy vấn cơ sở dữ liệu.

Trường hợp sử dụng không hợp lệ: Đường tổng hợp để đặt thuộc tính

Bây giờ chúng ta hãy sử dụng cùng một mẫu với Postlớp:

public class Post
{
    public string Title { get; set; }
    public DateTime DateCreated { get; set; }
    public string Body { get; set; }

    public Post SetTitle(string title)
    {
        Title = title;

        return this;
    }

    public Post SetDateCreated(DateTime created)
    {
        DateCreated = created;

        return this;
    }

    public Post SetBody(string body)
    {
        Body = body;

        return this;
    }
}

Bây giờ hãy xem cách bạn sẽ sử dụng lớp này:

Post post = new Post()
    .SetTitle("Test")
    .SetDateCreated(DateTime.Now)
    .SetBody("Just a test");

Khi tôi thấy mã này, tôi ngay lập tức hỏi câu hỏi này: "Sau khi gọi SetBody, nó có truy vấn cơ sở dữ liệu không? Tôi có cần gọi một phương thức khác để nói 'Tôi đã xong chưa?'"

Các cuộc gọi phương thức chuỗi liên lạc với mã bằng cách sử dụng Postlớp là gì?

  1. Tôi có một thiết lập phức tạp
  2. Mỗi cuộc gọi phương thức được xây dựng trên cuộc gọi trước

Điều này có thực sự đúng không? Không. PostLớp học không có thiết lập phức tạp. Đặt tiêu đề, ngày tạo và cơ thể không xây dựng cho nhau hướng tới mục tiêu cuối cùng phức tạp hơn. Bạn đã nghiền một cái chốt vuông thành một cái lỗ tròn.

Hạn chế của chuỗi phương thức tự tham chiếu là bạn giao tiếp rằng nhiều cuộc gọi phương thức được yêu cầu để thực hiện điều gì đó và mỗi cuộc gọi sẽ tạo ra lần cuối. Nếu điều này không đúng, thì chuỗi phương thức có thể truyền thông sai cho các lập trình viên khác.

Khi đồng nghiệp của bạn nói:

Giao diện thông thạo không nên được thực hiện chỉ để thuận tiện, nhưng cho ngữ nghĩa

Họ đã hoàn toàn chính xác. Một giao diện trôi chảy, hoặc chuỗi phương thức, truyền đạt một cái gì đó trong và chính nó có thể không đúng.


Điều này giả định rằng phương thức xâu chuỗi và cấu hình phức tạp luôn đi đôi với nhau. Chúng là những thực thể riêng biệt và sự hiện diện của cái này không nên khiến bạn giả định cái kia.
Jack

Đó không chỉ là "cấu hình phức tạp", mà còn là "các cuộc gọi phương thức tiếp theo xây dựng từ cuộc gọi trước". Phương thức xâu chuỗi có một giao tiếp meta về nó không phải lúc nào cũng đúng với mục đích của một lớp.
Greg Burghardt

1
Phương thức tiếp theo gọi việc xây dựng các phương thức trước cũng khác với phương thức xâu chuỗi phương pháp và tôi không nghĩ rằng việc xử lý cú pháp của phương thức xâu chuỗi như giao tiếp mạnh mẽ đối với ngữ nghĩa của chuỗi hoạt động phụ thuộc vào thứ tự là đáng tin cậy hoặc hữu ích. Đó là một tốc ký cú pháp, không có gì hơn. Sử dụng nó ở nơi nó làm cho mọi thứ ngắn hơn và dễ đọc hơn.
Jack

1
Tôi hiểu bạn nghĩ phương pháp chaining là riêng biệt, nhưng tôi nói rằng các lập trình viên khác, những người không phải là trong đầu của bạn và sử dụng thư viện lớp khác mà làm thực hiện phương pháp chaining vì những lý do có thể sẽ làm cho các giả định về mã của bạn mà là không đúng sự thật. Xin lưu ý rằng chuỗi phương thức có thể ngụ ý điều gì đó mà bạn, tác giả mã, không có ý định. Mã truyền đạt rõ ràng cũng quan trọng như mã dễ đọc. Đừng hy sinh cái này cho cái kia.
Greg Burghardt

1
When an object's methods always return the object, it communicates a couple of things- Tôi nghĩ đây là ý kiến ​​cá nhân; thật khó để khẳng định rằng tất cả mọi người nhìn vào các phương pháp bị xiềng xích sẽ thừa nhận những điều giống nhau.
Sam Dufel 16/12/14

1

Hạn chế chính là sự mất đi sự rõ ràng. Ví dụ:

x.foo();
x.bar();
x.baz();

Vì không có câu lệnh nào trả về giá trị (hoặc nếu có, nên nó bị bỏ qua), chúng chỉ có thể hữu ích nếu chúng tạo ra tác dụng phụ. Tương phản với:

x.foo()
 .bar()
 .baz();

Đầu tiên, không rõ điều đó barbazhoạt động trên các đối tượng cùng loại x, trừ khi bạn biết thực tế rằng xlớp đó là lớp duy nhất có các phương thức đó. Ngay cả khi đó là trường hợp, nó không rõ ràng các phương thức hoạt động trên x, hoặc các đối tượng mới.

Làm nổi bật các phần của mã có tác dụng phụ là hữu ích, vì bạn cần theo dõi các tác dụng phụ đó để lý giải về chương trình. Bạn phải cân nhắc sự mất khả năng rõ ràng so với mức tăng tiềm năng khi viết mã dễ dàng, nhưng cũng xem xét rằng mã được đọc nhiều hơn so với viết.


0

Xem xét tất cả các yếu tố phong cách của ngôn ngữ lập trình (trái ngược với ngôn ngữ máy mã hóa bằng tay) và nó làm suy yếu đối số "ngữ nghĩa không thuận tiện".

Toàn bộ những gì chúng tôi làm là các kỹ sư đang cung cấp sự tiện lợi xung quanh ngữ nghĩa.

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.