DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Low-Code Development: Leverage low and no code to streamline your workflow so that you can focus on higher priorities.

DZone Security Research: Tell us your top security strategies in 2024, influence our research, and enter for a chance to win $!

Launch your software development career: Dive head first into the SDLC and learn how to build high-quality software and teams.

Open Source Migration Practices and Patterns: Explore key traits of migrating open-source software and its impact on software development.

Related

  • Authorization Using Reverse Proxy Design Pattern in Cloud Environment
  • Comprehensive Proxy Server Guide: Types, Applications, and Developer Examples
  • CORS Anywhere on Pure NGINX Config
  • Architecting Excellence: Guided Insights for Elevated Code Design

Trending

  • Tackling Records in Spring Boot
  • Mastering System Design: A Comprehensive Guide to System Scaling for Millions, Part 2
  • Data Governance: Data Integration (Part 4)
  • GenAI: Spring Boot Integration With LocalAI for Code Conversion
  1. DZone
  2. Software Design and Architecture
  3. Integration
  4. Software Design Patterns and Principles

Software Design Patterns and Principles

An introduction to good object-oriented principles and design patterns every software programmer should be using on a daily basis.

By 
Shobhit Kukreti user avatar
Shobhit Kukreti
·
Tanvi Hungund user avatar
Tanvi Hungund
·
Priyank Singh user avatar
Priyank Singh
·
Karthik Kamarapu user avatar
Karthik Kamarapu
·
Dhanveer Nambiar user avatar
Dhanveer Nambiar
·
Jun. 05, 24 · Tutorial
Like (2)
Save
Tweet
Share
2.5K Views

Join the DZone community and get the full member experience.

Join For Free

Design patterns are a set of templates formulated over a period of time by software architects. They are best practices that software programmers can apply to their own software/application development. They provide incredible advantages by saving time and effort by reusing pre-existing solutions while improving the quality and consistency of the code. It can also help enhance communication and collaboration with other developers, facilitate the adaptation and evolution of your code, and prevent common pitfalls and errors. All in all, design patterns are a great way to streamline your programming process. 

Broadly speaking there are three kinds of patterns: structural, creational, and behavioral.

  • Creational Patterns are concerned with the creation of an object and separating the object creation from the client that will use the object. Examples include Singleton, Factory, and Factory Method. 
  • Behavioral Patterns define how multiple objects interact with each other. Command Patterns, Iterator Patterns, and Observer Patterns are some of the common behavioral patterns. The patterns show how different components of the system behave and respond to each other. It can improve the code by enhancing flexibility, modularity, and reusability.
  • Structural patterns, on the other hand, deal with the composition and organization of classes and objects. It can hide the complexity of the system by composing classes and objects into larger structures. Examples include Adapter, Composite, Decorator, Facade, and Proxy.

While design patterns are a tried and tested solution, they are formed on the backs of good object-oriented programming principles. Some of the key principles are listed below:

  • Program to an interface: Keeps the design flexible.
  • Identify the sections of your software that can vary and separate them from the sections that vary: Keep the design modular
  • Favor composition over inheritance: Compose the large structure with individual objects.
  • Loose coupling: Minimize interdependency on objects.
  • The open/closed principle: Class software once code is completed, tested, and validated should be closed for modification but the class is open to extension by means of inheritance.
  • Dependency inversion: Depend on abstract or interfaces rather than concrete instantiation of classes.
  • Single responsibility principle: A class is responsible for only one requirement.

Example: Proxy Pattern

We chose the Structural Proxy Pattern for our discussion. It is a popular pattern especially used in distributed systems as a Remote Proxy. Proxy Pattern, as the name suggests, is a proxy for someone else. A proxy-designed class provides public-facing APIs that clients use to send requests. The proxy class has the means to access the real object service and can serve the request to it after say authentication of the request from the client. Furthermore, a proxy pattern can allow for lazy initialization. If the real object creation is deemed expensive, we can delay its instantiation only when it is needed by a client.  It also allows for logging and caching which can be implemented in the proxy class methods.  In the case of distributed systems where the client and the proxy object are on one node and the service real object which services the request is on another node, the proxy pattern allows for a uniform view and the client is unaware of which node is servicing the object. 

Fig. 1: Proxy Pattern

Fig. 1: Proxy Pattern

Figure 1 shows an architecture diagram of the proxy pattern. It has a client class that contains a handle to the ProxyObject. The ProxyClass and RealClass both derive from the iProxy interface class and implement the APIs. To be able to communicate between the two nodes, both additionally have a CommObject which is responsible for the serialization and de-serialization of commands and data when shared over the network. The code snippet provides a minimal set of class and method declarations to visualize how the distributed system would operate together.

C++
 


// CommClass provides serialization/deserialization to
// to share data and command in a distributed system
class CommClass {

  // RealClass registers a callback with the CommClass to receive command 
  // and data from the proxy
  typedef std::function<void(unsigned, vector<unsigned>)> fCallBack;
  
  public:
  	CommClass() {}
	~CommClass() {}

  	// Proxy Class Uses the CommClass Object to send command and data to the remote service
  	void sendToRemoteService(unsigned cmd, std::vector<unsigned> data);

	// Remote Service Class is notified via event. It uses the registered callback
  	// to call into the remote service RealClass
  	void receiveFromProxy(unsigned cmd, std::vector<unsigned> data)
    {
    	_cb(cmd, data);
    }
  
  	void registerCallBack(fCallBack cb) { _cb = cb; }
  
  private:
  	fCallBack _cb;

  
};


// Proxy Interface Class declares the public facing methods
class iProxy {

  public:
  	iProxy() {}
  	virtual ~iProxy() {}
  
  	virtual void methodOne() = 0;
  	virtual void methodTwo() = 0;

};

// Concrete class which implements the interface class methods and
// lives on the same node as the client
class ProxyClass : public iProxy {

  public:
  	ProxyClass() {};
  	~ProxyClass() {};
  
  	// Implement Interfaces
  	void methodOne() {};
  	void methodTwo() {};
  
  private:
  	CommClass CommObject;
  
};

// Real Class which implements the Proxy Interface methods and is the service provider
class RealClass : public iProxy {

  public:
    RealClass() {};
    ~RealClass() {};
  
  // implement the interfaces
    void methodOne() {};
    void methodTwo() {};

  private:
  	CommClass CommObject;
  
};


Conclusion

The example Proxy Pattern is an important arrow in any software engineer's quiver. By using the principle of composition, we can control access to internal objects, add additional logic such as caching and logging around APIs as well add security. It allows for lazy initialization which is useful in a resource-constrained environment. Certain disadvantages such as added overhead and complexity do exist and therefore, this is not a one-size-fits-all solution.  

While Proxy Pattern offers a robust solution to many common design challenges, any design pattern should be used with caution to not overcomplicate your design. Always start with the simpler object-oriented principles and then switch to a design pattern when your architecture starts resembling a specific pattern.

Loose coupling Proxy pattern Software design pattern

Opinions expressed by DZone contributors are their own.

Related

  • Authorization Using Reverse Proxy Design Pattern in Cloud Environment
  • Comprehensive Proxy Server Guide: Types, Applications, and Developer Examples
  • CORS Anywhere on Pure NGINX Config
  • Architecting Excellence: Guided Insights for Elevated Code Design

Partner Resources


Comments

ABOUT US

  • About DZone
  • Send feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends: