22.02.2019 ד"ר עזאם מרעי. יסודות הנדסת תוכנה.. מועד: א'. 202-1-3051 תאריך הבחינה: שם המרצה: שם הקורס: מספר הקורס: שנה: 2019 משך הבחינה: סמסטר: א' 3 שעות הנחיות כלליות: נא לוודא כי בשאלון זה 18 עמודים + 17 עמודים שבנספח. יש לענות על כל השאלות בגוף המבחן בלבד. אין לחרוג מהמקום המוקצה )במקרים חריגים יש לבקש אישור ממרצה / מתרגל(. מומלץ להשתמש במחברת הבחינה כטיוטה. סך הניקוד במבחן הוא 100 כדלהלן: 25 נק' = שאלה 1: בדיקות, מבחני קבלה, TDD ו- XP 25 נק' = שאלה 2: תבניות עיצוב 25 נק' = שאלה :3 Refactoring 25 נק' = שאלה :4 Contract Design by אם אינך יודעים את התשובה, ניתן לכתוב "לא יודע" ולקבל 20% מהניקוד על הסעיף / השאלה. אין לכתוב בעיפרון. )1 )2 )3 )4 )5 1
שאלה [ 1 25 ] בדיקות,(T) מבחני קבלה TDD,(AT) ו- XP א. [ 7 ] AT(,T( TDD, סמנו ליד כל טיעון "נכון" או "לא נכון" אימות )Verification( בודק אם המוצר ממלא את יעדו ביקורת )Inspection( היא שיטה של אימות המטרה של אימות ותיקוף Validation( )Verification and היא שהמוצר נקי לגמרי מבאגים בדיקת קופסה לבנה בודקת את הלוגיקה והיא נעשית אחרי שהמוצר פותח, כחלק מתהליך ה- QA בדיקות יחידה tests( )Unit נכתבות על ידי המתכנתים כך שהבדיקות קשורות לאובייקטים של התוכנה בצורה רופפת. דבר זה יבטיח שאובייקט תכנותי ישפיע על התוצאה של מספר רב של בדיקות יחידה test( system הו( א חלק מבדיקות קופסא שחורה פיתוח מונחה טסטים )TDD( נקרא לעתים גם עיצוב מונחה טסטים, מכיוון שחלק ממהות השיטה היא לעודד עיצוב נכון של קוד.1.2.3.4.5.6.7 [ 5 ] )T( אימות ותיקוף Validation( )Verification and הן שיטות להוכחת המוצר. המטרה היא לייצר אימון במוצר. אימון במוצר תלוי בשלושה גורמים. ציינו את שלושת הגורמים הללו והסבירו אותם Software function.1.2.3 ב. [ 3 ] (AT) הסבירו את הרעיון שעומד מאחורי שיטת המסלול השמח, העצוב והרע )לאיזו מטרה משתמשים בשיטה הזאת וכיצד השיטה אמורה לשרת את המטרה(. ג. 2
[ 3 ] (AT) ציינו שני יתרונות בתבנית של הבדיקות הקבלה למערכת אותה רוצים לבדוק ד. )מערכת מבחני הקבלה( שמטרתה לגשר בין בדיקות (TDD) ציינו שלושה יתרונות של פיתוח בגישת TDD על פני פיתוח בגישה המסורתית. ה. [ 3 ] ] 4 [ (TDD) בדוגמת ה- cash money של קנט בק נעשה שימוש ב- object value שי, מספר משימות בדיקה חדשות לרשימת ה- TODO. ציינו מה הן והסבירו את חשיבותן. ו. מוש שגרר אחריו 3
שאלה.2 [ 25 ] תבניות עיצוב א. [ 8 ] מנהלת "מועדון הקורא המתמיד" החליטה למכן את תהליך החיפוש. הפרויקט כלל את המנשק FrequentReaderLibrary עם שיטה authorname) searchbyname(string ושיטה partialbooktitle),searchbytitle(string ואת המחלקה המממשת.BookSearchEngine בשל הראשון הפרויקט נחל הצלחה. בהמשך היו תלונות על איטיות של החיפוש, ולכן כדי לשפר את מהירות החיפוש, רכש המועדון מנוע חיפוש מהיר במיוחד. מפתחי המערכת בחרו להשתמש בתבנית העיצוב Adaptor על מנת לתת מענה לדרישה. הסבירו, מה הבעיה שעוסקת בה התבנית? הסבירו מדוע השימוש בתבנית מתאים לדרישה המתוארת לעיל. הדגימו את הפתרון בעזרת תרשים מחלקות. לכל מחלקה שציירתם, תנו שם משמעותי בהקשר של המערכת הנ"ל, כתבו בתוכה שדות חשובים ושיטות רלוונטיות לפתרון וציינו מעליה את שם התפקיד בו היא משמשת בתבנית. שימו לב שבסעיף הבא תצטרכו להרחיב את התרשים. 4
ב. [ 5 ] הדרישות של מנוע החיפוש החדש מחייבות להשתמש בו אך רק בצורה מכוונת. למנוע יש שיטה בשם isavailable() המספקת מידע על הזמינות של המנוע. לכן במידה והמנוע החדש אינו זמין, יש דרישה שהחיפוש יתבצע באמצעות המנוע הישן. החיבור למנוע צריך להישאר שקוף, המשתמשים אינם מודעים להחלפת מנוע החיפוש. הציעו תבנית עיצוב לפתרון הבעיה. נמקו את תשובתכם. שלבו את הפתרון בדיאגרמה מן הסעיף הקודם. ג. נתון הקוד הבא: public interface Payment { public void pay(int amount); public class PaypalPayment implements Payment{ private String emailid; private String password; public PaypalPayment(String email, String pwd){ this.emailid=email; this.password=pwd; @Override public void pay(int amount) { System.out.println(amount + " paid using Paypal."); public class CreditCardPayment implements Payment { private String name; private String cardnumber; private String cvv; private String dateofexpiry; 5
public CreditCardPayment(String nm, String ccnum, String cvv, String expirydate){ this.name=nm; this.cardnumber=ccnum; this.cvv=cvv; this.dateofexpiry=expirydate; @Override public void pay(int amount) { System.out.println(amount +" paid with credit/debit card"); public class Item { private String upccode; private int price; public Item(String upc, int cost){ this.upccode=upc; this.price=cost; public String getupccode() { return upccode; public int getprice() { return price; public class ShoppingCard { List<Item> items; public ShoppingCard(){ this.items=new ArrayList<Item>(); public void additem(item item){ this.items.add(item); public void removeitem(item item){ this.items.remove(item); 6
public int calculatetotal(){ int sum = 0; for(item item : items){ sum += item.getprice(); return sum; public void pay(payment paymentmethod){ int amount = calculatetotal(); paymentmethod.pay(amount); public class ShoppingCardTest { public static void main(string[] args) { ShoppingCard card = new ShoppingCard(); Item item1 = new Item("1234",10); Item item2 = new Item("5678",40); card.additem(item1); card.additem(item2); card.pay(new PaypalPayment("myemail@slu.edu", "mypwd")); card.pay(new CreditCardPayment("John A Smith", "1234567890123456", "786", "12/20")); 7 ] 4 [ איזו תבנית מתאר הקוד? נמקו את תשובתכם:
] 2 [ מה הפלט שיתקבל מהקוד? ] 6 ד. [ במערכת מבחני הקבלה שמימשתם במהלך הקורס השתמשנו בשלוש תבניות עיצוב. ציינו מה הן שלוש התבניות והסבירו איזה צורך במבחני הקבלה פותרת כל אחת מהן. ציירו את תרשים המחלקות של מערכת מבחני הקבלה ועבור כל מחלקה בתרשים ציינו את שמה בתוך הריבוע ומעליה את התפקיד/ים אותם היא ממלאה בתבנית. 8
שאלה [ 3 25 ] כללי שכתוב קוד (Refactoring) Replace Inheritance with Delegation [ 8 ] נתון ה- refactoring הבא:.1 A subclass uses only part of a superclasses interface or does not want to inherit data. Create a field for the superclass, adjust methods to delegate to the superclass, and remove the subclassing. איזה ריח רע עשוי להוביל אותנו להפעלת Refactoring זה? נמקו את תשובתכם. נסחו צעדים לביצוע ה- refactoring )מכניקה(. הקפידו על צעדים זהירים. _.1.2.3.4.5 _ 9
[ 5 ] מסעדת האוניברסיטה החליטה להתאים את המחירים על פי סוג הקהלים שמבקרים בה. למשל לסטודנטים, וסגל מנהלי. להלן מופיעה המחלקה.Course המחלקות Student ו- Business הן תתי מחלקות של המחלקה.Customer לכל אחת מהן יש את השיטה.discountPrice() ידוע כי סוגים חדשים של לקוחות צפויים בעתיד..2 public class Course { private double _thedishprice; public double calculateprice(customer customer){ if (customer.isstudent()) { return customer.discountprice(_thedishprice); else{ return customer.discountprice(_thedishprice + customer.getfridaycommision()); ציינו ריח רע אחד בקוד. הסבירו אותו וציינו Refactoring אחד שעוזר לבטל ריח רע זה. [ 6 ] קיים refactoring הופכי ל- Delegation Replace Inheritance with בשם.Replace Delegation with Inheritance א. הסבירו מה המוטיבציה ל- refactoring ההופכי:.3 10 ב. האם קיים מצב בו לא ניתן לבצע את ה- Refactoring הנתון? אם כן הגדירו כתנאי מקדים לשימוש ב- refactoring, אחרת הסבירו מדוע לא. את המצב
double disabilityamount() { if (seniority < 2) { return 0; if (monthsdisabled > 12) { return 0; if (isparttime) { return 0; // compute the disability amount //....4 [ 6 ] נתון הקוד הבא: המפתח ביצע refactoring על הקוד והתקבל הקוד הבא: double disabilityamount() { if (isnoteligablefordisability()) { return 0; // compute the disability amount //... נסחו את ה- refactoring הנ"ל על פי המבנה הבא: שם: מטרה: צעדים לביצוע )מכניקה(:.1.2.3.4.5 11
Design by Contract שאלה [ 4 25 ] Class Sum Expression augend; Expression addend; א. [ 10 ] להלן קוד של המחלקה,Sum addaddend(expression e) Purpose: Adds an addend component to an existing object e of type Expression. Possible only if the addend component does not exist. require: ensure: [ 4 ] השלימו את החוזה עבור השיטה addaddend.1 ] 6 [ הוגדרו שלוש תתי מחלקות למחלקה.Sum עבור כל אחד מהמקרים הבאים הגדירו את תת המחלקה אם הדבר מתאפשר על פי כללי.Design by Contract אם יש צורך להחליש חוזה של פעולה של,Sum עשו זאת, והסבירו. אם אי אפשר להגדיר את תת המחלקה על פי כללי Design by Contract הסבירו למה..2 1. הגדירו את החוזה עבור תת מחלקה MutatedSum של Sum שבה addaugend משוכתב,)overridden( על מנת לאפשר החלפת augend קיים. 12
2. הגדירו את החוזה עבור תת מחלקה MutatedSum של Sum שבה addaugend לא מבצע כלום אם augend כבר קיים הגדירו את החוזה עבור תת מחלקה MutatedSum של Sum שבה הפעלת addaugend מותנית בכך ששני המרכיבים, augend ו- addend, אינם קיימים..3 13
[ 15 ] כתיבת חוזה בשאלה זו עליכם לכתוב חוזה חלקי למחלקה FrequentReaderLibrary משאלה 2. מומלץ לקרוא את כל החוזה לפני שתתחילו לפתור. להלן כמה חוקים שצריך לקיים: ספריית הקורא המתמיד צריכה להחזיק לפחות 1000 ספרים במצב תקין. 1. ספר פגום יוצא מן השימוש או נמסר לתיקון. ספר פגום הוא ספר לא זמין להשאלה. 2. קורא לא יכול להשאיל ספר אם: 3. הספר מושאל, לא זמין או פגום i. הסטטוס של הקורא מוגבל )כלומר, חסום לא יכול להשאיל(.ii חורג מכמות הספרים שמותרת לו.iii ספר רגיל מושאל ל- 7 ימים, ספר שמור ליומיים בלבד 4. ב. class FrequentReaderLibrary features: books: Set[Book] -- Available books for lending notavailablebooks: Set[Book]-- List of books that are not available for use. numberofbooks: Integer-- Number of books owned by the library that are not out of use, MINIMUM 1000 initialize(books : Set[Book]): FrequentReaderLibrary Purpose: creates a library containing the books in the input set getnumberofreservedbooks(): Int Purpose: Returns the number of reserved books in the library borrowbook(abook: Book; areader: LibraryMember): Integer Purpose: borrows the book abook to the reader areader, if possible. The function returns the number of borrowing days according to the statuses of book and the reader. submitbookforrepair(book: Book): void Purpose: submits the book book for repair. The book becomes unavailable. setoutofuse(book:book): void Purpose: sets the status of book. searchbytitle(partialbooktitle: String): Set[Book] Purpose: searches books according to book title. The function returns a set of books. end 14
class Book features: המחלקה Book מספקת את השירותים (features) הבאים: title: String author: String state : STATUS {available, borrowed, underrepair, outofuse Books available for lending are available, borrowed books are borrowed, books under repair are underrepair and books that are out of use are outofuse reserved: Boolean // if the book is reserved, false otherwise reader: LibraryMember// The borrower of the book end getstate(): STATUS Purpose: returns the status of the book isreserved(): Boolean Purpose: returns true if the book is reserved getreader(): LibraryMember Purpose: returns the borrower of the book gettitle(): String Purpose: returns the title of the book isborrowed(): Boolean Purpose: returns true if the book is lent to a reader, false otherwise. המחלקה LibraryMember מספקת את השירותים הבאים Class LibraryMember feature: name: String status: STATUS {Regular, Limited //The status of the reader numberofallowedbooks: Integer // The maximal number of books that a reader can borrow numberofborrowedbooks: Integer// The number of borrowed books getstate(): STATUS Purpose: returns the status of the reader end ] 12 [ פתחו חוזה עבור המחלקה השירות עבור,Set כמו א..FrequentReaderLibrary אפשר להשתמש בפונקציות Set: add(e: Element), contains(e: Element), remove(e: Element), size() 15
class FrequentReaderLibrary initialize(books: Set[Book]): FrequentReaderLibrary Require: Ensure: getnumberofreservedbooks(): Int Require: Ensure: borrow (book: Book, reader: LibraryMember): Integer Require: Ensure: 16
repair (book: Book): void Require: Ensure: setoutofuse(book:book) Require: Ensure: searchbytitle(partialbooktitle: String): Set[Book] Require: Ensure: פקודות חדשות )לא צריך להגדיר עבורם חוזה, רק לציין אותן( 17
] 1 [ כתבו מה האינווריאנטה עבור המחלקה :FrequentReaderLibrary [ 2 ] ב. ג. במנשק )interface( שהתקבל הבחינו בין סוגי השאילתות והפעולות. יש להציג ארבע קבוצות: פעולות רגילות ו- initialization, ושני סוגי שאילתות. בהצלחה! 18