Presentation is loading. Please wait.

Presentation is loading. Please wait.

Introductory Software Engineering with a Focus on Dependency Management Christine Hofmeister.

Similar presentations


Presentation on theme: "Introductory Software Engineering with a Focus on Dependency Management Christine Hofmeister."— Presentation transcript:

1 Introductory Software Engineering with a Focus on Dependency Management Christine Hofmeister

2 Software Engineering Course Constraints  At East Stroudsburg University, the Software Engineering course is completed in the 3 rd or 4 th year of undergraduate study.  Only one semester course (3 credits):  3 hours of instruction per week  14 weeks  Typical student expertise before this course:  writing programs (not systems!)  ad-hoc testing.

3 Why Focus on Dependency Management?  Problem:  Students need to learn the challenges of large-scale development, yet most have had little experience with even small-scale development.  Solution:  Focus on design, since that is closest to the code.  Focus on dependency management, since dependencies are fundamental to design.

4 Approach  Key techniques for dependency management:  Interfaces (for static dependencies)  Factory design pattern (for object creation dependencies).  Use UML models to reveal dependencies:  Students learn to abstract key design details into a model.  Models reveal how interfaces and factory patterns remove dependencies.

5  FlexibleHello1:  Creates a Name object, either with an Encryptor or not.  Calls Name’s firstName() and lastName() methods, and prints the result.  Name:  Creates two Message objects: _textin and _textout.  Methods firstName() and lastName() do the following:  Use _textout to set and show the prompt.  Use _textin to capture the user’s input, which is returned to the caller. Hello Example: Version 1

6  Message:  setMessage(): saves the message string (saves it encrypted, if applicable).  showMessage(): displays the current message string (decrypted, if applicable) on the console.  readMessage(): reads a string from the console and returns it (encrypted, if applicable). (We don’t decrypt in this case simply because we want to see which version of Message was used.) Hello Example (Version 1 cont.)

7  FlexibleHello1 knows about all the variants of Message that exist.  For the plain text variant, it uses 0 as the Encryptor*.  For the secure text variant, it creates an Encryptor.  FlexibleHello1 passes the Encryptor* to Name.  Name does not know about the Message variants.  Name simply passes the Encryptor* when it constructs its Message objects.  Message is capable of using both plain text and encrypted messages.  It uses the Encryptor* object if available (if it’s non-null). V1: FlexibleHello Dependencies

8  To add a third kind of Message, numerous code changes are required:  Modify Message to handle 3 variants instead of 2.  Modify main() to pick one of the 3 variants and pass a flag to Name.  Modify Name to pass the variant flag to Message.  Students also see that the Encryptor object was doing double duty, both as a flag to pick the variant and as the object itself. Student Lab Exercise: Add LoudMessage (all caps)

9  Instead of making the Message class handle multiple message variants, create a separate class for each variant.  Hide these message variants behind interface IMessage. Improvement: Use an Interface

10  C++ is the language used for this course:  It’s a prevalent, mainstream language.  It’s a rich language:  Two kinds of variable declarations.  No garbage collection.  Two kinds of method binding.  No interface support.*  Methods can exist outside of classes. These “features” make it an excellent vehicle for teaching polymorphism, interfaces, factory patterns, libraries, and linking. * Note that sometimes the class declaration in the.h file is called the class’s “interface.” This is not a true interface. Implementation Language: C++

11  In C++ we create an interface by using an abstract class with only abstract public operations.  Example of interface in C++: class IMessage { public: virtual void setMessage(std::string) = 0; virtual void showMessage() = 0; virtual std::string readMessage() = 0; virtual ~IMessage() {} }; Interfaces in C++

12  Create two separate message classes: Message and SecureMessage. The Encryptor is now encapsulated in SecureMessage.  Provide an interface to the message classes (IMessage).  FlexibleHello2 (main()) chooses which variant of IMessage is used, creates the IMessage object and passes it to Name. V2: Hello Example with Interfaces

13  To add a third kind of message, students see that no changes are needed for Name.  However, since Name requires two message objects,  FlexibleHello2 must create both and pass both objects to Name.  FlexibleHello2 could create two different kinds of messages to pass to Name.  The fundamental problem is that Name should create the IMessage objects, but to do so it needs to call the appropriate constructor. Student Lab Exercise: Add LoudMessage to V2

14 (a.k.a. Abstract Factory design pattern in Design Patterns: Elements of Reusable Object-Oriented Software, Gamma, Helm, Johnson, Vlissides. Addison-Wesley 1995.)  Use a class factory when the creator of an object does not know what kind of object to create.  A class factory separates the decision of which object to create from the actual creation of the object.  A class factory is a class that simply creates objects, e.g.: MessageFactory::MessageFactory(){ } MessageFactory::~MessageFactory(){ } IMessage* MessageFactory::newMessage() { return new Message(); }  Different class factories create different kinds of objects. Class Factory

15  Name uses only the interfaces IMessageFactory and IMessage, even though the objects it accesses via these interfaces are really either MessageFactory and Message or SecureMessageFactory and SecureMessage. V3: Hello Example with Class Factory main() picks (creates) the Factory. Name uses the IMessageFactory to create an IMessage object (without knowing exactly what type of object it is creating).

16  To add a third kind of message, students must provide a new class: LoudMessageFactory.  To switch to another kind of message, students must  edit FlexibleHello3.cpp to call the constructor for the appropriate factory  rebuild the application. Student Lab Exercise: Add LoudMessage to V3

17  Idea:  For each interface, provide a C++ method (not part of a class) that creates an object of the desired class.  Because it’s a C++ method, the linker matches the declaration to the definition it is given. V4: Hello Example with Factory Method IMessage* NewMessage(); IMessage* NewMessage() { return new SecureMessage(); } IMessage* NewMessage() { return new Message(); }

18 Comparison of Factory Patterns

19  The class factory (V3) is used to create a coherent set of objects for a variant.  CatFactory creates PetCat and FoodCat  DogFactory creates PetDog and FoodDog  The factory method (V4) is used on the class factory to allow us to select different factories at link time.  At runtime, link in one of these:  Cat.lib (contains CatFactory, PetCat, and FoodCat)  Dog.lib (contains DogFactory, PetDog, and FoodDog) Maximum Flexibility: Combine Both Factory Patterns

20 Evaluation  Dependency management focus motivated by my prior 7 years in industry:  Projects needed interfaces but didn’t have them.  Factory design pattern was essential in one family of systems.  Course has evolved over the course of 14 years.  Students value the content:  Survey comments  Exit interviews  Spontaneous feedback

21 Numeric Course Evaluations

22 Summary  Dependency management:  Interfaces are used to control call-dependencies, and by using C++ (which has no native interface), student learn exactly how an interface differs from a class.  Factories are used to control creation dependencies, by enabling object creation while hiding the type of object being created.  Through their UML modeling work, the students:  Learn the UML language.  Reinforce their understanding of object-oriented design concepts, because they are abstracting these aspects of the code.  Develop a deeper understanding of C++ language features, e.g. static vs. dynamic memory allocation, the meaning of the ‘static’ keyword, virtual vs. non-virtual methods, and the meaning of ‘pure virtual’.  Learn to recognize design idioms, e.g. when interfaces and/or factory patterns are used.


Download ppt "Introductory Software Engineering with a Focus on Dependency Management Christine Hofmeister."

Similar presentations


Ads by Google