You are on page 1of 9

Phần mềm quản lý công việc của một công ty, trong đó có quản lý nhiều loại nhân viên

(Employee) khác nhau. Nhân viên có thể bao gồm các công nhân (Worker) làm việc tại nhà
máy, nhân viên văn phòng (Staff) làm việc tại văn phòng để phục vụ các nhu cầu liên quan
giấy tờ. Nhân viên kinh doanh (Sale) đi tìm khách hàng. Loại nhân viên cuối cùng là người
quản lý (Manager) để đảm bảo công việc thông suốt
Có hệ thống con SalarySubsystem thực hiện việc trả lương cho tất cả nhân viên. Hệ thống
này có phương thức transfer( ) nhận vào tham số là mảng các nhân viên toàn công ty và trả về
số tiền cần chuyển khoản trong một tháng
Có hệ thống con BonusSubsystem thực hiện việc thưởng doanh thu, hệ thống xác định số
tiền thưởng cho nhân viên. Hệ thống này cũng có phương thức transfer chỉ nhận vào MỘT
tham số là các nhân viên của toàn công ty và trả về số tiền cần dùng để thưởng
Hàng năm, một người quản lý có yêu cầu lập ra danh sách các nhân viên tham gia vào việc
viết báo cáo. Lớp Manager sẽ có PT involveReport( ) trả về danh sách các nhân viên sẽ tham
gia vào việc này. Biết rằng chỉ có Staff hoặc Sale có khả năng viết báo cáo.
a) Vẽ biểu đồ lớp
Nhắc lại các bước để vẽ cho được biểu đồ lớp.
Bước 1: xác định ra các đối tượng có trong phần mềm, từ đó tổng quát hoá lên thành các lớp.
Vậy theo các em thì trong yêu cầu đề, ta xác định ra được đối tượng nào?
Hint: một trong các mẹo nhận dạng các đối tượng, từ đó tổng quát lên thành lớp được đó là
các tên nằm trong dấu ngoặc đơn, viết hoa chữ cái đầu, có thể được in đậm
Các lớp Employee, Worker, Staff, Sale, Manager, SalarySubsystem, BonusSubsystem
Bước 2: xác định ra các thuộc tính và phương thức của các lớp
Gợi ý: để làm được điều này thì chúng ta cần đọc kĩ đề, để xác định ra các lớp có các thông
số gì, có các phương thức gì
Với đề này thì gần như các lớp không có thuộc tính gì cả. Nhưng ta vẫn có thể phát hiện ra
các phương thức của lớp
Chẳng hạn như lớp SalarySubsystem có phương thức long transfer(Employee [ ]). Ở đây SV
có thể khai báo kiểu long hoặc double cho phương thức transfer được. Vì các kiểu long hoặc
double đều có thể dùng làm biểu diễn cho số tiền
Tương tự, các bạn hãy tìm ra hai phương thức nữa có trong đề bài này.
Lớp BonusSubsystem có phương thức long transfer(Employee [ ])
Lớp Manager có phương thức involveReport, phương thức này không có tham số, tuy vậy
kiểu dữ liệu trả về phải là một kiểu mà là mảng (vì đề nói danh sách tham số), và phải thêm
được cả đối tượng của lớp Sale, Staff (vì đề nói có Sale hoặc Staff có khả năng viết báo cáo).
Ta cần nhớ một điều như sau:
(i) Giả sử có lớp A với lớp con của nó là B. Thì ta hoàn toàn làm được việc:
A[ ] array = new A[15]; //Khai báo mảng có 15 đối tượng của lớp A
array[3] = new B( ); //gán giá trị cho phần tử có chỉ số 3 ở mảng array
//và giá trị đó là một đối tượng của lớp B.
(ii) giả sử có giao diện C với lớp B cài đặt nó. Thì ta cũng hoàn toàn làm được việc:
C[ ] array = new C[15]; //Khai báo mảng có 15 đối tượng của giao diện C
array[3] = new B( ); //gán giá trị cho phần tử có chỉ số 3 ở mảng array
//và giá trị đó là một đối tượng của lớp B.
Từ hai điều trên, ta suy ra được kiểu dữ liệu trả về của phương thức involveReport là một
mảng kiểu X. Với X là thứ sẽ được xác định sau, tất nhiên sẽ rơi vào hai trường hợp: (i) X là
đối tượng của lớp mà Staff cùng Sale kế thừa; (ii) X là giao diện mà Staff cùng Sale cài đặt
Chốt lại, lớp Manager sẽ có phương thức X[ ] involveReport( ). Còn X là gì thì ta sẽ xét sau.
Bước 3: xác định các liên kết giữa các lớp
Hiện tại với đề này thì đề không đề cập đến liên kết gì cả giữa các lớp.
Bước 4: xác định xem có giao diện gì hay không?
Có thể có giao diện nếu như X ở bước 2 được xác định là giao diện. Ở đây SV có quyền lựa
chọn khi làm bài; thầy giả sử bạn SV sẽ chọn lựa X là giao diện
Giao diện này sẽ được Staff và Sale cài đặt. Đầu tiên, ta xác định tên của giao diện. Các bạn
có đặt tên theo ý của mình, thử với IReport (chữ I là viết tắt của interface, Report mang hàm
ý đây là những đối tượng có thể viết được report)
Ta có lớp Staff và Sale cài đặt giao diện này
Bước 5: Xác định xem các lớp trừu tượng và mối quan hệ kế thừa
Có một lớp có thể đại diện chung cho mọi nhân viên trong công ty, và lớp này là lớp trừu
tượng Employee.
Các lớp Worker, Manager, Staff, Sale kế thừa lớp Employee này.
SV hãy vẽ biểu đồ lớp đi. Chú ý về các cách biểu diễn cài đặt, kế thừa, biểu diễn lớp trong
biểu đồ UML

