I am considering this example Factory Design Pattern Suppose I have 2 clients using this notification library the code for respective clients will look like this in the below cases.
Case 1: Without factory pattern
Client 1
SMSNotification notification = new SMSNotification();
notification.notifiyUser();
Client 2
EmailNotification notification = new EmailNotification();
notification.notifiyUser();
Case 2: With the Factory pattern
Client 1
Notification notification = notificationFactory.createNotification("SMS");
notification.notifiyUser();
Client 2
Notification notification = notificationFactory.createNotification("Email");
notification.notifiyUser();
So now if suppose the notification team adds a new notification system in their library and if suppose client 2 wants to include that then in case 1 I have to change the concrete class name and in case 2 I have to change the string value to the new value, so in both the cases anyhow I have to make changes.
How is the Factory design pattern helping?
You can make the "SMS" or "Email" String be read out of an external property file.
Then you can configure your factory without having to recompile your project.
We also use a design principle called Separation of concerns SoC. There can be multiple "concerns" to separate, for example, business logic and data retrieval.
One of SoC is separating Configuration and Application logic. Applying this, We can configure our application's behaviour which can be super helpful.
For example, We can have the same application code running on our test environment and production environment, with the only difference being the configuration. In your example, we can have a "Fake-email" factory running on the test environment that prevents us from sending unwanted emails to our actual clients (True Story).