Tech Point Fundamentals

Friday, April 29, 2022

Design Patterns Interview Questions - Part 09

Design Patterns Interview Questions and Answers - Part 09

design-pattern-interview-questions

In Software Industry the Design Patterns and Principles are always followed. So this is the most common topic for the interview. In this article, we will see the most frequently asked 90+ Design Patterns and Principles Interview Questions with Answers

Please visit our YouTube Channel for Interviews and other videos by below link:


Please read the complete C# Interview Questions and Answers article series here.



Introduction


This is the 9th part of this Design Patterns and Principles Interview Questions and Answers article series. Each part contains five Design Pattern Interview Questions. Please read all the Design Patterns and Principles Interview Questions list here.

I will highly recommend to please read the previous parts over here before continuing the current part:





Design Patterns Interview Questions - Part 09


Q65. Why Singleton Classes are sealed? What is the difference between a Singleton Pattern and Singleton Object?

We know that a private constructor prevents the subclassing then why the singleton class should be sealed or final. So there are two reasons and both are to prevent subclassing or inheritance. 

1. If you define only default private constructor, it prevents both instantiation and subclassing but if any developer created any public constructor accidentally other classes can do instantiate and extend both. Which is a violation of the singleton design pattern.

2. The private default constructor cannot prevent the nested class (inner class) of the singleton from extending. Which is a violation of the singleton design pattern again.

So they can cause a trivial problem to the singleton design pattern goal. That's why we should make the singleton class sealed. 

Please read more about the sealed class here and the private constructor here.



Singleton Pattern vs Singleton Object:

Different IoC containers like Autofac, Ninject, etc also control the lifetime and scope of a registered object for example singleton (one instance for the duration of the application), transient (new instance each time), or scoped (one instance per scope).

So here we are not creating any singleton pattern explicitly, everything is taken care of by the IoC container. We can still use the singleton object in our project and in fact, everyone has used these in the projects.

Please read more about DI and IoC here.



Q66. What are the Structural Design Patterns (SDP)? What are the different Structural Design Patterns?

These design patterns are about organizing different classes and objects to form larger structures and provide new functionality. Structural patterns explain how to assemble objects and classes into larger structures while keeping these structures flexible and efficient.

This design pattern concerns class and object composition. The concept of inheritance is used to compose interfaces and define ways to compose objects to obtain new functionalities.



Following are the common structural design patterns:

  1. Adapter Pattern: This allows for two incompatible classes to work together by wrapping an interface around one of the existing classes.
  2. Bridge Pattern: This pattern decouples an abstraction so two classes can vary independently.
  3. Composite Pattern: This pattern takes a group of objects into a single object.
  4. Decorator Pattern: This allows for an object’s behavior to be extended dynamically at run time.
  5. Facade Pattern: This pattern provides a simple interface to a more complex underlying object.
  6. Flyweight Pattern: This pattern reduces the cost of complex object models.
  7. Proxy Pattern: This pattern provides a placeholder interface to an underlying object to control access, reduce cost, or reduce complexity.



Q67. What is Adapter Design Pattern (ADP)? When to use the Adapter Structural Design Pattern?

The Adapter Design Pattern works as a bridge between two incompatible interfaces. An adapter is a structural design pattern that allows objects with incompatible interfaces to collaborate. This design pattern involves a single class called adapter which is responsible for communication between two independent or incompatible interfaces.

You can create an adapter. This is a special object that converts the interface of one object so that another object can understand it. An adapter wraps one of the objects to hide the complexity of conversion happening behind the scenes. The wrapped object isn’t even aware of the adapter.



Types of Adapter Patterns:

Object Adapter Pattern: An Object Adapter delegates to an adaptee object. This implementation uses the object composition principle: the adapter implements the interface of one object and wraps the other one. It can be implemented in all popular programming languages.

Class Adapter Pattern: In this approach, the Adapter calls the methods inherited from the Adaptee class. So this implementation uses inheritance. The adapter inherits interfaces from both objects at the same time. Note that this approach can only be implemented in programming languages that support multiple inheritances, such as C++.



Component of Adapter Pattern:

Target Interface: It is an interface and this interface needs to be implemented by the Adapter and the client can see only this interface.

Adapter Class: The Adapter class implements the Trager interface and provides the implementation for the service methods. This is a class that makes two incompatible systems work together.  This class is also composed of the Adaptee i.e. it has a reference to the Adaptee object.

Adaptee: This class contains the functionality that the client requires but it’s not compatible with the existing client code. So, it requires some adaptation before the client code can use it. It means the client will call the Adapter and the Adapter will do the conversion if required and then it will make a call to the Adaptee.

Client: The Client class can only see the Target interface.