Cần sửa thêm 1 số thứ như sau: các thuộc tính nên là private, và để biểu diễn private trong
biểu đồ UML thì ta viết kí hiệu - ở trước tên thuộc tính. Tuy vậy, đề này hiện tại không có
thuộc tính (vì đây là đề cho chúng ta phụ đạo)
Chúng ta cần bổ sung ký hiệu sau vào tên của lớp trừu tượng <<abstract>>, như vậy tên của
lớp trừu tượng Employee sẽ là: <<abstract>> Employee
Khai báo phương thức trong UML thì lại cần để dấu hai chấm sau dấu ngoặc đóng, rồi mới
viết kiểu dữ liệu trả về. Ngoài ra, trong đề nếu không nói rõ thì ta ngầm hiểu mọi phương
thức đều là public
Do đó bạn SV cần sửa lại: (i) abstract, (ii) phương thức ở lớp SalarySubsystem sẽ là
+ transfer(Employee [ ]) : long
Bạn ở trên đang thiếu hai lớp nữa và một giao diện. Giao diện cần bổ sung (như bước 4 phân
tích) có tên là IReport. Nhớ rằng vì nó là một giao diện nên ta cần thêm <<interface>> trước
tên của giao diện. Giao diện đó sẽ được cài đặt bởi lớp Staff và Sale. Ngoài ra phương thức
X[ ] involveReport( ) có kiểu trả về là mảng các X (mà X = IReport). Vậy SV hãy vẽ nốt:
(i) giao diện IReport
(ii) đường nối biểu thị Staff và Sale cài đặt giao diện
(iii) phương thức involveReport không có tham số, public và kiểu trả về là IReport[ ]
Bài 2: Một cửa hàng (Shop) thường bán rau (Vegetable) và thịt (Meat), trong đó rau có thể
là khoai tây (Potato) hoặc cà chua (Tomato). Thịt có thể là gà (Chicken) hoặc lợn (Pig).
Mỗi loại rau được đặc trưng bởi gía tiền trên một kg (cost kiểu double), ngày sản xuất (nsx
kiểu String), hạn sử dụng (hsd kiểu String) và tên các vitamin (vita kiểu String).
Mỗi loại thịt cũng được đặc trưng bởi giá tiền trên kg, ngày sản xuất, ngày hết hạn và loại bio
hay không (isBio kiểu boolean)
Một hệ thống gợi ý nấu ăn (CookingSystem) có PT getList( ) đưa danh sách các nguyên liệu
và khối lượng nguyên liệu. Đầu vào thứ nhất của phương thức là biến kiểu int đặc trưng cho
buổi sáng, trưa, tối (0, 1, 2), đầu vào thứ hai là một mảng kiểu double. Đầu ra là một mảng
kiểu Object.
a) Vẽ biểu đồ lớp
Bước 1: xác định tên các lớp Shop, Vegetable, Meat, Potato, Tomato, Chicken, Pig,
CookingSystem
Bước 2: xác định các thuộc tính và các phương thức
Vegetable, Potato, Tomato (đều là rau) và sẽ có các thuộc tính cost, nsx, hsd, vita
Chicken, Pig, (đều là thịt) và sẽ có các thuộc tính cost, nsx, hsd, isBio
CookingSystem có phương thức + getList(int, double): Object[ ]
Bước 3: xác định mối quan hệ
Shop bán các loại rau, thịt. Nên các lớp Vegetable có liên kết với Shop và mối quan hệ là * -
1 (nhiều - một). Vì cửa hàng bán nhiều rau, còn 1 mới rau thì chỉ có mặt ở một cửa hàng
Bước 4: xác định giao diện
Khi các em đọc kĩ sẽ thấy không có đề cập đến giao diện nào cả.
Bước 5: kế thừa
Lớp Vegetable và lớp Meat đều đại diện cho 1 loại rau thịt nào đó trong cửa hàng. Chúng có
các lớp con cụ thể. Rõ ràng cửa hàng ko thể bán 1 loại rau/thịt không có thông tin cụ thể;
cũng như V, M đều đã có các lớp con cụ thể => Vegetable và Meat đều là các lớp trừu tượng
Potato, Tomato đều là lớp con của Vegetable. Và lớp Chicken, Pig đều là lớp con của Meet
Vẽ biểu đồ lớp?
Các thuộc tính private thì thường sẽ có các phương thức get/set tương ứng.
Như vậy bạn đã vẽ thiếu các pt getCost/setCost, getNsx/setNsx… Đương nhiên viết hết sẽ rất
dài, mất thời gian; do đó thầy đã gợi ý cách viết tắt (chỉ đúng với lớp ta thôi) như sau
+ get…( ): …
+ set…(...): void
Như vậy một lớp nếu có nhiều hơn 1 thuộc tính private thì ta được quyền viết tắt như thế.
Còn lớp Vegetable, có định nghĩa thuộc tính mới vita
ta sẽ phải bổ sung phương thức get/set (phải viết đầy đủ) như sau:
SV sẽ kẻ thêm 1 đường phân tách thuộc tính và phương thức
+ getVita( ): String
+ setVita(String) : void
Còn CookingSystem thì sao, nó ko có thuộc tính nào và có phương thức. Vậy ta vẫn phải kẻ
ra một đường nữa, đường này tạo ra một hình chữ nhật trống ở giữa tên lớp và tên phương
thức

