2009-03-10 31 views
5

Tôi đang viết một API để tạo hình dạng hình học và tôi đang gặp một số khó khăn khi đặt tên cho các phương thức của mình.Cần tư vấn về cách đặt tên cho các phương thức

Hãy lấy một trường hợp đơn giản: Tạo vòng kết nối. Hầu hết chúng ta có thể quen thuộc với một phương pháp như graphics.drawEllipse(x, y, w, h). Để vẽ một vòng tròn, bạn cần biết tọa độ trên cùng bên trái và chiều rộng và chiều cao của vòng tròn.

API của tôi nhằm giúp nhà phát triển dễ dàng vẽ hình dạng bằng nhiều thông tin khác nhau mà không cần phải làm nhiều toán - điều này không quan trọng đối với vòng kết nối, nhưng phức tạp hơn đối với các hình dạng khác. Ví dụ, bạn cũng có thể vẽ một vòng tròn cho tọa độ trung tâm và bán kính của nó, hoặc các tọa độ bên trái và dưới cùng bên phải.

Vì vậy, tôi có một lớp Circle với các phương pháp nhà máy như:

Circle.createWithCenterAndRadius(cx, cy, r) 
Circle.createWithBoundingBox(x1, y1, x2, y2) 
Circle.createWithWidthAndHeight(x, y, w, h) 

tôi cảm thấy như có thể có một "mã mùi" ở đây, nhưng tôi không chắc chắn. Một mặt, các phương pháp nhà máy này nhất thiết là mô tả. Mặt khác, tôi có thể xem xét những tên phương pháp này ngoài tầm kiểm soát. Ví dụ, làm thế nào tôi sẽ đặt tên một phương pháp nhà máy Triangle tạo ra một tam giác cho một điểm, chiều dài của một bên, một góc, và chiều dài của một bên khác? Triangle.createWithPointSideAngleAndSide(x, y, side1, angle, side2)? Có phải đó chỉ là điều ác?

Nếu bạn sử dụng API này, các tên phương thức như thế này có phù hợp với bạn không? Bạn có lời khuyên về cách tôi có thể làm cho tên phương pháp trở nên lành mạnh hơn?

+0

bạn đã làm gì với? – eglasius

+0

Tôi đang thay đổi các phương thức để đặt tên 'từ', giống như trong bài đăng của Jason. Tôi đang loại bỏ một số 'không cần thiết', theo nhận xét của Joe_M về bài đăng của kevchadder. Tôi đã xem xét ý tưởng giao diện thông thạo của bạn; Tôi đang sử dụng Java, do đó, không có tham số được đặt tên. Tôi thích ý tưởng của Slim, xem nó có khả thi hay không. –

+0

Và tôi có kế hoạch theo dõi khi tôi hoàn tất bản dự thảo API của mình, tôi sẽ sớm có. –

Trả lời

0

Có, đây là một câu trả lời meta, nhưng tôi khuyên bạn nên xem qua cách đặt tên được thực hiện trong Apple's Cocoa.

11

Đồng ý với bất kỳ ngôn ngữ nào không hỗ trợ các thông số được đặt tên. Nếu ngôn ngữ hỗ trợ các tham số được đặt tên, tôi thích hơn Create ngắn và chỉ có các tên tham số rõ ràng.

Đối với một ngôn ngữ với các thông số được đặt tên, bạn sẽ:

Circle.Create(
    centerX = cx, 
    centerY = cy, 
    radius = r 
); 

Một tùy chọn khác tham gia nhiều hơn, sẽ là một giao diện thông thạo loại tương tự (nhưng điều đó có lẽ là quá nhiều):

circleBuilder.Center(cx,cy).Radius(r) 
circleBuilder.Center(x,y).Width(w).Height(y) 
circleBuilder.BoundWith().Left(x1,y1).Right(x2,y2) 

Trung tâm lợi nhuận một thể hiện của một lớp trung gian chỉ cho phép Bán kính hoặc Chiều rộng. Và BoundWith trả về một cái chỉ cho phép Trái.

+0

Đó là một mã khủng khiếp để tạo. Tôi nghĩ rằng bạn sẽ lãng phí rất nhiều thời gian tạo ra mã đó và sau đó cố gắng để genericize nó để nó cũng hoạt động khi tạo một hình chữ nhật hoặc một tam giác. – jmucchiello