Use of Adapter Pattern:

  1. Use the Adapter class when you want to use some existing class, but its interface isn’t compatible with the rest of your code.
  2. Use the pattern when you want to reuse several existing subclasses that lack some common functionality that can’t be added to the superclass.
  3. Adapter Pattern allows a system to use classes of another system that is incompatible with it. It also allows communication between a new and already existing system that is independent or incompatible with each other.
  4. The adapter pattern can follow the Single Responsibility Principle. You can separate the interface or data conversion code from the primary business logic of the program.
  5. This also follows the Open/Closed Principle. You can introduce new types of adapters into the program without breaking the existing client code, as long as they work with the adapters through the client interface.



Q68. What is Bridge Design Pattern (BDP)?

A bridge is a structural design pattern that lets you split a large class or a set of closely related classes into two separate hierarchies: abstraction and implementation—which can be developed independently of each other. 

The Bridge Design Pattern separates the abstraction hierarchy and the implementation hierarchy into two different layers so that change in one hierarchy will not affect the development or functionality of another hierarchy.

According to GoF, the Bridge Pattern “Decouples an abstraction from its implementation so that the two can vary independently“. The GoF book introduces the terms Abstraction and Implementation as part of the Bridge definition. 

Abstraction is a high-level control layer for some entities. This layer isn’t supposed to do any real work on its own. It should delegate the work to the implementation layer (also called platform). 



In the bridge design pattern, there are 2 parts. The first part is the abstraction and the second part is the implementation. The bridge design pattern allows the abstraction and implementation to be developed independently and the client code can access only the abstraction part without being concerned about the implementation part.

Use of Bridge Pattern:

  1. Use the Bridge pattern when you want to divide and organize a monolithic class that has several variants of some functionality
  2. Use the pattern when you need to extend a class in several orthogonal (independent) dimensions.
  3. Use the Bridge if you need to be able to switch implementations at runtime.
  4. You can create platform-independent classes and apps. The client code works with high-level abstractions. It isn’t exposed to the platform details.
  5. The bridge pattern follows the Single Responsibility Principle. You can focus on high-level logic in the abstraction and on platform details in the implementation.
  6. The bridge pattern also follows the Open/Closed Principle. You can introduce new abstractions and implementations independently from each other.




Q69. What is Composite Design Pattern (CDP) or Tree Pattern?

Composite is a structural design pattern that lets you compose objects into tree structures and then work with these structures as if they were individual objects. Using the Composite pattern makes sense only when the core model of your app can be represented as a tree.

According to GoF, the Composite Design Pattern states that “Compose objects into tree structures to represent part-whole hierarchies. Composite let clients treat individual objects and compositions of objects uniformly”. 

The Composite Design Pattern allows us to have a tree structure and ask each node in the tree structure to perform a task. The Composite Pattern is used where we need to treat a group of objects in a similar way as a single unit object.



A composite object is an object which contains other objects. A composite component may also contain other composite objects. The object which does not contain any other objects is simply treated as a leaf object.

Use of Composite Pattern:

  1. Use the Composite pattern when you have to implement a tree-like object structure.
  2. Use the pattern when you want the client code to treat both simple and complex elements uniformly.
  3. It follows the  Open/Closed Principle. You can introduce new element types into the app without breaking the existing code, which now works with the object tree.




Q70. What is Decorator Design Pattern (DDP) or Wrapper Pattern? When to use the Decorator Structural Design Pattern?

The Decorator Design Pattern in C# allows us to dynamically add new functionalities to an existing object without altering or modifying its structure and this design pattern acts as a wrapper to the existing class. This design pattern dynamically changes the functionality of an object at runtime without impacting the existing functionality of the objects.

A decorator is a structural design pattern that lets you attach new behaviors to objects by placing these objects inside special wrapper objects that contain the behaviors.

The Decorator Design Pattern provides an alternative approach to inheritance for modifying the behavior of an object. When we use inheritance to extend the behavior of a class, then this takes place at compile time.

Use the Decorator pattern when you need to be able to assign extra behaviors to objects at runtime without breaking the code that uses these objects. Use the pattern when it’s awkward or not possible to extend an object’s behavior using inheritance.



Decorator Pattern vs Inheritance:

Extending a class is the first thing that comes to mind when you need to alter an object’s behavior. But inheritance has several serious caveats:

Inheritance is static. You can’t alter the behavior of an existing object at runtime. You can only replace the whole object with another one that’s created from a different subclass.
Subclasses can have just one parent class. In most languages, inheritance doesn’t let a class inherit behaviors of multiple classes at the same time.

One of the ways to overcome these caveats is by using Aggregation or Composition instead of Inheritance. Both of the alternatives work almost the same way: one object has a reference to another and delegates it some work, whereas, with inheritance, the object itself is able to do that work, inheriting the behavior from its superclass.



Q71. What is Proxy Design Pattern (PDP)? When to use the Proxy Structural Design Pattern?

Proxy is a structural design pattern that lets you provide a substitute or placeholder for another object. A proxy controls access to the original object, allowing you to perform something either before or after the request gets through to the original object. 

