Shallow & Deep Copy in Prototype Design Pattern - PDF

Document Details

IllustriousXylophone

Uploaded by IllustriousXylophone

Kafr El Sheikh University

Tags

shallow copy deep copy prototype design pattern object-oriented programming

Summary

This document explains shallow and deep copy concepts in programming, focusing on the Prototype Design Pattern. It includes example C# code, illustrating how shallow copying affects the original object due to shared memory locations, whereas deep copy creates a completely independent copy. The document distinguishes these two approaches, highlighting the importance of memory management in object-oriented design.

Full Transcript

# Shallow Copy and Deep Copy in Prototype Design Pattern ## Introduction to Creational Patterns - **Singleton Pattern** - Ensures a class has only one instance and provides a global point of access to it. - **Factory Method Pattern** - Defines an interface for creating an object, but lets s...

# Shallow Copy and Deep Copy in Prototype Design Pattern ## Introduction to Creational Patterns - **Singleton Pattern** - Ensures a class has only one instance and provides a global point of access to it. - **Factory Method Pattern** - Defines an interface for creating an object, but lets subclasses decide which class to instantiate. - **Abstract Factory Pattern** - Provides an interface for creating families of related or dependent objects without specifying their concrete classes. - **Builder Pattern** - Separates the construction of a complex object from its representation so that the same construction process can create different representations. - **Prototype Pattern** - Specifies the kind of object to create using a prototypical instance, and creates new objects by copying this prototype. ## Prototype Design Pattern ### What is the Prototype Design Pattern? - The Prototype Design Pattern is a creational design pattern that allows objects to be created by cloning an existing object, rather than creating a new object from scratch. ### Advantages of the Prototype Design Pattern - The Prototype Design Pattern can help improve performance, reduce object creation time, and simplify the creation of complex objects by allowing them to be easily copied. ### Use Cases of the Prototype Design Pattern - The Prototype Design Pattern is commonly used in scenarios where you need to create objects with complex configurations, such as in game development, image processing, and configuration management systems. ### The Prototype Design Pattern is a powerful and flexible design pattern that can help simplify object creation and improve performance in various software development scenarios. ## Understanding Shallow Copy - Shallow copy is a method of creating a new object that references the same underlying data as the original object. - This means that when you modify the new object, the original object is also affected, as they share the same memory location. ## Understanding Deep Copy - Deep Copy is a concept in programming where a duplicate of an object is created, with all its properties and values being independently copied. - This means that any changes made to the copy will not affect the original object, providing a completely separate and independent version. ## Shallow Copy Example: **Code of the Program:** ```C# class Person { public string Name { get; set; } public int age { get; set; } public Address Address { get; set; } // Reference type field // Shallow copy method using MemberwiseClone() public Person ShallowCopy() { return (Person)this.MemberwiseClone() } public void Display() { Console.WriteLine($"Name: {Name}, Age: {Age}, City: {Address.City}"); } } class Address { public string City { get; set; } public Address(string city) { City = city; } } static void Main() { // Create a new person with a reference to an Address object Person person1 = new Person { Name = "Alice", Age = 25, Address = new Address("New York") } // Perform a shallow copy Person personCopy = person1.ShallowCopy(); // Display original and copied person details Console.WriteLine("Original Person:"); person1.Display(); Console.WriteLine("Shallow Copy Person:"); personCopy .Display(); // Modify the original object's Address and Name person1.Name = "Bob"; person1.Address.City = "Los Angeles"; // Display the result after modification Console.WriteLine("\nAfter modifying the original:"); Console.WriteLine("Original Person:"); person1.Display(); Console.WriteLine("Shallow Copy Person:"); personCopy .Display(); } ``` **Explanation of the Program:** 1. **Person class** - Has properties for `Name`, `Age`, and an `Address` object (which is a reference type). - The `ShallowCopy` method uses the built-in `MemberwiseClone()` method, which creates a shallow copy of the current object. 2. **Address class:** - A simple class that holds the city information. 3. **Main Program** - Creates an instance of `Person` with a reference to an `Address` object. - Creates a shallow copy using the `ShallowCopy` method. - After modifying the original `person1`, both `person1` and `personCopy` share the same `Address` object, but their `Name` fields are independent. **Output of the Program:** ``` Original Person: Name: Alice Age: 25 City: New York Shallow Copy Person: Name: Alice Age: 25 City: New York After modifying the original: Original Person: Name: Bob Age: 25 City: Los Angeles Shallow Copy Person- Name: Alice Age: 25 City: Los Angeles ``` **Explanation of Results:** - After performing a shallow copy, both `person1` and `personCopy` share the same reference to the `Address` object. Therefore, changing `person1`'s `Address.City` also affects `personCopy`. - However, the `Name` field is a value type (string is immutable in C#), so changing the `Name` in `person1` does not affect `personCopy`. **Key Points** - Shallow Copy: In C#, shallow copying copies the reference to reference-type members (like `Address`), not the actual object. Hence, changes to reference-type members in the original object will affect the copy and vice versa. - MemberwiseClone: A built-in C# method that creates a shallow copy of the object. For a deep copy, you would need to manually copy each reference-type member. ## Deep Copy Example **Code of the Program:** ```C# using System; class Person { public string Name { get; set; } public int Age { get; set; } public Address Address { get; set; } // Reference type field // Deep copy method public Person DeepCopy() { Person clonedPerson = (Person)this.MemberwiseClone(); clonedPerson.Address = new Address(this.Address.City); // Deep copy the Address return clonedPerson; } public void Display() { Console.WriteLine($"Name: {Name}, Age: {Age}, City: {Address.City}"); } } class Address { public string City { get; set; } public Address(string city) { City = city; } } static void Main() { // Create a new person with a reference to an Address object Person person1 = new Person { Name = "Alice", Age = 25, Address = new Address("New York") } // Perform a deep copy Person personCopy = person1.DeepCopy(); // Display original and copied person details Console.WriteLine("Original Person:"); person1.Display(); Console.WriteLine("Deep Copy Person:"); personCopy.Display(); // Modify the original object's Address and Name person1.Name = "Bob"; person1.Address.City = "Los Angeles"; // Display the result after modification Console.WriteLine("\nAfter modifying the original:"); Console.WriteLine("Original Person:"); person1.Display(); Console.WriteLine("Deep Copy Person:"); personCopy.Display(); } ``` **Explanation of the Program:** 1. **Person.DeepCopy method:** - Performs a shallow copy of the `Person` object using `MemberwiseClone()`. - Then, we create a new `Address` object and copy the `City` value to ensure a deep copy of the `Address` object. This ensures that the copied `Person` has its own separate `Address` object. 2. **Address class:** - Remains the same, with a `City` property. 3. **Main Program:** - We create an instance of `Person` with a reference to an `Address` object. - We perform a deep copy using the `DeepCopy` method, ensuring that the new object has a separate `Address` instance. - When modifying `person1`, the changes will not affect `personCopy`. **Output of the Program:** ``` Original Person: Name: Alice Age: 25 City: New York Deep Copy Person: Name: Alice Age: 25 City: New York After modifying the original: Original Person: Name: Bob Age: 25 City: Los Angeles Deep Copy Person: Name: Alice Age: 25 City: New York ``` ## Choosing the Right Copy Mechanism | Concept | Description | |---|---| | Shallow Copy | A shallow copy creates a new object that has a reference to the same elements as the original object. This means that any changes made to the new object will also affect the original object. | | Deep Copy | A deep copy creates a new object with a completely independent set of data. Any changes made to the new object will not affect the original object. | | Object Type | Consider the type of objects you are working with. Shallow copy may be sufficient for simple objects, but deep copy is necessary for complex objects with nested data structures. | | Performance | Deep copy can be more computationally expensive than shallow copy, as it requires creating a new object from scratch. Use shallow copy when possible to improve performance. | | Memory Usage | Deep copy requires more memory as it creates a new object, while shallow copy only creates a new reference. Consider the memory constraints of your application when choosing the appropriate copy mechanism. | ## Real-world Applications | Diagram | Description | |---|---| | Duplicating Files in File Systems | Shows how files can be copied with a deep copy mechanism | | Copying Data in Databases |Shows how data can be copied with a deep copy mechanism | | Cloning Virtual Machines | Shows how virtual machines can be cloned with a deep copy mechanism | | Duplicating Game Levels | Shows how game levels can be duplicated with a deep copy mechanism | ## Creational Pattern: Factory Design Pattern # Factory Design Pattern: - The Factory Design Pattern is a creational design pattern that provides an interface for creating objects in a superclass but allows subclasses to alter the type of objects that will be created. - **Example use cases:** - Payment methods - Animals creation in a game - The diagram below shows how this pattern applies to payment methods. ## Factory Design Pattern Diagram - There is a Client. - The client interacts with `PaymentFactory` which provides the interface to create new payment methods. - The interface `IPayment` is implemented by several payment methods: - `CreditCardPayment` - `PayPalPayment` - `GooglePayPayment` ## Code of the Program: **IPayment Interface:** ```C# using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace FactoryPattern { public interface IPayment { void Pay(double amount); } } ``` **CreditCardPayment Class:** ```C# public class CreditCardPayment : IPayment { public void Pay(double amount) { Console.WriteLine($"Successfully paid ${amount} to merchant using a Credit Card."); } } ``` **PayPalPayment Class:** ```C# public class PayPalPayment : IPayment { public void Pay(double amount) { Console.WriteLine($"Successfully paid ${amount} to merchant using a Credit Card."); } } ``` **GooglePayPayment Class:** ```C# public class GooglePayPayment : IPayment { public void Pay(double amount) { Console.WriteLine($"Successfully paid ${amount} to merchant using Google Pay."); } } ``` **PaymentMethod Enum:** ```C# public enum PaymentMethod { CreditCard, PayPal, GooglePay } ``` **PaymentFactory Class:** ```C# using System.Linq; using System.Threading.Tasks; namespace FactoryPattern { public class PaymentFactory { public static IPayment create(PaymentMethod paymentMethod) { switch (paymentMethod) { case PaymentMethod.CreditCard: return new CreditCardPayment(); case PaymentMethod.PayPal: return new PayPalPayment(); case PaymentMethod.GooglePay: return new GooglePayPayment(); default: throw new NotSupportedException( $"{paymentMethod} is not currently supported as a payment method."); } } } } ``` **Main Program:** ```C# using FactoryPattern; // See https://aka.ms/new-console-template for more information // Payment payment = PaymentFactory.create(PaymentMethod.PayPal); payment.Pay(1000.00); ``` **Output:** ``` Successfully paid $1000 to merchant using PayPal. ``` **Explanation of the Code:** - `IPayment` is the interface that defines the common method `Pay` that is used by all payment methods. - The payment method classes `CreditCardPayment`, `PayPalPayment`, and `GooglePayPayment` implement the `IPayment` interface and provide specific implementation for the `Pay` method. - The `PaymentMethod` enum defines all the available payment methods - The `PaymentFactory` class has a static method `create` that takes a `PaymentMethod` enum as an argument and returns an instance of the corresponding payment method. - The main program demonstrates how to use the `PaymentFactory` to create a payment method and call its `Pay` method. This example program demonstrates how the Factory Design Pattern allows you to abstract the creation of objects from the client code. This makes the client code more flexible and easier to maintain, as it does not have to be aware of the specific payment methods.

Use Quizgecko on...
Browser
Browser