Tôi duy trì phần mềm CAD/CAM cho máy cắt kim loại. Vì vậy, tôi có một số kinh nghiệm với các vấn đề này.
Khi lần đầu tiên chúng tôi chuyển đổi phần mềm của mình (lần đầu tiên được phát hành vào năm 1985!) Cho một đối tượng được thiết kế theo định dạng, tôi đã làm những gì bạn không thích. Các đối tượng và giao diện có Draw, WriteToFile, vv Khám phá và đọc về các mẫu thiết kế ở giữa quá trình chuyển đổi đã giúp rất nhiều nhưng vẫn còn rất nhiều mùi mã xấu.
Cuối cùng tôi nhận ra rằng không có loại hoạt động nào trong số này thực sự là mối quan tâm của đối tượng. Nhưng thay vì các hệ thống phụ khác nhau cần thiết để thực hiện các hoạt động khác nhau. Tôi xử lý điều này bằng cách sử dụng những gì bây giờ được gọi là một đối tượng lệnh Passive View, và được xác định rõ Giao diện giữa các lớp phần mềm.
phần mềm của chúng tôi được cấu trúc cơ bản như thế này
- Các hình thức thực hiện khác nhau Mẫu Interface. Các biểu mẫu này là một sự kiện truyền qua các lớp sự kiện đến Tầng giao diện người dùng.
- Lớp giao diện người dùng nhận Sự kiện và thao tác biểu mẫu thông qua giao diện Biểu mẫu.
- Lớp giao diện người dùng sẽ thực thi các lệnh mà tất cả triển khai giao diện Lệnh
- Đối tượng giao diện người dùng có giao diện riêng mà lệnh có thể tương tác.
- Lệnh nhận thông tin mà họ cần, xử lý nó, thao tác mô hình và sau đó báo cáo lại cho các đối tượng giao diện người dùng mà sau đó thực hiện mọi thứ cần thiết với biểu mẫu.
- Cuối cùng, các mô hình có chứa các đối tượng khác nhau của hệ thống của chúng tôi. Giống như các chương trình hình dạng, đường cắt, bàn cắt và tờ kim loại.
Bản vẽ được xử lý trong Lớp giao diện người dùng. Chúng tôi có phần mềm khác nhau cho các máy khác nhau. Vì vậy, trong khi tất cả các phần mềm của chúng tôi chia sẻ cùng một mô hình và sử dụng lại nhiều lệnh giống nhau. Họ xử lý những thứ như vẽ rất khác nhau. Ví dụ một bàn cắt được vẽ khác nhau cho một máy router so với một máy bằng cách sử dụng một ngọn đuốc plasma mặc dù cả hai đều là esstentially một bàn phẳng X-Y khổng lồ. Điều này bởi vì giống như xe hơi, hai máy này được chế tạo đủ khác nhau để có sự khác biệt thị giác cho khách hàng.
Đối với hình dạng, chúng tôi thực hiện như sau
Chúng tôi có các chương trình hình dạng tạo đường cắt thông qua các thông số đã nhập. Con đường cắt biết được chương trình hình dạng nào được tạo ra. Tuy nhiên một con đường cắt không phải là một hình dạng. Nó chỉ là thông tin cần thiết để vẽ trên màn hình và cắt hình. Một lý do cho thiết kế này là các đường cắt có thể được tạo mà không có chương trình hình dạng khi chúng được nhập từ một ứng dụng bên ngoài.
Thiết kế này cho phép chúng tôi tách thiết kế đường cắt khỏi thiết kế hình dạng không phải lúc nào cũng giống nhau. Trong trường hợp của bạn, tất cả những gì bạn cần để đóng gói là thông tin cần thiết để vẽ hình dạng.
Mỗi chương trình hình dạng có một số chế độ xem triển khai Giao diện IShapeView. Thông qua giao diện IShapeView, chương trình hình dạng có thể cho biết dạng hình dạng chung chúng ta có cách thiết lập chính nó để hiển thị các tham số của hình dạng đó. Dạng hình dạng chung thực hiện một giao diện IShapeForm và đăng ký chính nó với đối tượng ShapeScreen. Đối tượng ShapeScreen đăng ký chính nó với đối tượng ứng dụng của chúng ta. Các khung nhìn hình dạng sử dụng bất kỳ khung hình nào tự đăng ký với ứng dụng.
Lý do cho nhiều lượt xem mà chúng tôi có khách hàng muốn nhập hình dạng theo nhiều cách khác nhau. Cơ sở khách hàng của chúng tôi được phân chia bằng một nửa giữa những người muốn nhập thông số hình dạng trong biểu mẫu bảng và những người muốn nhập bằng biểu diễn đồ họa của hình dạng trước mặt họ. Chúng tôi cũng cần phải truy cập vào các thông số vào các thời điểm thông qua một hộp thoại tối thiểu thay vì màn hình nhập hình dạng đầy đủ của chúng tôi. Do đó nhiều lượt xem.
Lệnh điều khiển hình dạng rơi vào một trong hai loại hình ảnh. Hoặc là họ thao tác đường cắt hoặc họ thao tác các thông số hình dạng. Để thao tác các thông số hình dạng chung, chúng tôi hoặc ném chúng trở lại màn hình nhập hình hoặc hiển thị hộp thoại tối thiểu. Tính toán lại hình dạng và hiển thị nó trong cùng một vị trí.
Đối với đường cắt, chúng tôi gộp từng hoạt động vào một đối tượng lệnh riêng biệt. Ví dụ: chúng tôi có các đối tượng lệnh
ResizePath RotatePath MovePath SplitPath v.v.
Khi chúng ta cần thêm chức năng mới, chúng tôi thêm đối tượng lệnh khác, tìm một nút menu, bàn phím ngắn hoặc nút thanh công cụ trong màn hình giao diện người dùng phù hợp và thiết lập đối tượng UI để thực thi lệnh đó.
Ví dụ
CuttingTableScreen.KeyRoute.Add vbShift+vbKeyF1, New MirrorPath
hoặc
CuttingTableScreen.Toolbar("Edit Path").AddButton Application.Icons("MirrorPath"),"Mirror Path", New MirrorPath
Trong cả hai trường hợp đối tượng MirrorPath lệnh đang được liên kết với một yếu tố giao diện người dùng mong muốn. Trong phương thức thực hiện của MirrorPath là tất cả mã cần thiết để nhân bản đường dẫn trong một trục cụ thể. Có khả năng lệnh sẽ có hộp thoại riêng của nó hoặc sử dụng một trong các thành phần giao diện người dùng để yêu cầu người dùng có trục phản chiếu. Không ai trong số này đang tạo khách truy cập hoặc thêm phương thức vào đường dẫn.
Bạn sẽ thấy rằng rất nhiều thứ có thể được xử lý thông qua các hành động đóng gói thành các lệnh. Tuy nhiên, tôi cảnh cáo đó không phải là một tình huống màu đen hoặc trắng. Bạn sẽ vẫn thấy rằng những thứ nhất định hoạt động tốt hơn như các phương thức trên đối tượng gốc. Trong kinh nghiệm có thể tôi thấy rằng có lẽ 80% những gì tôi sử dụng để làm trong các phương pháp đã có thể được chuyển vào lệnh. 20% cuối cùng chỉ đơn giản là làm việc tốt hơn trên đối tượng.
Hiện tại một số có thể không thích điều này vì dường như vi phạm đóng gói. Từ việc duy trì phần mềm của chúng tôi như một hệ thống hướng đối tượng trong thập kỷ qua, tôi phải nói rằng điều quan trọng nhất trong dài hạn mà bạn có thể làm là ghi rõ sự tương tác giữa các lớp khác nhau của phần mềm và giữa các đối tượng khác nhau.
Hành động đóng gói vào các đối tượng Command giúp với mục tiêu này tốt hơn so với một sự tận tụy sâu sắc đối với các lý tưởng đóng gói.Tất cả mọi thứ cần được thực hiện để Mirror a Path được đóng gói trong Mirror Path Command Object.
Chỉ cần một lưu ý sang một bên, vì không chắc bạn có thể thay đổi ngôn ngữ của mình: Có các ngôn ngữ hỗ trợ trực tiếp cho nhiều hàm chung của công văn. – Svante
Câu hỏi hay. Tôi chỉ muốn cung cấp một điểm đối kháng. Đôi khi vấn đề của bạn với (5) có thể là một điều tốt. Tôi sử dụng mẫu khách truy cập khi tôi có một số chức năng phải được cập nhật khi loại phụ IShape mới được xác định. Tôi có một giao diện IShapeVisitor xác định những phương thức nào là cần thiết. Miễn là giao diện đó được cập nhật với loại phụ mới, mã của tôi không xây dựng cho đến khi chức năng quan trọng được cập nhật. Đối với một số trường hợp, điều này có thể rất hữu ích. – oillio
Tôi đồng ý với @oillio, nhưng sau đó bạn cũng có thể thực thi nó như một phương pháp trừu tượng trên IShape. Mẫu khách truy cập mua bạn bằng ngôn ngữ OO thuần túy là địa phương của hàm (so với địa phương của lớp học) và do đó có sự phân tách các mối quan tâm.Trong bất kỳ trường hợp nào, việc sử dụng mẫu khách truy cập phải rõ ràng phá vỡ thời gian biên dịch khi bạn muốn buộc thêm các loại mới để được xem xét cẩn thận! –