Bài 01 (24/07)
Một hệ thống quản lý giao thông tại ngã tư (Intersection). Tại đó có đèn giao thông (Light) với thông
số về vị trí (pos kiểu String), màu (color kiểu int) và thời gian hiển thị (time kiểu int). Số đèn giao
thông tối đa là 24. Các loại xe được yêu cầu phải dừng ở ngã tư (khi đèn đỏ) là xe máy (Motor), xe
oto (Car). Chỉ có xe khẩn cấp (EmerCar) là một loại xe đặc biệt có thể không cần dừng tại ngã tư. Số
xe được phép dừng tại ngã tư là dưới 150 xe. Nếu có nhiều hơn thì các tài xế sẽ được thông báo về
việc tìm tuyến đường khác (cho dù có phải đi lấn làn)
Các xe đều có thông số về kích thước (dms kiểu String), biển số xe (id kiểu String) và số lốp (tire kiểu
int), vị trí (pos kiểu String), hướng đi (dir kiểu String).
Hệ thống quản lý Management có trách nhiệm điều khiển đèn sáng trong thời gian nào đó. Hệ thống
này có hàm lightOnOff trả về mảng các giá trị true, false. Hàm này nhận tham số là mảng các đèn giao
thông cùng mảng các phương tiện (không gồm xe cấp cứu)
a) Vẽ biểu đồ lớp của hệ thống trên
B1: Xác định các đối tượng từ đó tổng quát lên thành các lớp.
Intersection, Light, Motor, Car, EmerCar, Management
B2: Xác định thuộc tính, phương thức của các lớp?
Light (pos, color, time), Car/Motor/EmerCar (dms, id, tire, pos, dir)
Management có phương thức + lightOnOff(Light [ ], X[ ]): boolean. Với X là một kiểu dữ liệu đại
diện được cho Motor và Car
Bước 3: Xác định liên kết
Có điều cần nhớ: Nếu A liên kết với X mà X lại là lớp cha của Y, Z. Thì điều đó cũng tương đương
với việc A có liên kết với Y và Z.
X có thể đặt tên là Vehicle, với A sẽ là Intersection. Bội số quan hệ là 1 - *
Nếu là * thì chưa đúng, chính xác hơn là một intersection chứa được tối đa 150 xe. Như vậy bội số
quan hệ sẽ phải là 1 - 0..150
Vẫn còn một loại liên kết nữa: Có một lớp với liên kết đến Light, bội số quan hệ trong liên kết đó là
1 - 0..24, đúng. Tuy vậy tên lớp liên kết với Light không phải là Management.
Lớp đó là Intersection. Intersection – Light (1-0..24, thực ra nếu các bạn viết 1-4..24 cũng được)
Bước 4: xác định giao diện
cùng mảng các phương tiện (không gồm xe cấp cứu)
Điều đó có nghĩa Management có phương thức + lightOnOff(Light [ ], X[ ]): boolean. Với X là một
kiểu dữ liệu đại diện được cho Motor và Car, NHƯNG không đại diện cho EmerCar
X có thể là lớp cha của Motor và Car còn EmerCar không kế thừa X.
Nhưng ta vẫn có thể thiết lập X là một giao diện và Motor cùng Car sẽ cài đặt giao diện đó. Ta có thể
đặt tên X là: IStoppingVehicle
Bước 5: lớp trừu tượng. Theo các bạn có lớp trừu tượng nào không?
Có lớp trừu tượng. Nói chung các bạn kiểm tra xem có những lớp nào giống nhau ở một vài phương
thức hoặc thuộc tính hay không? Nếu có, thì ta cần đặt ra một lớp cha chung rồi các lớp (giống nhau
đó) sẽ kế thừa lớp cha chung ấy. Lớp cha chung ấy sẽ là lớp trừu tượng.
Ta có lớp Vehicle là lớp trưù tượng, lớp này được các lớp nào kế thừa? Chúng là EmerCar, Car và
Motor
Hãy vẽ biểu đồ đi?
Hãy sửa cách viết bội số quan hệ
Trong một hội thảo người ta tổ chức cho các sinh viên (Student) hoặc giảng viên
(Lecturer) trình bày một bài báo nào đó (Paper). Sẽ có một hội đồng (Council) hỏi
và đánh giá chất lượng bài báo. Hội đồng này có các giảng viên, sinh viên và khách
mời (Visitor). Tên vai trò của giảng viên, sinh viên và khách mời trong liên kết giữa
hội đồng và những người kia lần lượt là lr, st, vr. Trong hội đồng có từ 3..5 bài báo sẽ
được hội đồng duyệt.
Mỗi thành viên tham gia hội thảo đều phải có thông tin về tên (name), tuổi (age),
CCCD (id), ngoài ra có thể có thể mssv (sid), mã cán bộ (lid) và mã khách mời (vid).
Các bài báo cần có thông tin về tên bài (name), số trang (pgs), danh sách các tác giả
(mảng aut), biết rằng các tác giả có thể là sinh viên hoặc giảng viên hoặc khách mời.
Ngoài ra mỗi sinh viên còn có thể theo học các khóa học (Course) khác nhau, mỗi
khóa học có tối đa 24 SV đăng ký và 01 giảng viên giảng dạy. Tên các vai trò của lớp
Student và Course trong liên kết của chúng lần lượt là s và c. Tên vai trò các lớp
Lecturer và Course trong liên kết của chúng lần lượt là lr và c
a) Hãy vẽ biểu đồ lớp trên
Một ban quản lý xây dựng của phường cần có phần mềm lưu trữ thông tin của các
công trình xây dựng trên địa bàn. Một công trình (Build) có các thông số về diện tích
(sqr kiểu double), số định danh (id kiểu String) và địa chỉ (adr kiểu String) và số
người sống trong công trình (peo kiểu int). Một công trình xây dựng có thể là:
(i) một phòng cụ thể (Room) với thông số về tầng của Room (fls kiểu int).
(ii) Một nhà (Home) là một căn hộ riêng biệt và có thông số về diện tích vườn (grd
kiểu double).
(iii) Một chung cư (Cond) là tập hợp nhiều Room bên trong. Chung cư có thông số về
số tầng (fls) và số lượng Room trong một tầng.
(iv) Khoảng không gian trống (Park) có thêm thông số về tỉ lệ bao phủ cây xanh bên
trong diện tích đó (gre kiểu double).
Ở phường có hai ban kiểm tra độc lập nhau. Một ban kiểm tra (Alpha) chuyên đi kiểm
tra các danh mục trong checkList gồm các chung cư và không gian trống. Một ban
(Beta) chuyên đi kiểm tra các danh mục trong checkList là các công trình còn lại
a) Hãy vẽ biểu đồ lớp mô tả hệ thống kể trên