A proxy pattern is used when we need to create a wrapper to cover the main object’s complexity from the client. We can define a proxy as a class functioning as an interface to something else.

According to the GoF, the Proxy Design Pattern provides a surrogate (act on behalf of other) or placeholder for another object to control the access to it. Proxy means ‘in place of‘ or ‘representing‘ or ‘on behalf of‘.

Proxy means an object representing another object. A Proxy Pattern "provides the control for accessing the original object". A proxy pattern is also known as a Surrogate or Placeholder.

We can also say that the Proxy is the object which is being called by the client to access the real object behind the scene. That means, In Proxy Design Pattern, a class represents the functionality of another class.



Types of Proxy:

Virtual Proxy: A virtual proxy is a placeholder for “expensive to create” objects. The real object is only created when a client first requests or accesses the object. These proxies initiate the operation on real objects and provide a default result to the application. Once the real object is done, these proxies push the actual data to the client where it has provided dummy data earlier.

Remote Proxy: They are responsible for representing the object located remotely. A remote proxy provides local representation for an object that resides in a different address space. All that logic is encapsulated in these proxies and the client application need not worry about them.

Protection Proxy: A protection proxy control access to a sensitive master object. The surrogate object checks that the caller has the access permissions required prior to forwarding the request. If an application does not have access to some resource then such proxies will talk to the objects in applications that have access to that resource and then get the result back.

Smart Proxy: A smart proxy provides an additional layer of security by interposing specific actions when the object is accessed. For example, to check whether the real object is locked or not before accessing it so that no other objects can change it.



Adapter vs Decorator vs Proxy:

The adapter provides a different interface to its subject. Proxy provides the same interface. The decorator provides an enhanced interface.

Decorator and Proxy have different purposes but similar structures. Both describe how to provide a level of indirection to another object, and the implementations keep a reference to the object to which they forward the request.

Use of Proxy Pattern:

  1. A proxy pattern is used to add secure access to an existing object. The proxy will determine if the client can access the object of interest.
  2. The proxy can provide a simple API so that the client code does not have to deal with the complexity of the object of interest.
  3. It is used for providing interfaces for remote resources such as web service or REST resources.



Q72. What is Façade Design Pattern (FDP)? What is the difference between Façade and Mediator?

A facade is a structural design pattern that provides a simplified interface to a library, a framework, or any other complex set of classes.

Provide a unified interface to a set of interfaces in a subsystem. A facade defines a higher-level interface that makes the subsystem easier to use. It wraps a complicated subsystem with a simpler interface.

According to the GoF, the Façade Design Pattern states that you need to provide a unified interface to a set of interfaces in a subsystem. The Façade Design Pattern defines a higher-level interface that makes the subsystem easier to use.



Facade Design Pattern is used to hide the complexities of a system and provides an easy-to-use interface to the client using which the client can access the system. The Façade (usually a wrapper) sits on the top of a group of subsystems and allows them to communicate in a unified manner.

The Façade class knows which subsystem classes are responsible for a given request and then it delegates the client requests to appropriate subsystem objects.
The Subsystem classes Implement their respective functionalities assigned to them and these subsystems do not have any knowledge of the facade.

The facade pattern defines a new interface for existing objects, whereas the Adapter pattern tries to make the existing interface usable. The adapter pattern usually wraps just one object, while Facade works with an entire subsystem of objects.



Q73. What is Flyweight Design Pattern (FDP) or Cache Pattern?

Flyweight is a structural design pattern that lets you fit more objects into the available amount of RAM by sharing common parts of the state between multiple objects instead of keeping all of the data in each object.

The Flyweight Design Pattern is used when there is a need to create a large number of objects of almost similar nature. A large number of objects consumes a large amount of memory and the Flyweight design pattern provides a solution for reducing the load on memory by sharing objects.



This design pattern is basically used to reduce the number of objects created, decrease the memory footprint, and increase the overall performance of the application. So this design pattern tries to reduce the already existing similar kind of objects by storing them and creating a new object when no matching object is found.

In the flyweight design pattern, there are two states i.e. Intrinsic and Extrinsic. Intrinsic states are things that are constants and stored in memory. On the other hand, extrinsic states are things that are not constant and need to be calculated on the Fly and are therefore not stored in the memory.

Since the same flyweight object can be used in different contexts, you have to make sure that its state can’t be modified. A flyweight should initialize its state just once, via constructor parameters. It shouldn’t expose any setters or public fields to other objects.


To Be Continued Part-10...


Recommended Articles






Thanks for visiting this page. Please follow and join us on LinkedInFacebookTelegramQuoraYouTubeTwitterPinterestTumblerVK, and WhatsApp for regular updates.

    



External Reference:


  1. Wikipedia
  2. RefacturingGuru
  3. SourceMaking


No comments:

Post a Comment

Please do not enter any HTML. JavaScript or spam link in the comment box.