+0

@Joe, cập nhật nó từ "nhưng điều đó có thể là quá nhiều" để "nhưng đó có lẽ là quá nhiều". – eglasius

14

Bạn có thể thay đổi phương pháp vòng tròn của bạn để

Circle.FromCenterAndRadius(...) 
Circle.FromBoundingBox(...) 
Circle.FromWidthAndHeight(...) 

Nó ám chỉ rằng bạn đang tạo vòng kết nối khỏi cơ quan đại diện khác nhau của họ trong một loại cách súc tích ...

+0

+1 Tôi thích sự cải thiện :) – eglasius

1

Đối với các ngôn ngữ mà không hỗ trợ đặt tên tham số, nó sẽ được sạch hơn để làm cho phương pháp tên một cái gì đó rất đơn giản như Circle.create và sau đó chỉ cần thêm một chuỗi cờ đầu vào bổ sung (như "trung tâm" hoặc "bounding") chỉ ra cách các giá trị đầu vào nên được giải thích cho các trường hợp khó phân biệt dựa trên đầu vào v số và loại đáng tin cậy? Hạn chế này sẽ là nó đòi hỏi thêm logic bên trong của phương thức để xử lý các kiểu đối số đầu vào khác nhau và cũng yêu cầu người dùng nhớ các tùy chọn cờ.

1

Tôi sẽ có phương pháp CreateTriangle và có quá tải hiển thị các phần thông tin khác nhau cần thiết.

Ví dụ:

Circle.CreateCircle(cx, cy, r) 
Circle.CreateCircle(point1, point2) 
Circle.CreateCircle(point, width, height) 
+0

+1: Đồng ý. Đây là cách tôi sẽ làm điều đó là tốt ... Hãy để các thông số quá tải nói cho chính mình. – Cerebrus

+0

er, bạn có hai phương pháp ở đây với các tham số tương tự (giả sử tất cả các tham số là một số kiểu số nguyên). – slim

+0

bạn ars chính xác, nó sẽ là tốt hơn để sử dụng một điểm lớp rhather hơn hai ints để phân biệt – cjk

8

Tôi nghĩ không có gì sai với các phương pháp mô tả của bạn - chúng nhỏ gọn và mô tả chính xác những gì đang diễn ra. Người sử dụng thư viện sẽ không nghi ngờ gì về chức năng của các phương thức của bạn, không phải là các lập trình viên bảo trì.

Bạn cũng có thể áp dụng một số mẫu thiết kế ở đây nếu bạn thực sự lo lắng về việc trưng ra một số lượng lớn các phương pháp nhà máy - như có phương pháp nhà máy với các lớp thuộc tính. Bạn có thể có một lớp CircleProperties với các thuộc tính như CenterX, CenterY, Radius, (bool) UseCenterX, (bool) UseCenterY vv và sau đó bạn chuyển nó tới phương thức factory mà sẽ tìm ra phương thức factory (private) nào được sử dụng.

Giả sử C#:

var circleProperties = new CircleProperties() 
{ 
    CenterX = 10, 
    CenterY = -5, 
    Radius = 8, 
    UseCenterX = true, 
    UseCenterY = true, 
    UseCenterRadius = true 
}; 

var circle = Circle.Create(circleProperties); 
+0

Bạn có thực sự cần thuộc tính "UseX" không? Bạn có thể không chỉ đơn giản là kiểm tra các thuộc tính đã được thiết lập (là không null)? Hoặc đặt chúng trong trình cài đặt cho các thuộc tính khác (ví dụ: setCenterX() đặt UseCenterX)? – TMN

+0

TMN: Bạn có thể, nhưng sau đó bạn thực sự phải chọn số ma thuật của bạn một cách đúng đắn ... Rõ ràng, 0.0 là một tọa độ hoàn toàn hợp lệ. Thiết lập các boolean tự động trong setter thích hợp là một ý tưởng tốt mặc dù. –

6

bản năng đầu tiên của tôi là phải có nhiều loại, trong đó sẽ cho phép phương pháp quá tải trực quan hơn.

// instead of Circle.createWithCenterAndRadius(cx, cy, r) 
Circle.create(new Point(cx,xy), r); 

