2010-04-07 28 views
5

Tôi đang thiết kế một ứng dụng cho phép tôi vẽ một số chức năng trên đồ họa. Mỗi chức năng sẽ được rút ra từ một tập hợp các điểm mà tôi sẽ chuyển đến lớp đồ họa này.Thiết kế một lớp theo cách mà nó không trở thành một "đối tượng Thiên Chúa"

Có nhiều loại điểm khác nhau, tất cả đều được kế thừa từ lớp MyPoint. Đối với một số loại điểm nó sẽ chỉ in chúng trên màn hình như chúng, những người khác có thể bị bỏ qua, những người khác được thêm vào, do đó, có một số loại logic liên quan đến họ có thể trở nên phức tạp.

Cách vẽ đồ họa thực sự không phải là vấn đề chính ở đây. Điều làm phiền tôi là làm thế nào để làm cho logic mã như vậy mà lớp GraphicMaker này không trở thành cái gọi là Thiên Chúa-Object.

Nó sẽ là dễ dàng để làm một cái gì đó như thế này:

class GraphicMaker { 
    ArrayList<Point> points = new ArrayList<Point>(); 

    public void AddPoint(Point point) { 
     points.add(point); 
    } 

    public void DoDrawing() { 
     foreach (Point point in points) { 
      if (point is PointA) { 
       //some logic here 
      else if (point is PointXYZ) { 
       //...etc 
      } 
     } 
    } 
} 

Làm thế nào bạn sẽ làm điều gì đó như thế này? Tôi có cảm giác cách chính xác sẽ là đặt logic vẽ lên từng đối tượng Điểm (vì vậy mỗi lớp con từ Point sẽ biết cách vẽ chính nó) nhưng hai vấn đề phát sinh:

  1. Sẽ có các loại điểm cần phải biết tất cả các điểm khác tồn tại trong lớp GraphicObject để biết cách tự vẽ.
  2. Tôi có thể tạo ra rất nhiều phương pháp/thuộc tính từ lớp đồ họa công khai, để tất cả các điểm có tham chiếu đến lớp Đồ họa và có thể tạo ra tất cả logic của chúng theo ý muốn, nhưng không phải là giá lớn trả tiền vì không muốn có một lớp Thiên Chúa?

Trả lời

4

tôi sẽ làm như bạn đề nghị và làm cho mỗi điểm chịu trách nhiệm cho việc vẽ bản thân, vượt qua hàng loạt các điểm khác với nó:

interface ICanDraw { 
    void Draw(ArrayList<Point> allPoints); 
} 

public abstract class Point : ICanDraw { 
    ... 
} 

public PoniePoint : Point { 
    public void Draw(ArrayList<Point> allPoints) { 
     // do drawing logic here 
    } 
} 

Đối GraphicMaker của bạn:

public void DoDrawing() { 
    foreach (Point point in points) { 
     point.Draw(points); 
    } 
} 

(My Java là một chút gỉ, vì vậy mà có thể không 100% cú pháp chính xác Java nhưng tôi nghĩ rằng nó chuyển tải đề nghị của tôi).

+0

Aha! Tôi đã không nghĩ đến việc có lớp GraphicObject chuyển danh sách các điểm làm đối số cho phương thức Draw() của Point. Điều đó có vẻ là một ý tưởng rất hay. Mặc dù tôi vẫn không chắc chắn nó không phải là tốt nhất chỉ để làm cho tất cả các thuộc tính có liên quan công khai trong lớp GraphicObject, như có thể trong tương lai tôi sẽ cần cho logic vẽ điểm của tôi không chỉ danh sách tất cả các điểm mà còn một số thứ khác. Nếu tôi thông qua danh sách trái ngược với việc có các thuộc tính công khai, tôi sẽ phải thêm các tham số mới vào các phương thức Draw() của điểm. –

+1

Nó phụ thuộc thực sự như thế nào các GraphicsObject hoạt động, nhưng tôi nghĩ rằng tôi không muốn vượt qua nó vào phương pháp Vẽ (tôi có thể sai, rất theo ngữ cảnh của nó và tôi không có bối cảnh đầy đủ).Nếu bạn thấy rằng bạn cần một tập hợp con thông tin mà GraphicsObject có thể cung cấp, cộng với tất cả các điểm, tôi sẽ xem xét việc tạo một lớp hoàn toàn cho mục đích chuyển đến phương thức Draw có chứa Danh sách các điểm và nội dung bổ sung từ GraphicsObject mà bạn nhu cầu. Điều này duy trì duy nhất reposinsibilty và tách mối quan tâm. KHÔNG BAO GIỜ - nếu GraphicsObject quan tâm đến bản vẽ rồi chuyển nó vào. –

+3

Hãy xem qua các hệ thống hiện có để lấy cảm hứng. Trong Swing, mỗi thành phần có một lớp sơn riêng() được truyền qua đối tượng Grapics. Cách tiếp cận Container/Layout/Component cho phép một số thành phần ảnh hưởng đến các thành phần (chứa) khác. Tuy nhiên, tôi sẽ không chuyển danh sách tới Point's Draw. Tôi muốn thêm một truy vấn vào GraphicsObject trả về một danh sách các điểm khác. Giống như các điểm với một loại nhất định, trong một khoảng cách nào đó, cùng màu, v.v. –

3

Bạn đúng là mỗi phân lớp của điểm phải có phương thức vẽ riêng sẽ ghi đè phương thức vẽ trong lớp điểm cơ sở.

Phương thức vẽ phải có tham chiếu đến đối tượng đồ họa, cần có phương pháp/thuộc tính công khai cho bất kỳ thứ gì cần được sử dụng trong phương pháp vẽ điểm, bao gồm danh sách các điểm nếu đó là một trong những điều các phương pháp vẽ cần.

Tại sao bạn quan tâm đến việc tạo phương pháp công khai trên lớp đồ họa? Một khi mã phát triển, một vài phương thức hiển thị thêm sẽ khó hiểu hơn rất nhiều so với một phương thức khổng lồ làm mọi thứ.

+0

Có, tôi nghĩ bạn đúng. Có một số thuộc tính/phương pháp công khai chắc chắn là cách để đi đến đây. –

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