1 / 22

Introductory Software Engineering w ith a Focus on Dependency Management

Introductory Software Engineering w ith a Focus on Dependency Management. Christine Hofmeister. Software Engineering Course Constraints. At East Stroudsburg University, the Software E ngineering course is completed in the 3 rd or 4 th year of undergraduate study.

violet-pope
Download Presentation

Introductory Software Engineering w ith a Focus on Dependency Management

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

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 3rd or 4th 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. Hello Example: Version 1 • 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.

  6. Hello Example (Version 1 cont.) • 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.)

  7. V1: FlexibleHello Dependencies • 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).

  8. Student Lab Exercise: Add LoudMessage (all caps) • 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.

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

  10. Implementation Language: C++ • 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.

  11. Interfaces in C++ • 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() {} };

  12. V2: Hello Example with Interfaces • 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 IMessageobject and passes it to Name.

  13. Student Lab Exercise: Add LoudMessage to V2 • 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.

  14. Class Factory (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.

  15. 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). • 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.

  16. Student Lab Exercise: Add LoudMessage to V3 • 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.

  17. V4: Hello Example with Factory Method • 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. IMessage* NewMessage() { return new Message(); } IMessage* NewMessage(); IMessage* NewMessage() { return new SecureMessage(); }

  18. Comparison of Factory Patterns

  19. Maximum Flexibility: Combine Both Factory Patterns • 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)

  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.

More Related