NX Lab

Mẫu thiết kế 'lệnh + kết quả': mỗi tác vụ là một lớp có validate, thực thi và báo cáo thống nhất

#Python#Kiến trúc1 lượt xem

  1. Quản trị viênQuản trị· 0 điểm

    Câu hỏi ·

    Khi bộ công cụ có hàng chục tác vụ, mỗi tác vụ nên theo một khuôn: kiểm tra đầu vào, thực thi, trả kết quả có cấu trúc. Khuôn thống nhất giúp thêm tác vụ mới dễ và cho phép chạy từ hộp thoại, dòng lệnh hay lịch tự động.

    Mẫu thiết kế 'lệnh + kết quả' Mẫu thiết kế 'lệnh + kết quả'

    Các bước thực hiện

    1. Định nghĩa lớp cơ sở. validate(), chay(), ten.
    2. Kết quả có cấu trúc. thành công, thông báo, dữ liệu.
    3. Đăng ký tác vụ. Từ điển tên -> lớp.
    4. Bộ chạy chung. Gọi validate, chay, bắt lỗi, in kết quả.
    5. Thêm tác vụ mới. Chỉ cần viết lớp và đăng ký.

    Code tham khảo (Python)

    import NXOpen
    
    class KetQua:
        def __init__(self, thanh_cong, thong_bao, du_lieu=None):
            self.thanh_cong, self.thong_bao, self.du_lieu = thanh_cong, thong_bao, du_lieu or {}
    
    class TacVu:
        ten = "tac_vu"
        mo_ta = ""
        def validate(self, session):
            part = session.Parts.Work
            return None if part is not None else "Chưa có Work Part"
        def chay(self, session):
            raise NotImplementedError
    
    class DemBody(TacVu):
        ten = "dem_body"
        mo_ta = "Đếm body đặc và tấm"
        def chay(self, session):
            part = session.Parts.Work
            dac = sum(1 for b in part.Bodies if b.IsSolidBody)
            tam = sum(1 for b in part.Bodies if b.IsSheetBody)
            return KetQua(True, "Có %d body đặc, %d body tấm" % (dac, tam), {"dac": dac, "tam": tam})
    
    class LietKeExpression(TacVu):
        ten = "liet_ke_expression"
        mo_ta = "Liệt kê expression số"
        def chay(self, session):
            part = session.Parts.Work
            ds = [(e.Name, e.RightHandSide) for e in part.Expressions if e.Type == "Number" and not e.Name.startswith("p")]
            return KetQua(True, "%d expression" % len(ds), {"ds": ds})
    
    DANG_KY = {c.ten: c for c in (DemBody, LietKeExpression)}
    
    def chay_tac_vu(ten, session, lw):
        lop = DANG_KY.get(ten)
        if lop is None:
            lw.WriteLine("Không có tác vụ '%s'. Có: %s" % (ten, ", ".join(DANG_KY)))
            return None
        tv = lop()
        loi = tv.validate(session)
        if loi:
            lw.WriteLine("[%s] Không chạy được: %s" % (ten, loi))
            return KetQua(False, loi)
        try:
            kq = tv.chay(session)
        except Exception as ex:
            kq = KetQua(False, "Lỗi: %s" % ex)
        lw.WriteLine("[%s] %s: %s" % (ten, "OK" if kq.thanh_cong else "LỖI", kq.thong_bao))
        return kq
    
    def main():
        session = NXOpen.Session.GetSession()
        lw = session.ListingWindow
        lw.Open()
        for ten in ("dem_body", "liet_ke_expression", "khong_ton_tai"):
            chay_tac_vu(ten, session, lw)
    
    if __name__ == "__main__":
        main()
    

    Giải thích code

    • Lớp cơ sở TacVu ép mọi tác vụ có cùng hợp đồng: validate rồi chay.
    • KetQua giúp mọi nơi gọi (hộp thoại, log, hàng loạt) xử lý kết quả theo cùng cách.
    • DANG_KY là điểm duy nhất cần sửa khi thêm tác vụ mới; menu có thể sinh ra từ nó.

    Lỗi thường gặp

    • Đừng thiết kế quá tay cho ba tác vụ; mẫu này đáng giá từ khoảng 10 tác vụ trở lên.
    • Mô tả (mo_ta) nên đủ rõ vì thường dùng làm tooltip trong menu.

    Code mang tính tham khảo, viết cho NX 12 trở lên (Python journal). Tên menu và một số lớp có thể khác theo phiên bản NX; hãy chạy thử trên bản sao của chi tiết trước khi dùng cho dữ liệu thật.

    Điểm: 0

Trả lời

Đăng nhập để tham gia thảo luận.