Người ta muốn xây dựng một phần mềm quản lý giao thông đô thị. Một làn
đường (Lane) có các thông số về id (kiểu String) điểm nguồn (fr kiểu String) và điểm
đến (to kiểu String). Ngoài ra còn có thông số về việc cho phép có lối đi của người đi
bộ hay không (allow kiểu int với giá trị 0 ứng với việc không cho người đi bộ mà chỉ
cho xe di chuyển, 1 ứng với việc chỉ dành cho người đi bộ và 2 ứng với việc cả người
đi bộ và xe đều có thể di chuyển).
Một con đường (Road) có thông số về id (kiểu String) tối đa hai làn đường (L1
và L2 kiểu Lane), và tối thiểu một làn đường, nếu con đường chỉ có một làn thì một
trong hai thuộc tính kia bằng null
Một vạch vượt đường (Cross) nối hai làn đường (L1 và L2 kiểu Lane) với
nhau, hai làn này có thể cùng thuộc một con đường hoặc không. Khác với Road, Cross
bắt buộc hai thuộc tính L1 và L2 đều khác null.
Một loại vạch vượt đường đặc biệt, cũng nối hai làn đường với nhau nhưng
không tiếp đất là cầu vượt (Bridge). Ở loại này, cần có tham số về chiều cao (h kiểu
double) và trọng tải (w kiểu double) của cầu.
Để đảm bảo lối đi cho khách bộ hành, một thành phần con của hệ thống (mang
tên Walking) có nhiệm vụ theo dõi chất lượng của các làn có người đi bộ hoặc các
vạch vượt đường. Thành phần này có phương thức public boolean check với một tham
số là đối tượng kiểu Cross hoặc Bridge hoặc Lane.
Để đảm bảo lối đi cho xe, một thành phần con khác của hệ thống (mang tên
Rolling) có nhiệm vụ theo dõi chất lượng của các đường có xe đi qua. Thành phần này
có phương thức public boolean check với một tham số là đối tượng kiểu Cross (nhưng
không nhận kiểu Bridge làm tham số) hoặc Road.
a) Vẽ biểu đồ lớp UML. (2 điểm)
Thành phần này có phương thức public boolean check với một tham số là đối
tượng kiểu Cross hoặc Bridge hoặc Lane.
=> Chứng tỏ lớp Walking có phương thức check như sau:
+ check(X): boolean
Ta đặt X là kiểu dữ liệu đại diện được cho cả Cross, Bridge và Lane.
Thành phần này có phương thức public boolean check với một tham số là đối
tượng kiểu Cross (nhưng không nhận kiểu Bridge làm tham số) hoặc Road.
=> Lớp Rolling có phương thức check như sau:
+ check(Y) : boolean
trong đó Y là kiểu dữ liệu đại diện được cho cả Cross và Road
Nếu em đã để lớp Road có hai thuộc tính L1, L2 kiểu Lane thì không cần phải biểu
diễn mối quan hệ Road-Lane có bội số 1-2 đâu.
Tương tự với Bridge và Lane, nếu Bridge đã có thuộc tính L1, L2 rồi thì Bridge không
cần có liên kết với Lane đâu.
Liên kết giữa Road và Cross cùng bội số quan hệ 1-* là đúng rồi. Nhưng còn thiếu
quan hệ giữa Road và Bridge, bội số quan hệ của chúng là 1-*
Chúng ta không để Lane làm lớp trừu tượng được. Vì nếu là lớp trừu tượng thì lớp nào
là lớp con của nó? Không có. Khi ấy Road có 2 thuộc tính L1, L2 kiểu Lane và L1 L2
luôn luôn null (do Lane là trừu tượng mà lại không có lớp con)
Nên Lane không thể là lớp trừu tượng được.
Nếu Rolling là lớp trừu tượng thì lớp nào là lớp con? => Không có! Rolling không
phải là lớp cha của lớp Cross đâu.
Bước 4:

b) Cài đặt mã nguồn của lớp Bridge (2 điểm)


public class Bridge extends implements…{

You might also like