// instead of Circle.createWithBoundingBox(x1, y1, x2, y2) 
Circle.create(new Point(x1,y1), new Point(x1,y1)); 
// or even... 
Circle.create(new Box(p1,p2)); 

// instead of Circle.createWithWidthAndHeight(x, y, w, h) 
Circle.create(new Point(x,y), w, h); 

Cũng như Point, bạn có thể xác định cách (mà sẽ cho phép cho các đơn vị khác nhau)

Nếu phong cách này phù hợp với bạn, hãy xem xét lý do tại sao bạn cần một phương pháp nhà máy thay vì một nhà xây dựng.

Circle c = new Circle(new Point(cx,xy), r); 
-1

Tôi biết, tôi biết. Điều này nghe hoàn toàn điên rồ đối với bạn C/C++/Java người, nhưng các ví dụ được đưa ra trong câu hỏi và trong tất cả những câu trả lời rõ ràng chứng minh những gì một, xấu CamelCaseNaming quy ước thực sự là.

Chúng ta hãy nhìn vào một ví dụ ban đầu:

Circle.createWithCenterAndRadius(cx, cy, r) 
Circle.createWithBoundingBox(x1, y1, x2, y2) 
Circle.createWithWidthAndHeight(x, y, w, h) 

Và bây giờ chúng ta hãy thoát khỏi rằng trường hợp lạc đà ký hiệu

Circle.create_with_center_and_radius(cx, cy, r) 
Circle.create_with_bounding_box(x1, y1, x2, y2) 
Circle.create_with_width_and_height(x, y, w, h) 

Điều này có vẻ khủng khiếp unfamilar, nhưng phải trung thực: phiên bản nào là dễ đọc hơn?

+0

Không phải là một ví dụ xấu - nó thực sự là dễ dàng hơn một chút để đọc - nhưng hoàn toàn không liên quan. Nó không giống như bất cứ ai sẽ chuyển đổi hoặc bất cứ điều gì (và MAN nó sẽ là xấu nếu ai đó đã làm !!) Vì vậy, những gì bạn đang cố gắng để thực hiện? –

+0

Lưu ý: Khi tôi ở Java, tôi sử dụng cú pháp Java, khi tôi ở trong Ruby, tôi đã sử dụng cú pháp Ruby. Tôi cảm thấy không cần phải chuyển đổi bất kỳ người dùng nào sang người khác - cả hai đều khá dễ đọc. ps. Mặc dù ruby ​​dễ đọc hơn một chút, nhưng java là một việc tốt để gõ. –

0

Bản năng của bạn là chính xác - toàn bộ mô hình tạo ra mọi thứ theo cách này là - iffy.

Trừ khi chúng được sử dụng chỉ một hoặc hai lần, chúng sẽ trở nên khá lộn xộn. Nếu bạn đang tạo ra một hình dạng với 5 vòng tròn và 3 hình tam giác, nó sẽ là một mớ hỗn độn.

Bất kỳ thứ gì ngoài một ví dụ tầm thường có thể được thực hiện tốt nhất với một số loại triển khai theo hướng dữ liệu.

Hướng tới những đầu đó, việc lấy chuỗi, băm hoặc XML để xác định hình dạng của bạn có thể cực kỳ hữu ích.

Nhưng tất cả phụ thuộc vào cách bạn mong đợi chúng được sử dụng.

Tôi có cùng loại vấn đề với việc tạo điều khiển Swing trong Java. Bạn kết thúc với dòng sau dòng "new Button()" theo sau là một chuỗi các cuộc gọi thuộc tính .set cũng như một dòng mã để sao chép giá trị vào một đối tượng (hoặc thêm một người nghe) và một dòng để đặt lại giá trị..

Loại boilerplate này không bao giờ xảy ra trong mã, vì vậy tôi thường cố gắng tìm cách điều khiển nó bằng dữ liệu, liên kết các điều khiển với các đối tượng động - và hướng tới kết thúc đó, một ngôn ngữ dựa trên chuỗi mô tả sẽ rất Hữu ích.

+0

Đề xuất của bạn chắc chắn có giá trị. Bạn có thể đưa ra một ví dụ ngắn về triển khai theo hướng dữ liệu không? Đối với "chuỗi", bạn ngụ ý một cái gì đó giống như một ngôn ngữ cụ thể theo miền (DSL)? –

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