<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Venu's blog]]></title><description><![CDATA[Venu's blog]]></description><link>https://venuemmadi.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Thu, 12 Nov 2026 10:18:31 GMT</lastBuildDate><atom:link href="https://venuemmadi.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[A Complete Guide to OpenTelemetry Java Agent: JVM Flags You Should Know]]></title><description><![CDATA[OpenTelemetry (OTel) has become the industry standard for collecting and exporting telemetry data (traces, metrics, and logs) from applications. One of the…]]></description><link>https://venuemmadi.hashnode.dev/a-complete-guide-to-opentelemetry-java-agent-jvm-flags-you-should-know</link><guid isPermaLink="true">https://venuemmadi.hashnode.dev/a-complete-guide-to-opentelemetry-java-agent-jvm-flags-you-should-know</guid><category><![CDATA[OpenTelemetry]]></category><category><![CDATA[opentelemetry collector]]></category><category><![CDATA[observability]]></category><category><![CDATA[monitoring]]></category><dc:creator><![CDATA[Venu Madhav Emmadi]]></dc:creator><pubDate>Fri, 30 May 2025 11:41:43 GMT</pubDate><content:encoded><![CDATA[<p>OpenTelemetry (OTel) has become the industry standard for collecting and exporting telemetry data (traces, metrics, and logs) from applications. One of the simplest ways to instrument your Java application is by using the <strong>OpenTelemetry Java Agent</strong>.</p>
<p>But what truly unlocks its potential is configuring it through the right <strong>JVM flags</strong>. In this article, I’ll walk through a <strong>comprehensive list of JVM options</strong> that help you control service metadata, exporters, instrumentation, sampling, and more.</p>
<hr />
<h2 id="heading-getting-started-attach-the-agent">Getting Started: Attach the Agent</h2>
<p>At the heart of instrumentation is the agent itself:</p>
<pre><code class="lang-bash">-javaagent:/path/to/opentelemetry-javaagent.jar
</code></pre>
<p>This flag attaches the OpenTelemetry Java Agent to your running JVM process.</p>
<hr />
<h2 id="heading-define-your-service-and-attributes">Define Your Service and Attributes</h2>
<p>You can tag telemetry data with service-specific metadata:</p>
<pre><code class="lang-bash">-Dotel.service.name=my-service
-Dotel.resource.attributes=env=prod,region=us-west,team=observability
</code></pre>
<p>Use this to enrich traces, metrics, and logs with context.</p>
<hr />
<h2 id="heading-exporters-where-your-telemetry-goes">Exporters: Where Your Telemetry Goes</h2>
<p>OpenTelemetry supports multiple exporters. You can configure them like this:</p>
<h3 id="heading-general-exporter-configuration">General Exporter Configuration</h3>
<pre><code class="lang-bash">-Dotel.traces.exporter=otlp
-Dotel.metrics.exporter=otlp
-Dotel.logs.exporter=otlp
</code></pre>
<hr />
<h3 id="heading-otlp-exporter-settings-recommended-default">OTLP Exporter Settings (Recommended Default)</h3>
<pre><code class="lang-bash">-Dotel.exporter.otlp.endpoint=http://otel-collector:4317
-Dotel.exporter.otlp.traces.endpoint=http://otel-collector:4317/v1/traces
-Dotel.exporter.otlp.metrics.endpoint=http://otel-collector:4317/v1/metrics
-Dotel.exporter.otlp.logs.endpoint=http://otel-collector:4317/v1/logs
-Dotel.exporter.otlp.protocol=grpc
-Dotel.exporter.otlp.headers=x-tenant-id=mytenant,x-api-key=abc123
-Dotel.exporter.otlp.timeout=10s
-Dotel.exporter.otlp.certificate=/path/to/cert.pem
</code></pre>
<hr />
<h3 id="heading-jaeger-exporter-optional">Jaeger Exporter (Optional)</h3>
<pre><code class="lang-bash">-Dotel.traces.exporter=jaeger
-Dotel.exporter.jaeger.endpoint=http://localhost:14250
-Dotel.exporter.jaeger.timeout=10s
</code></pre>
<hr />
<h3 id="heading-zipkin-exporter-optional">Zipkin Exporter (Optional)</h3>
<pre><code class="lang-bash">-Dotel.traces.exporter=zipkin
-Dotel.exporter.zipkin.endpoint=http://localhost:9411/api/v2/spans
-Dotel.exporter.zipkin.timeout=10s
</code></pre>
<hr />
<h2 id="heading-context-propagation">Context Propagation</h2>
<p>Control how context (trace, baggage) is propagated across services:</p>
<pre><code class="lang-bash">-Dotel.propagators=b3,baggage,tracecontext
</code></pre>
<hr />
<h2 id="heading-sampling-control-the-volume-of-data">Sampling: Control the Volume of Data</h2>
<p>Sampling policies define how many traces are collected:</p>
<pre><code class="lang-bash">-Dotel.traces.sampler=traceidratio
-Dotel.traces.sampler.arg=0.25
</code></pre>
<p>Other samplers include:</p>
<ul>
<li><p><code>always_on</code></p>
</li>
<li><p><code>always_off</code></p>
</li>
<li><p><code>parentbased_always_on</code></p>
</li>
</ul>
<hr />
<h2 id="heading-fine-grained-instrumentation-control">Fine-Grained Instrumentation Control</h2>
<p>Enable or disable specific instrumentations:</p>
<pre><code class="lang-bash">-Dotel.instrumentation.spring-web.enabled=<span class="hljs-literal">true</span>
-Dotel.instrumentation.jdbc.enabled=<span class="hljs-literal">true</span>
-Dotel.instrumentation.kafka.enabled=<span class="hljs-literal">false</span>
-Dotel.instrumentation.reactor.enabled=<span class="hljs-literal">false</span>
-Dotel.instrumentation.common.default-enabled=<span class="hljs-literal">true</span>
</code></pre>
<hr />
<h2 id="heading-experimental-features">Experimental Features</h2>
<p>These are cutting-edge flags, useful in specific use cases:</p>
<pre><code class="lang-bash">-Dotel.experimental.span.attributes=<span class="hljs-literal">true</span>
-Dotel.experimental.suppress-nested-client-span=<span class="hljs-literal">true</span>
-Dotel.instrumentation.runtime-metrics.enabled=<span class="hljs-literal">true</span>
-Dotel.instrumentation.micrometer.enabled=<span class="hljs-literal">true</span>
-Dotel.javaagent.experimental.thread-propagation.enabled=<span class="hljs-literal">true</span>
</code></pre>
<hr />
<h2 id="heading-debugging-and-logging">Debugging and Logging</h2>
<p>To debug agent behavior or get verbose logging:</p>
<pre><code class="lang-bash">-Dotel.javaagent.debug=<span class="hljs-literal">true</span>
-Dio.opentelemetry.javaagent.slf4j.simpleLogger.defaultLogLevel=debug
-Dio.opentelemetry.context.enableStrictContext=<span class="hljs-literal">true</span>
</code></pre>
<hr />
<h2 id="heading-miscellaneous-options">Miscellaneous Options</h2>
<p>Some additional flags that control agent lifecycle and SDK behavior:</p>
<pre><code class="lang-bash">-Dotel.javaagent.bootstrap.enabled=<span class="hljs-literal">true</span>
-Dotel.sdk.disabled=<span class="hljs-literal">false</span>
</code></pre>
<hr />
<h2 id="heading-how-to-use-these-in-practice">How to Use These in Practice</h2>
<p>Here’s how all this comes together in a Java application startup:</p>
<pre><code class="lang-bash">java -javaagent:/opt/otel/opentelemetry-javaagent.jar \
  -Dotel.service.name=order-service \
  -Dotel.resource.attributes=env=prod,region=us-east \
  -Dotel.traces.exporter=otlp \
  -Dotel.exporter.otlp.endpoint=http://otel-collector:4317 \
  -Dotel.traces.sampler=traceidratio \
  -Dotel.traces.sampler.arg=0.2 \
  -Dotel.javaagent.debug=<span class="hljs-literal">true</span> \
  -jar app.jar
</code></pre>
<hr />
<h2 id="heading-configuring-with-environment-variables"><strong>Configuring with Environment Variables</strong></h2>
<p>In certain environments, configuring settings through environment variables is often preferred. Any setting that can be configured using a system property can also be set using an environment variable. While many of the settings below provide examples for both formats, for those that do not, use the following steps to determine the correct name mapping for the desired system property:</p>
<ul>
<li><p>Convert the system property name to uppercase.</p>
</li>
<li><p>Replace all <code>.</code> and <code>-</code> characters with <code>_</code>.</p>
</li>
</ul>
<p>For example <code>otel.instrumentation.common.default-enabled</code> would convert to <code>OTEL_INSTRUMENTATION_COMMON_DEFAULT_ENABLED</code></p>
<hr />
<h2 id="heading-conclusion">Conclusion</h2>
<p>The OpenTelemetry Java Agent is a powerful plug-and-play tool that can be fine-tuned with the right JVM flags. Whether you're sending data to OTLP, Jaeger, or Zipkin, or disabling noisy instrumentation — these flags offer full control over what gets collected and how.</p>
<p>By customizing your startup flags, you ensure your telemetry pipeline is efficient, secure, and insightful — just as it should be.</p>
]]></content:encoded></item><item><title><![CDATA[Setting Up LGTP Stack (Loki, Grafana, Tempo, Prometheus) on Windows]]></title><description><![CDATA[Monitoring and observability have become essential in modern development. If you're looking to run the LGTP stack on your Windows laptop for local testing…]]></description><link>https://venuemmadi.hashnode.dev/setting-up-lgtp-stack-loki-grafana-tempo-prometheus-on-windows</link><guid isPermaLink="true">https://venuemmadi.hashnode.dev/setting-up-lgtp-stack-loki-grafana-tempo-prometheus-on-windows</guid><category><![CDATA[observability]]></category><category><![CDATA[Grafana]]></category><category><![CDATA[loki]]></category><category><![CDATA[Tempo]]></category><category><![CDATA[#prometheus]]></category><category><![CDATA[OpenTelemetry]]></category><category><![CDATA[telemetry]]></category><dc:creator><![CDATA[Venu Madhav Emmadi]]></dc:creator><pubDate>Sun, 20 Apr 2025 15:40:51 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1745163479809/e09dd2dd-0354-48c9-8362-0e51506dbf6b.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Monitoring and observability have become essential in modern development. If you're looking to run the LGTP stack on your Windows laptop for local testing or learning, this guide walks you through each step—no Docker required!</p>
<hr />
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>Before we begin, make sure:</p>
<ul>
<li><p>You're on <strong>Windows 10/11</strong></p>
</li>
<li><p>You have <strong>Git</strong>, <strong>PowerShell</strong>, and <strong>a modern browser</strong></p>
</li>
<li><p>You’ve installed the <strong>OpenTelemetry Collector</strong> (optional, for pushing metrics/logs/traces to Prometheus, Loki, and Tempo)</p>
</li>
</ul>
<hr />
<h2 id="heading-step-by-step-setup">Step-by-Step Setup</h2>
<hr />
<h3 id="heading-1-download-binaries">1. Download Binaries</h3>
<h4 id="heading-grafana">Grafana</h4>
<ul>
<li><p>Go to <a target="_blank" href="https://grafana.com/grafana/download">Grafana Download</a></p>
</li>
<li><p>Select <strong>Windows</strong> and download the ZIP</p>
</li>
<li><p>Extract and keep it in a path like <code>C:\tools\grafana</code></p>
</li>
</ul>
<h4 id="heading-prometheus">Prometheus</h4>
<ul>
<li><p>Download from: <a target="_blank" href="https://prometheus.io/download/">Prometheus Releases</a></p>
</li>
<li><p>Choose <code>prometheus-&lt;version&gt;.windows-amd64.zip</code></p>
</li>
<li><p>Extract and keep it in <code>C:\tools\prometheus</code></p>
</li>
</ul>
<h4 id="heading-loki">Loki</h4>
<ul>
<li><p>Visit: <a target="_blank" href="https://github.com/grafana/loki/releases">Loki Releases</a></p>
</li>
<li><p>Download the latest <code>loki-windows-amd64.exe</code></p>
</li>
<li><p>Rename to <code>loki.exe</code> and place it in <code>C:\tools\loki</code></p>
</li>
</ul>
<h4 id="heading-tempo">Tempo</h4>
<ul>
<li><p>Go to <a target="_blank" href="https://github.com/grafana/tempo/releases">Tempo Releases</a></p>
</li>
<li><p>Download <code>tempo-windows-amd64.exe</code></p>
</li>
<li><p>Rename to <code>tempo.exe</code> and place in <code>C:\tools\tempo</code></p>
</li>
</ul>
<hr />
<h3 id="heading-2-create-configuration-files">2. Create Configuration Files</h3>
<p>Create config files in respective folders:</p>
<h4 id="heading-prometheusyml-for-prometheus"><code>prometheus.yml</code> (for Prometheus)</h4>
<pre><code class="lang-yaml"><span class="hljs-attr">global:</span>
  <span class="hljs-attr">scrape_interval:</span> <span class="hljs-string">15s</span>

<span class="hljs-attr">scrape_configs:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">job_name:</span> <span class="hljs-string">'prometheus'</span>
    <span class="hljs-attr">static_configs:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">targets:</span> [<span class="hljs-string">'localhost:9090'</span>]
</code></pre>
<h4 id="heading-loki-configyaml-for-loki"><code>loki-config.yaml</code> (for Loki)</h4>
<pre><code class="lang-yaml"><span class="hljs-attr">auth_enabled:</span> <span class="hljs-literal">false</span>

<span class="hljs-attr">server:</span>
  <span class="hljs-attr">http_listen_port:</span> <span class="hljs-number">3100</span>

<span class="hljs-attr">ingester:</span>
  <span class="hljs-attr">lifecycler:</span>
    <span class="hljs-attr">ring:</span>
      <span class="hljs-attr">kvstore:</span>
        <span class="hljs-attr">store:</span> <span class="hljs-string">inmemory</span>
      <span class="hljs-attr">replication_factor:</span> <span class="hljs-number">1</span>
  <span class="hljs-attr">final_sleep:</span> <span class="hljs-string">0s</span>

<span class="hljs-attr">schema_config:</span>
  <span class="hljs-attr">configs:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">from:</span> <span class="hljs-number">2023-01-01</span>
      <span class="hljs-attr">store:</span> <span class="hljs-string">boltdb-shipper</span>
      <span class="hljs-attr">object_store:</span> <span class="hljs-string">filesystem</span>
      <span class="hljs-attr">schema:</span> <span class="hljs-string">v11</span>
      <span class="hljs-attr">index:</span>
        <span class="hljs-attr">prefix:</span> <span class="hljs-string">index_</span>
        <span class="hljs-attr">period:</span> <span class="hljs-string">24h</span>

<span class="hljs-attr">storage_config:</span>
  <span class="hljs-attr">boltdb_shipper:</span>
    <span class="hljs-attr">active_index_directory:</span> <span class="hljs-string">C:/tools/loki/index</span>
    <span class="hljs-attr">cache_location:</span> <span class="hljs-string">C:/tools/loki/cache</span>
    <span class="hljs-attr">shared_store:</span> <span class="hljs-string">filesystem</span>
  <span class="hljs-attr">filesystem:</span>
    <span class="hljs-attr">directory:</span> <span class="hljs-string">C:/tools/loki/chunks</span>

<span class="hljs-attr">limits_config:</span>
  <span class="hljs-attr">enforce_metric_name:</span> <span class="hljs-literal">false</span>
  <span class="hljs-attr">reject_old_samples:</span> <span class="hljs-literal">true</span>
  <span class="hljs-attr">reject_old_samples_max_age:</span> <span class="hljs-string">168h</span>
</code></pre>
<h4 id="heading-tempo-configyaml-for-tempo"><code>tempo-config.yaml</code> (for Tempo)</h4>
<pre><code class="lang-yaml"><span class="hljs-attr">auth_enabled:</span> <span class="hljs-literal">false</span>

<span class="hljs-attr">server:</span>
  <span class="hljs-attr">http_listen_port:</span> <span class="hljs-number">3200</span>

<span class="hljs-attr">distributor:</span>
  <span class="hljs-attr">receivers:</span>
    <span class="hljs-attr">jaeger:</span>
      <span class="hljs-attr">protocols:</span>
        <span class="hljs-attr">grpc:</span>
        <span class="hljs-attr">thrift_binary:</span>
        <span class="hljs-attr">thrift_compact:</span>
        <span class="hljs-attr">thrift_http:</span>
    <span class="hljs-attr">otlp:</span>
      <span class="hljs-attr">protocols:</span>
        <span class="hljs-attr">grpc:</span>
        <span class="hljs-attr">http:</span>

<span class="hljs-attr">storage:</span>
  <span class="hljs-attr">trace:</span>
    <span class="hljs-attr">backend:</span> <span class="hljs-string">local</span>
    <span class="hljs-attr">local:</span>
      <span class="hljs-attr">path:</span> <span class="hljs-string">C:/tools/tempo/traces</span>
</code></pre>
<hr />
<h3 id="heading-3-run-each-component">3. Run Each Component</h3>
<p>Open separate PowerShell windows for each service:</p>
<h4 id="heading-start-prometheus">Start Prometheus</h4>
<pre><code class="lang-powershell"><span class="hljs-built_in">cd</span> C:\tools\prometheus
.\prometheus.exe -<span class="hljs-literal">-config</span>.file=prometheus.yml
</code></pre>
<h4 id="heading-start-loki">Start Loki</h4>
<pre><code class="lang-powershell"><span class="hljs-built_in">cd</span> C:\tools\loki
.\loki.exe -<span class="hljs-literal">-config</span>.file=loki<span class="hljs-literal">-config</span>.yaml
</code></pre>
<h4 id="heading-start-tempo">Start Tempo</h4>
<pre><code class="lang-powershell"><span class="hljs-built_in">cd</span> C:\tools\tempo
.\tempo.exe -<span class="hljs-literal">-config</span>.file=tempo<span class="hljs-literal">-config</span>.yaml
</code></pre>
<h4 id="heading-start-grafana">Start Grafana</h4>
<pre><code class="lang-powershell"><span class="hljs-built_in">cd</span> C:\tools\grafana\bin
.\grafana<span class="hljs-literal">-server</span>.exe
</code></pre>
<hr />
<h2 id="heading-access-the-interfaces">Access the Interfaces</h2>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Component</td><td>URL</td></tr>
</thead>
<tbody>
<tr>
<td>Grafana</td><td><a target="_blank" href="http://localhost:3000/">http://localhost:3000</a></td></tr>
<tr>
<td>Prometheus</td><td><a target="_blank" href="http://localhost:9090/">http://localhost:9090</a></td></tr>
<tr>
<td>Loki API</td><td><a target="_blank" href="http://localhost:3100/">http://localhost:3100</a></td></tr>
<tr>
<td>Tempo API</td><td><a target="_blank" href="http://localhost:3200/">http://localhost:3200</a></td></tr>
</tbody>
</table>
</div><p>Default Grafana login: <strong>admin / admin</strong></p>
<hr />
<h2 id="heading-configure-grafana">Configure Grafana</h2>
<ol>
<li><p>Go to <a target="_blank" href="http://localhost:3000/"><strong>http://localhost:3000</strong></a></p>
</li>
<li><p>Add data sources:</p>
<ul>
<li><p>Prometheus (<a target="_blank" href="http://localhost:9090/">http://localhost:9090</a>)</p>
</li>
<li><p>Loki (<a target="_blank" href="http://localhost:3100/">http://localhost:3100</a>)</p>
</li>
<li><p>Tempo (<a target="_blank" href="http://localhost:3200/">http://localhost:3200</a>)</p>
</li>
</ul>
</li>
<li><p>Import community dashboards or build your own.</p>
</li>
</ol>
<hr />
<h2 id="heading-summary">Summary</h2>
<p>You now have LGTP stack running on your Windows laptop—great for testing, exploring observability, and learning Prometheus queries or tracing flows with Tempo.</p>
]]></content:encoded></item><item><title><![CDATA[Send OpenTelemetry Telemetry Directly to Elasticsearch (No APM Server Needed!)]]></title><description><![CDATA[If you're using the OpenTelemetry Collector Contrib and want to send telemetry directly to Elasticsearch without relying on Logstash or Elastic APM Server…]]></description><link>https://venuemmadi.hashnode.dev/send-opentelemetry-telemetry-directly-to-elasticsearch-no-apm-server-needed</link><guid isPermaLink="true">https://venuemmadi.hashnode.dev/send-opentelemetry-telemetry-directly-to-elasticsearch-no-apm-server-needed</guid><category><![CDATA[observability]]></category><category><![CDATA[OpenTelemetry]]></category><category><![CDATA[elasticsearch]]></category><dc:creator><![CDATA[Venu Madhav Emmadi]]></dc:creator><pubDate>Tue, 08 Apr 2025 05:52:40 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1745165965774/aa6e6e86-c096-48fc-83f2-9a48d9baf952.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>If you're using the <a target="_blank" href="https://github.com/open-telemetry/opentelemetry-collector-contrib">OpenTelemetry Collector Contrib</a> and want to send telemetry directly to <strong>Elasticsearch</strong> without relying on <strong>Logstash</strong> or <strong>Elastic APM Server</strong>, you're in luck.</p>
<p>As of recent versions, the <code>elasticsearch</code> exporter in OpenTelemetry Collector Contrib supports <strong>logs</strong>, <strong>metrics</strong>, <strong>traces</strong>, and even <strong>profiling data</strong> — all natively, all directly into Elasticsearch!</p>
<p>In this guide, we’ll show you how to configure the <strong>OpenTelemetry Collector on any platform (including Windows)</strong> to forward telemetry to Elasticsearch, bypassing the APM Server.</p>
<hr />
<h2 id="heading-architecture-overview">Architecture Overview</h2>
<pre><code class="lang-bash">[App with OTel SDK or Agent]
         ↓ OTLP
[OpenTelemetry Collector]
         ↓ elasticsearch exporter
[Elasticsearch]
         ↓
[Kibana]
</code></pre>
<ul>
<li><p><strong>No APM Server</strong></p>
</li>
<li><p><strong>No Logstash</strong></p>
</li>
<li><p>Just pure OpenTelemetry ➝ Elasticsearch ➝ Kibana</p>
</li>
</ul>
<hr />
<h2 id="heading-why-this-is-awesome">Why This is Awesome</h2>
<ul>
<li><p>No need to run Elastic APM Server</p>
</li>
<li><p>Works with Elasticsearch 7.17+ and 8.x</p>
</li>
<li><p>Supports logs, metrics, traces, and profiles</p>
</li>
<li><p>Configurable <code>mapping.mode</code> for better indexing/querying</p>
</li>
<li><p>Clean OTLP-to-Elastic pipeline</p>
</li>
</ul>
<hr />
<h2 id="heading-prerequisites">Prerequisites</h2>
<ul>
<li><p>Elasticsearch 7.17 or 8.x running and accessible</p>
</li>
<li><p>Kibana (for visualization)</p>
</li>
<li><p>OpenTelemetry Collector Contrib binary</p>
</li>
<li><p>Optional: an app using an OpenTelemetry SDK/agent (Java, Python, etc.)</p>
</li>
</ul>
<hr />
<h2 id="heading-sample-opentelemetry-collector-config-otel-configyaml">Sample OpenTelemetry Collector Config (<code>otel-config.yaml</code>)</h2>
<h3 id="heading-prepare-the-configuration">Prepare the Configuration</h3>
<p>Create a config file named <code>otel-config.yaml</code> in <code>C:\otel-collector</code>, and paste the config as shown below (with <code>otlp</code> receiver and <code>elasticsearch</code> exporter).</p>
<p>Make sure to update:</p>
<ul>
<li><p>Elasticsearch endpoint (default is <a target="_blank" href="http://localhost:9200"><code>http://localhost:9200</code></a>)</p>
</li>
<li><p>Any TLS or authentication settings, if needed</p>
</li>
</ul>
<pre><code class="lang-yaml"><span class="hljs-attr">receivers:</span>
  <span class="hljs-attr">otlp:</span>
    <span class="hljs-attr">protocols:</span>
      <span class="hljs-attr">http:</span>

<span class="hljs-attr">processors:</span>
  <span class="hljs-attr">batch:</span>

<span class="hljs-attr">exporters:</span>
  <span class="hljs-attr">elasticsearch:</span>
    <span class="hljs-attr">endpoints:</span> [<span class="hljs-string">"http://localhost:9200"</span>]
    <span class="hljs-attr">tls:</span>
      <span class="hljs-attr">insecure:</span> <span class="hljs-literal">true</span>

<span class="hljs-attr">service:</span>
  <span class="hljs-attr">pipelines:</span>
    <span class="hljs-attr">traces:</span>
      <span class="hljs-attr">receivers:</span> [<span class="hljs-string">otlp</span>]
      <span class="hljs-attr">processors:</span> [<span class="hljs-string">batch</span>]
      <span class="hljs-attr">exporters:</span> [<span class="hljs-string">elasticsearch</span>]

    <span class="hljs-attr">metrics:</span>
      <span class="hljs-attr">receivers:</span> [<span class="hljs-string">otlp</span>]
      <span class="hljs-attr">processors:</span> [<span class="hljs-string">batch</span>]
      <span class="hljs-attr">exporters:</span> [<span class="hljs-string">elasticsearch</span>]

    <span class="hljs-attr">logs:</span>
      <span class="hljs-attr">receivers:</span> [<span class="hljs-string">otlp</span>]
      <span class="hljs-attr">processors:</span> [<span class="hljs-string">batch</span>]
      <span class="hljs-attr">exporters:</span> [<span class="hljs-string">elasticsearch</span>]
</code></pre>
<hr />
<h2 id="heading-download-and-set-up-opentelemetry-collector-on-windows">Download and Set Up OpenTelemetry Collector on Windows</h2>
<p>To run the OpenTelemetry Collector on Windows, follow these steps:</p>
<h3 id="heading-download-the-collector">Download the Collector</h3>
<ol>
<li><p>Visit the <a target="_blank" href="https://github.com/open-telemetry/opentelemetry-collector-releases/releases">OpenTelemetry Collector Releases.</a></p>
</li>
<li><p>Look for the latest <code>otelcol-contrib</code> release.</p>
</li>
<li><p>Download the <strong>Windows AMD64 zip</strong> file — e.g.,<br /> <code>otelcol-contrib_windows_amd64.zip</code></p>
</li>
<li><p>Extract the contents to a folder, e.g.: C:\otel-collector</p>
</li>
</ol>
<hr />
<h2 id="heading-run-the-opentelemetry-collectorhttpsgithubcomopen-telemetryopentelemetry-collector-releasesreleases">Run the <a target="_blank" href="https://github.com/open-telemetry/opentelemetry-collector-releases/releases">OpenTelemetry Collector</a></h2>
<pre><code class="lang-bash">otelcol-contrib.exe --config otel-config.yaml
</code></pre>
<p><a target="_blank" href="https://github.com/open-telemetry/opentelemetry-collector-releases/releases">Or in</a> Linux/macOS:</p>
<pre><code class="lang-bash">./otelcol-contrib --config otel-config.yaml
</code></pre>
<p><a target="_blank" href="https://github.com/open-telemetry/opentelemetry-collector-releases/releases">Make sure your app is</a> sending OTLP telemetry to the correct endpoint (<code>http://&lt;otel-host&gt;:4318</code> for HTTP-based OTLP).</p>
<hr />
<h2 id="heading-visualizing-data-in-kibana">Visualizing Data in Kibana</h2>
<ul>
<li><p>Visit <strong>Kibana</strong> (<code>http://localhost:5601</code>)</p>
</li>
<li><p>Use the <strong>Discover</strong> tab to search telemetry in:</p>
<ul>
<li><p><code>otel-logs-*</code></p>
</li>
<li><p><code>otel-metrics-*</code></p>
</li>
<li><p><code>otel-traces-*</code></p>
</li>
</ul>
</li>
<li><p>Create dashboards or use Lens/TSVB for metrics</p>
</li>
</ul>
<blockquote>
<p>You won’t get APM-specific UI (service maps, trace waterfalls) — but you can build dashboards manually.</p>
</blockquote>
<hr />
<h2 id="heading-bonus-generate-test-data">Bonus: Generate Test Data</h2>
<p>Try <a target="_blank" href="https://github.com/open-telemetry/opentelemetry-demo">OpenTelemetry Demo App</a> or run a simple instrumented app (like Spring Boot + OTel Java agent) to test logs/traces/metrics flowing into Elasticsearch.</p>
<hr />
<h2 id="heading-caveats">Caveats</h2>
<ul>
<li><p>No out-of-the-box <strong>Elastic APM UI features</strong> like service maps, span graphs, or anomaly detection.</p>
</li>
<li><p><code>otel</code> mapping mode requires recent Elasticsearch versions.</p>
</li>
<li><p>Profiling data support is <strong>experimental</strong>.</p>
</li>
</ul>
<hr />
<h2 id="heading-final-thoughts">Final Thoughts</h2>
<p>With the enhanced <code>elasticsearch</code> exporter in OpenTelemetry Collector Contrib, sending <strong>logs, metrics, traces, and profiles directly to Elasticsearch</strong> is not only possible — it's practical, clean, and fast.</p>
<p>Whether you're running in cloud or on-prem, this setup removes the dependency on APM Server or Logstash while still leveraging the power of the <strong>Elastic Stack</strong>.</p>
<hr />
<h2 id="heading-resources">Resources</h2>
<ul>
<li><p><a target="_blank" href="https://github.com/open-telemetry/opentelemetry-collector-contrib">OpenTelemetry Collector Contrib</a></p>
</li>
<li><p><a target="_blank" href="https://www.elastic.co/elastic-stack/">Elastic Stack</a></p>
</li>
<li><p><a target="_blank" href="https://opentelemetry.io/docs/specs/">OpenTelemetry Specification</a></p>
</li>
<li><p><a target="_blank" href="https://github.com/open-telemetry/opentelemetry-java-instrumentation">OpenTelemetry Java Agent</a></p>
</li>
</ul>
<hr />
]]></content:encoded></item><item><title><![CDATA[Attaching OpenTelemetry Java Agent to a Maven Microservice]]></title><description><![CDATA[Observability is critical in modern microservices architecture. It enables you to monitor, debug, and optimize distributed systems. OpenTelemetry (OTel) is…]]></description><link>https://venuemmadi.hashnode.dev/attaching-opentelemetry-java-agent-to-a-maven-microservice</link><guid isPermaLink="true">https://venuemmadi.hashnode.dev/attaching-opentelemetry-java-agent-to-a-maven-microservice</guid><category><![CDATA[observability]]></category><category><![CDATA[OpenTelemetry]]></category><category><![CDATA[telemetry]]></category><dc:creator><![CDATA[Venu Madhav Emmadi]]></dc:creator><pubDate>Thu, 03 Apr 2025 06:01:43 GMT</pubDate><content:encoded><![CDATA[<p>Observability is critical in modern microservices architecture. It enables you to monitor, debug, and optimize distributed systems. OpenTelemetry (OTel) is a powerful observability framework that supports tracing, metrics, and logs in a vendor-neutral way.</p>
<p>In this blog post, we’ll walk through how to attach the <strong>OpenTelemetry Java Agent</strong> to a <strong>Maven-based microservice</strong>, enabling automatic instrumentation with minimal effort.</p>
<hr />
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>Before we dive in, ensure you have the following set up:</p>
<ul>
<li><p>Java 8 or later (Java 17 and java 21 recommended)</p>
</li>
<li><p>Maven 3.6+</p>
</li>
<li><p>A working microservice project (Spring Boot, Jakarta EE, or similar)</p>
</li>
<li><p>Access to an OpenTelemetry-compatible backend like Jaeger, Zipkin, or an observability platform (e.g., Grafana Tempo, Lightstep)</p>
</li>
</ul>
<hr />
<h2 id="heading-what-is-the-opentelemetry-java-agent">What is the OpenTelemetry Java Agent?</h2>
<p>The OpenTelemetry Java Agent is a JAR file that you can attach to any Java application. It automatically instruments your application without requiring any code changes. It supports popular frameworks like:</p>
<ul>
<li><p>Spring Boot</p>
</li>
<li><p>gRPC</p>
</li>
<li><p>JDBC</p>
</li>
<li><p>HTTP clients (RestTemplate, OkHttp, Apache HTTP Client, etc.)</p>
</li>
<li><p>Servlet containers (Tomcat, Jetty)</p>
</li>
</ul>
<hr />
<h2 id="heading-step-by-step-attach-the-otel-agent-to-a-maven-microservice">Step-by-Step: Attach the OTel Agent to a Maven Microservice</h2>
<h3 id="heading-1-download-the-opentelemetry-java-agent"><strong>1. Download the OpenTelemetry Java Agent</strong></h3>
<p>Go to the <a target="_blank" href="https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases">OpenTelemetry Java Instrumentation Releases page</a> and download the latest <code>opentelemetry-javaagent.jar</code>.</p>
<p>You can also use <code>curl</code>:</p>
<pre><code class="lang-bash">curl -L -o opentelemetry-javaagent.jar https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest/download/opentelemetry-javaagent.jar
</code></pre>
<p>Place this file in the root directory of your microservice or a common location.</p>
<hr />
<h3 id="heading-2-update-maven-pomxml-optional"><strong>2. Update Maven</strong> <code>pom.xml</code> (Optional)</h3>
<p>You don't need to change your <code>pom.xml</code> to use the agent, but if you want to send custom spans or metrics, add the OpenTelemetry SDK dependencies:</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">dependencyManagement</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">dependencies</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>io.opentelemetry<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>opentelemetry-bom<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>1.35.0<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">type</span>&gt;</span>pom<span class="hljs-tag">&lt;/<span class="hljs-name">type</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">scope</span>&gt;</span>import<span class="hljs-tag">&lt;/<span class="hljs-name">scope</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">dependencies</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">dependencyManagement</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">dependencies</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>io.opentelemetry<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>opentelemetry-api<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>io.opentelemetry<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>opentelemetry-sdk<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">dependencies</span>&gt;</span>
</code></pre>
<blockquote>
<p>Skip this step if you only need automatic instrumentation.</p>
</blockquote>
<hr />
<h3 id="heading-3-configure-the-opentelemetry-agent"><strong>3. Configure the OpenTelemetry Agent</strong></h3>
<p>To enable observability, you'll configure the OpenTelemetry Java agent and run your microservice with it attached. The agent picks up system properties or environment variables to determine where to send telemetry like <strong>traces</strong>, <strong>metrics</strong>, and <strong>logs</strong>.</p>
<p><strong>Note - You can send telemetry from the OpenTelemetry agent to any OTLP-compatible backend. First, ensure your observability backend is up and running, then configure the agent with the appropriate endpoint URL and port to forward the telemetry data.</strong></p>
<h3 id="heading-run-the-microservice-with-the-agent"><strong>Run the Microservice with the Agent</strong></h3>
<p>You attach the agent via the <code>-javaagent</code> option when starting your microservice.</p>
<p>If you’re using the Spring Boot Maven plugin:</p>
<pre><code class="lang-bash">java -javaagent:./opentelemetry-javaagent.jar \
     -Dotel.service.name=my-microservice \
     -Dotel.exporter.otlp.traces.endpoint=http://traces-backend:4317 \
     -Dotel.exporter.otlp.metrics.endpoint=http://metrics-backend:4317 \
     -Dotel.exporter.otlp.logs.endpoint=http://logs-backend:4317 \
     -Dotel.metrics.exporter=otlp \
     -Dotel.logs.exporter=otlp \
     -Dotel.instrumentation.log-injection.enabled=<span class="hljs-literal">true</span> \
     -jar target/my-microservice.jar
</code></pre>
<p>Or if using <code>mvn spring-boot:run</code>:</p>
<pre><code class="lang-bash">MAVEN_OPTS=<span class="hljs-string">"\
-javaagent:./opentelemetry-javaagent.jar \
-Dotel.service.name=my-microservice \
-Dotel.exporter.otlp.traces.endpoint=http://traces-backend:4317 \
-Dotel.exporter.otlp.metrics.endpoint=http://metrics-backend:4317 \
-Dotel.exporter.otlp.logs.endpoint=http://logs-backend:4317 \
-Dotel.metrics.exporter=otlp \
-Dotel.logs.exporter=otlp \
-Dotel.instrumentation.log-injection.enabled=true"</span> \
mvn spring-boot:run
</code></pre>
<blockquote>
<p>You can also pass <code>OTEL_EXPORTER_OTLP_ENDPOINT</code> and other settings as environment variables.</p>
</blockquote>
<h3 id="heading-you-can-also-update-pomxml-snippet-with-full-opentelemetry-agent-setup">you can also Update <code>pom.xml</code> Snippet with Full OpenTelemetry Agent Setup</h3>
<pre><code class="lang-bash">&lt;build&gt;
  &lt;plugins&gt;
    &lt;plugin&gt;
      &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
      &lt;artifactId&gt;spring-boot-maven-plugin&lt;/artifactId&gt;
      &lt;configuration&gt;
        &lt;jvmArguments&gt;
          -javaagent:<span class="hljs-variable">${project.basedir}</span>/opentelemetry-javaagent.jar
          -Dotel.service.name=my-microservice
          -Dotel.exporter.otlp.traces.endpoint=http://traces-backend:4317
          -Dotel.exporter.otlp.metrics.endpoint=http://metrics-backend:4317
          -Dotel.exporter.otlp.logs.endpoint=http://logs-backend:4317
          -Dotel.metrics.exporter=otlp
          -Dotel.logs.exporter=otlp
          -Dotel.instrumentation.log-injection.enabled=<span class="hljs-literal">true</span>
        &lt;/jvmArguments&gt;
      &lt;/configuration&gt;
    &lt;/plugin&gt;
  &lt;/plugins&gt;
&lt;/build&gt;
</code></pre>
<blockquote>
<p>Make sure the agent JAR is located at <code>./opentelemetry-javaagent.jar</code> relative to your project root — or adjust the path as needed.</p>
</blockquote>
<hr />
<h3 id="heading-verification">Verification</h3>
<p>Once your service starts, check your observability backend (e.g., Jaeger, Tempo, or your OpenTelemetry Collector). You should see:</p>
<ul>
<li><p><strong>Traces</strong> for incoming HTTP requests</p>
</li>
<li><p><strong>Spans</strong> representing downstream calls (e.g., DB, external services)</p>
</li>
<li><p><strong>Service metadata</strong> like service name, environment, etc.</p>
</li>
</ul>
<hr />
<h2 id="heading-advanced-configurations-optional">Advanced Configurations (Optional)</h2>
<ul>
<li><p><strong>Disable instrumentation for certain libraries</strong>:</p>
<pre><code class="lang-bash">  -Dotel.instrumentation.spring-web.enabled=<span class="hljs-literal">false</span>
</code></pre>
</li>
<li><p><strong>Add custom context propagation or headers</strong>:</p>
<pre><code class="lang-bash">  -Dotel.propagators=b3
</code></pre>
</li>
<li><p><strong>Enable metrics export (if Collector supports it)</strong>:</p>
<pre><code class="lang-bash">  -Dotel.metrics.exporter=otlp
</code></pre>
</li>
<li><p><strong>Remote config via environment variables</strong>:</p>
<pre><code class="lang-bash">  <span class="hljs-built_in">export</span> OTEL_TRACES_SAMPLER=always_on
</code></pre>
</li>
</ul>
<hr />
<h2 id="heading-docker-support">Docker Support</h2>
<p>If your microservice is containerized, you can mount the agent JAR and pass the Java options in your Dockerfile or entrypoint.</p>
<pre><code class="lang-Dockerfile"><span class="hljs-keyword">COPY</span><span class="bash"> opentelemetry-javaagent.jar /otel/opentelemetry-javaagent.jar</span>
<span class="hljs-keyword">ENV</span> JAVA_TOOL_OPTIONS <span class="hljs-string">"-javaagent:/otel/opentelemetry-javaagent.jar"</span>
</code></pre>
<h2 id="heading-example-with-spring-boot">Example with Spring Boot</h2>
<p>For a Spring Boot app named <code>orderservice</code>, start it with:</p>
<pre><code class="lang-bash">java -javaagent:./opentelemetry-javaagent.jar \
     -Dotel.service.name=orderservice \
     -Dotel.exporter.otlp.endpoint=http://localhost:4317 \
     -jar target/orderservice-0.0.1-SNAPSHOT.jar
</code></pre>
<p>When you set:</p>
<pre><code class="lang-bash"> -Dotel.exporter.otlp.endpoint=http://localhost:4317
</code></pre>
<p>You're telling the OpenTelemetry agent to send <strong>all telemetry signals (traces, metrics, and logs)</strong> to that <strong>single OTLP endpoint</strong> — <strong>unless you override them individually</strong>.</p>
<h3 id="heading-override-per-signal-as-we-did-previously-at-top-of-this-blog">Override Per Signal (as we did previously at top of this blog)</h3>
<p>If you want to <strong>split</strong> telemetry signals to different backends, you’d need to use:</p>
<pre><code class="lang-bash">-Dotel.exporter.otlp.traces.endpoint=http://traces-backend:4317
-Dotel.exporter.otlp.metrics.endpoint=http://metrics-backend:4317
-Dotel.exporter.otlp.logs.endpoint=http://logs-backend:4317
</code></pre>
<p>Or the environment variable equivalents:</p>
<pre><code class="lang-bash"><span class="hljs-built_in">export</span> OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://traces-backend:4317
<span class="hljs-built_in">export</span> OTEL_EXPORTER_OTLP_METRICS_ENDPOINT=http://metrics-backend:4317
<span class="hljs-built_in">export</span> OTEL_EXPORTER_OTLP_LOGS_ENDPOINT=http://logs-backend:4317
</code></pre>
<p>And just like that, you're automatically capturing traces for:</p>
<ul>
<li><p>REST controllers</p>
</li>
<li><p>JDBC queries</p>
</li>
<li><p>Redis or Kafka integrations (if supported)</p>
</li>
</ul>
<hr />
<h2 id="heading-conclusion">Conclusion</h2>
<p>Attaching the OpenTelemetry Java Agent is one of the fastest and easiest ways to get observability into your Java applications. Whether you're running Spring Boot microservices, Jakarta EE apps, or vanilla Java services — the agent gives you <strong>deep visibility with zero code changes</strong>.</p>
<p>Next steps:</p>
<ul>
<li><p>Visualize traces and metrics in Grafana or Jaeger</p>
</li>
<li><p>Add custom spans for business logic</p>
</li>
<li><p>Use OpenTelemetry Collector for exporting to multiple backends</p>
</li>
</ul>
<hr />
<h2 id="heading-useful-links">Useful Links</h2>
<ul>
<li><p><a target="_blank" href="https://github.com/open-telemetry/opentelemetry-java-instrumentation">OpenTelemetry Java Agent GitHub</a></p>
</li>
<li><p><a target="_blank" href="https://opentelemetry.io/docs/collector/">OpenTelemetry Collector</a></p>
</li>
<li><p><a target="_blank" href="https://grafana.com/oss/tempo/">Grafana Tempo</a></p>
</li>
<li><p><a target="_blank" href="https://www.jaegertracing.io/">Jaeger</a></p>
</li>
<li><p><a target="_blank" href="https://opentelemetry.io/docs/instrumentation/java/">OpenTelemetry Java Docs</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Network Abstractions: Remote Procedure Calls (RPC)]]></title><description><![CDATA[The foundation of effective and scalable solutions in the field of distributed systems is smooth communication between components. With the help of Remote…]]></description><link>https://venuemmadi.hashnode.dev/demystifying-remote-procedure-calls-rpc-a-potent-abstraction</link><guid isPermaLink="true">https://venuemmadi.hashnode.dev/demystifying-remote-procedure-calls-rpc-a-potent-abstraction</guid><category><![CDATA[#Thirft]]></category><category><![CDATA[System Design]]></category><category><![CDATA[RPC]]></category><category><![CDATA[gRPC]]></category><dc:creator><![CDATA[Venu Madhav Emmadi]]></dc:creator><pubDate>Fri, 22 Nov 2024 18:30:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1746273717480/7a290282-8c9d-478e-a05b-48468bd8d5ca.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The foundation of effective and scalable solutions in the field of distributed systems is smooth communication between components. With the help of Remote Procedure Calls (RPC), a potent abstraction, developers can create distributed systems without being constrained by the complexities of network connection.</p>
<p>This blog explains RPC's definition, operation, and practical uses, demonstrating why it's still a preferred option for developers everywhere.</p>
<hr />
<h2 id="heading-what-is-an-rpc"><strong>What is an RPC?</strong></h2>
<p>At its core, <strong>RPC (Remote Procedure Call)</strong> is a communication protocol employed by a program wishing to execute a procedure or a subroutine that is located in a different address space in most cases, on another machine, while it appears to users as if the procedure is being invoked locally.</p>
<p>In the <strong>OSI model</strong> of the RPC uses address and name spaces and spans the transport and application layers.</p>
<h3 id="heading-key-features">Key Features:</h3>
<ul>
<li><p><strong>Abstraction</strong>: Developers call remote procedures just like local functions, without coding network-level details.</p>
</li>
<li><p><strong>Interoperability</strong>: Enables seamless communication across different platforms and languages.</p>
</li>
</ul>
<p>This abstraction allows developers to focus on application design rather than the complexities of networking, such as data serialization, retries, or error handling.</p>
<hr />
<h2 id="heading-how-does-rpc-work"><strong>How Does RPC Work?</strong></h2>
<p>The RPC process encapsulates the complexities of remote communication, allowing for smooth execution. Here’s how it works:</p>
<h3 id="heading-components-of-an-rpc-system"><strong>Components of an RPC System</strong></h3>
<ol>
<li><p><strong>Client and Client Stub</strong>:<br /> The client initiates the process and sends requests using the client stub, which acts as a proxy for the remote procedure.</p>
</li>
<li><p><strong>RPC Runtime</strong>:<br /> Both client and server sides include an RPC runtime responsible for message transmission, acknowledgment, and retransmission.</p>
</li>
<li><p><strong>Server Stub and Server</strong>:<br /> The server stub unpacks the message, processes the request, and invokes the appropriate local procedure on the server.</p>
</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1734247565501/724de3ee-2f6f-4a0e-9aa7-4dae51f671f5.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-step-by-step-workflow"><strong>Step-by-Step Workflow</strong></h3>
<ol>
<li><p>The <strong>client</strong> initiates a procedure call and passes parameters to the <strong>client stub</strong>.</p>
</li>
<li><p>The <strong>client stub</strong> serializes the parameters (marshalling) into a standard format and packs them into a message.</p>
</li>
<li><p>The <strong>client-side RPC runtime</strong> sends the message over the network to the server.</p>
</li>
<li><p>The <strong>server-side RPC runtime</strong> receives the message and passes it to the <strong>server stub</strong>.</p>
</li>
<li><p>The <strong>server stub</strong> unpacks the parameters, calls the desired procedure, and executes it.</p>
</li>
<li><ol start="7">
<li><ol start="8">
<li><p>The procedure’s result is returned to the <strong>server stub</strong>, packed into a message, and sent back via the RPC runtime.</p>
<ol start="9">
<li>10 .The <strong>client-side RPC runtime</strong> receives the result, and the <strong>client stub</strong> unpacks it, returning it to the caller.</li>
</ol>
</li>
</ol>
</li>
</ol>
</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1734246786780/b1b25302-9f72-4f17-b282-9d9a352a48c7.png" alt class="image--center mx-auto" /></p>
<p>This process abstracts all network communication complexities, allowing the developer to work as though the procedure call is local.</p>
<hr />
<h2 id="heading-real-world-applications-of-rpc"><strong>Real-World Applications of RPC</strong></h2>
<p>RPCs play a important part in building versatile, high-performance frameworks. Here are a few outstanding real-world cases:</p>
<h3 id="heading-1-google"><strong>1. Google</strong></h3>
<p>Google employments RPC broadly over its disseminated frameworks, utilizing an open-source RPC system called <strong>gRPC</strong>. This system empowers effective, high-performance communication between microservices, fueling administrations like Google Look and YouTube.</p>
<h3 id="heading-2-facebook"><strong>2. Facebook</strong></h3>
<p>Facebook utilizes <strong>Thrift</strong>, an RPC system, for inter-service communication. Thrift bolsters different dialects, empowering a Python client to communicate consistently with a C++ server. It's too utilized for serializing information in capacity frameworks, upgrading interoperability and execution.</p>
<h3 id="heading-3-uber"><strong>3. Uber</strong></h3>
<p>Real-time operations like ride coordinating, area following, and driver-rider communication depend on <strong>RPC</strong>. By encouraging fast information trade between the app and servers, RPC guarantees that Uber gives responsive and dependable administrations.</p>
<hr />
<h2 id="heading-benefits-of-using-rpc"><strong>Benefits of Using RPC</strong></h2>
<ol>
<li><p><strong>Simplified Development</strong>:<br /> Developers can write distributed applications without worrying about the underlying network complexities.</p>
</li>
<li><p><strong>High Performance</strong>:<br /> Efficient data serialization and optimized communication mechanisms ensure low latency and high throughput.</p>
</li>
<li><p><strong>Cross-Platform Interoperability</strong>:<br /> Frameworks like gRPC and Thrift enable communication across different languages and platforms.</p>
</li>
</ol>
<hr />
<h2 id="heading-summary"><strong>Summary</strong></h2>
<p>Remote Procedure Calls (RPCs) rearrange the complexities of dispersed frameworks by permitting farther intelligent to seem as nearby work calls. By abstracting the subtle elements of arrange communication, RPC enables designers to center on building vigorous and versatile applications.</p>
<p>With applications traversing industries—from real-time ride-hailing frameworks to large-scale look engines—RPC remains a foundation innovation for cutting edge dispersed models.</p>
<hr />
<h3 id="heading-ready-to-harness-the-power-of-rpc">Ready to Harness the Power of RPC?</h3>
<p>Whether you’re designing microservices or building a distributed system, understanding and leveraging RPC can significantly enhance your application’s performance and scalability. Explore frameworks like <strong>gRPC</strong> or <strong>Thrift</strong> to get started today!</p>
]]></content:encoded></item><item><title><![CDATA[API Gateway vs Load Balancer: Key Differences and Use Cases]]></title><description><![CDATA[In modern distributed systems, API Gateways and Load Balancers are both essential tools for managing network traffic, but they serve distinct purposes…]]></description><link>https://venuemmadi.hashnode.dev/api-gateway-vs-load-balancer-key-differences-and-use-cases</link><guid isPermaLink="true">https://venuemmadi.hashnode.dev/api-gateway-vs-load-balancer-key-differences-and-use-cases</guid><category><![CDATA[System Design]]></category><category><![CDATA[Load Balancing]]></category><category><![CDATA[Load Balancer]]></category><category><![CDATA[API Gateway]]></category><category><![CDATA[gateway]]></category><category><![CDATA[Site Reliability Engineering]]></category><dc:creator><![CDATA[Venu Madhav Emmadi]]></dc:creator><pubDate>Sun, 08 Sep 2024 17:55:55 GMT</pubDate><content:encoded><![CDATA[<p>In modern distributed systems, <strong>API Gateways</strong> and <strong>Load Balancers</strong> are both essential tools for managing network traffic, but they serve distinct purposes. Understanding the differences between them is crucial for designing efficient and scalable architectures. This blog will explore their key differences, use cases, and how they complement each other in a distributed environment.</p>
<h3 id="heading-what-is-an-api-gateway">What is an API Gateway?</h3>
<p>An <strong>API Gateway</strong> is a server that sits between client applications and backend services. It functions as a reverse proxy to accept API requests, route them to the appropriate services, and return the correct responses. Additionally, API gateways often handle various cross-cutting concerns like authentication, rate-limiting, caching, and request transformations.</p>
<p><strong>Key Features of an API Gateway:</strong></p>
<ul>
<li><p><strong>Routing:</strong> Directs API requests to the correct backend service based on rules.</p>
</li>
<li><p><strong>Security:</strong> Handles authentication, authorization, and input validation.</p>
</li>
<li><p><strong>Rate Limiting:</strong> Controls the number of API requests from a client within a time period.</p>
</li>
<li><p><strong>Request Transformation:</strong> Transforms requests and responses as needed (e.g., protocol or payload conversion).</p>
</li>
<li><p><strong>Logging &amp; Monitoring:</strong> Tracks API calls and performance metrics.</p>
</li>
<li><p><strong>Service Aggregation:</strong> Combines responses from multiple backend services into a single response.</p>
</li>
</ul>
<p><strong>Common Use Cases for API Gateways:</strong></p>
<ul>
<li><p><strong>Microservices Architecture:</strong> API Gateways are widely used in microservices environments to decouple frontend and backend services.</p>
</li>
<li><p><strong>Security Management:</strong> They enforce security policies such as OAuth, JWT tokens, and SSL termination.</p>
</li>
<li><p><strong>Rate Limiting and Quotas:</strong> Useful for public-facing APIs to prevent abuse and control resource utilization.</p>
</li>
<li><p><strong>Content Delivery:</strong> Efficiently route client requests to backend services based on client requirements.</p>
</li>
</ul>
<h3 id="heading-what-is-a-load-balancer">What is a Load Balancer?</h3>
<p>A <strong>Load Balancer</strong> is a networking tool that distributes incoming traffic across multiple servers, ensuring that no single server becomes overwhelmed. Load balancers primarily focus on distributing network traffic to maintain high availability and reliability of services.</p>
<p><strong>Key Features of a Load Balancer:</strong></p>
<ul>
<li><p><strong>Traffic Distribution:</strong> Routes incoming traffic to healthy instances of the backend service.</p>
</li>
<li><p><strong>Health Monitoring:</strong> Constantly monitors server health to ensure requests are only routed to functioning servers.</p>
</li>
<li><p><strong>Session Persistence:</strong> Maintains user sessions by ensuring that subsequent requests from the same client go to the same server.</p>
</li>
<li><p><strong>SSL Termination:</strong> Offloads SSL decryption from backend servers, improving performance.</p>
</li>
<li><p><strong>Scalability:</strong> Facilitates horizontal scaling by adding more backend servers as needed.</p>
</li>
</ul>
<p><strong>Common Use Cases for Load Balancers:</strong></p>
<ul>
<li><p><strong>High Availability Applications:</strong> Ensures applications are available even if one or more backend servers fail.</p>
</li>
<li><p><strong>Auto-Scaling Architectures:</strong> In environments where services auto-scale based on demand, load balancers can efficiently distribute traffic to newly spawned instances.</p>
</li>
<li><p><strong>Zero Downtime Deployments:</strong> By routing traffic to healthy instances during software updates, load balancers help achieve zero-downtime deployment.</p>
</li>
<li><p><strong>Global Traffic Management:</strong> Distributes traffic across multiple geographical locations for improved performance and resilience.</p>
</li>
</ul>
<h3 id="heading-key-differences-between-api-gateway-and-load-balancer">Key Differences Between API Gateway and Load Balancer</h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Feature</td><td>API Gateway</td><td>Load Balancer</td></tr>
</thead>
<tbody>
<tr>
<td><strong>Primary Function</strong></td><td>Manages API requests and orchestrates backend services</td><td>Distributes network traffic across multiple servers</td></tr>
<tr>
<td><strong>Use Case</strong></td><td>Best suited for microservices and managing APIs</td><td>Best for balancing traffic load in high-availability architectures</td></tr>
<tr>
<td><strong>Routing</strong></td><td>Routes based on API endpoint or service</td><td>Routes based on server health and performance</td></tr>
<tr>
<td><strong>Security Features</strong></td><td>Provides authentication, authorization, and input validation</td><td>Typically doesn’t handle authentication or security</td></tr>
<tr>
<td><strong>Rate Limiting</strong></td><td>Handles rate limiting and quotas</td><td>Not responsible for rate limiting</td></tr>
<tr>
<td><strong>Session Management</strong></td><td>Can enforce session management and token-based security</td><td>Handles session persistence for the same server</td></tr>
<tr>
<td><strong>Protocol Handling</strong></td><td>Can manage multiple protocols (HTTP, HTTPS, WebSocket, etc.)</td><td>Primarily handles TCP/UDP/HTTP/HTTPS</td></tr>
<tr>
<td><strong>Service Aggregation</strong></td><td>Can aggregate multiple services into a single API response</td><td>No service aggregation; simply forwards traffic</td></tr>
<tr>
<td><strong>SSL Termination</strong></td><td>Terminates SSL for APIs</td><td>Terminates SSL at the load balancer level</td></tr>
<tr>
<td><strong>Monitoring and Logging</strong></td><td>Tracks API requests and metrics</td><td>Primarily focuses on health checks and server availability</td></tr>
</tbody>
</table>
</div><h3 id="heading-when-to-use-api-gateway-vs-load-balancer">When to Use API Gateway vs Load Balancer?</h3>
<ul>
<li><p><strong>Use API Gateway when:</strong></p>
<ul>
<li><p>You need fine-grained control over API traffic.</p>
</li>
<li><p>Security, authentication, and request routing need to be centralized.</p>
</li>
<li><p>You have a microservices architecture with multiple APIs.</p>
</li>
<li><p>You want to offload complex functions like rate-limiting, caching, and monitoring.</p>
</li>
</ul>
</li>
<li><p><strong>Use Load Balancer when:</strong></p>
<ul>
<li><p>You need to distribute traffic to maintain high availability.</p>
</li>
<li><p>Your goal is fault tolerance and horizontal scaling.</p>
</li>
<li><p>You’re managing traffic for traditional web applications or services without specific API orchestration needs.</p>
</li>
</ul>
</li>
</ul>
<h3 id="heading-combining-api-gateway-and-load-balancer">Combining API Gateway and Load Balancer</h3>
<p>In many distributed systems, API gateways and load balancers are used together to leverage their respective strengths. Here’s how they typically work together:</p>
<ul>
<li><p><strong>API Gateway</strong> is responsible for handling and routing API requests, managing API traffic, and performing security checks.</p>
</li>
<li><p><strong>Load Balancer</strong> sits behind the API Gateway and distributes traffic to the backend services, ensuring that requests are routed to healthy instances and balancing the overall load.</p>
</li>
</ul>
<p>For example, in a microservices architecture, an API Gateway could handle all incoming API traffic, applying security policies, rate limits, and transformations. The gateway could then forward requests to a Load Balancer, which ensures that the backend microservices are evenly utilized and that there is no single point of failure.</p>
<h3 id="heading-conclusion">Conclusion</h3>
<p>Both <strong>API Gateways</strong> and <strong>Load Balancers</strong> are crucial components in modern cloud-native and distributed architectures. An API Gateway is best suited for managing API traffic, providing security, and handling complex API functionalities. A Load Balancer, on the other hand, is essential for distributing traffic across multiple servers to ensure high availability and reliability. By understanding their roles and capabilities, you can use them in tandem to build scalable, secure, and resilient applications.</p>
]]></content:encoded></item><item><title><![CDATA[DaemonSet Vs Deployment Kind for Open Telemetry Collector]]></title><description><![CDATA[Efficient telemetry collection is crucial for maintaining the health and performance of applications and infrastructure in modern cloud environments. In…]]></description><link>https://venuemmadi.hashnode.dev/daemonset-vs-deployment-kind-for-open-telemetry-collector</link><guid isPermaLink="true">https://venuemmadi.hashnode.dev/daemonset-vs-deployment-kind-for-open-telemetry-collector</guid><category><![CDATA[OpenTelemetry]]></category><category><![CDATA[observability]]></category><category><![CDATA[monitoring]]></category><dc:creator><![CDATA[Venu Madhav Emmadi]]></dc:creator><pubDate>Fri, 06 Sep 2024 12:35:02 GMT</pubDate><content:encoded><![CDATA[<h3 id="heading-optimizing-telemetry-collection-with-daemonsets-and-deployments-across-two-kubernetes-clusters">Optimizing Telemetry Collection with DaemonSets and Deployments Across Two Kubernetes Clusters</h3>
<p>Efficient telemetry collection is crucial for maintaining the health and performance of applications and infrastructure in modern cloud environments. In this blog, we explore a telemetry setup involving two Kubernetes clusters: <strong>Azure Cluster1</strong> and <strong>AKS Cluster2</strong>, using both DaemonSets and Deployments to manage and aggregate telemetry data.</p>
<hr />
<h4 id="heading-1-overview-of-the-setup"><strong>1. Overview of the Setup</strong></h4>
<p><strong>Azure Cluster1</strong>:</p>
<ul>
<li><p><strong>Applications</strong>: <code>app1</code>, <code>app2</code>, and <code>app3</code> are running with the OpenTelemetry Java agent configured to send Metrics, Events, Logs, and Traces (MELT) directly to a central collector.</p>
</li>
<li><p><strong>Collector1</strong>: An OpenTelemetry Collector deployed within Azure Cluster1 to gather and forward infrastructure telemetry.</p>
</li>
</ul>
<p><strong>AKS Cluster2</strong>:</p>
<ul>
<li><strong>Collector2</strong>: A central OpenTelemetry Collector deployed in AKS Cluster2 to receive, aggregate, and process telemetry data from various sources, including both infrastructure telemetry from Azure Cluster1 application and infrastructure telemetry from AKS Cluster2.</li>
</ul>
<hr />
<h4 id="heading-2-telemetry-collection-flow"><strong>2. Telemetry Collection Flow</strong></h4>
<p><strong>Application Telemetry</strong>:</p>
<ul>
<li><strong>Direct to Central Collector</strong>: The OpenTelemetry agents in <code>app1</code>, <code>app2</code>, and <code>app3</code> send their application telemetry directly to <code>Collector2</code> in AKS Cluster2. This centralizes the application MELT data for easier aggregation and analysis.</li>
</ul>
<p><strong>Infrastructure Telemetry</strong>:</p>
<ul>
<li><p><strong>From Collector1</strong>: <code>Collector1</code> in Azure Cluster1 collects node-level metrics and logs from Azure Cluster1 and forwards this infrastructure telemetry to <code>Collector2</code> in AKS Cluster2.</p>
</li>
<li><p><strong>From DaemonSet</strong>: <code>Collector2</code> in AKS Cluster2 uses a DaemonSet to collect infrastructure telemetry from each node within AKS Cluster2.</p>
</li>
</ul>
<hr />
<h4 id="heading-3-configuration-in-azure-cluster1"><strong>3. Configuration in Azure Cluster1</strong></h4>
<p><strong>DaemonSet for Infrastructure Telemetry</strong>:</p>
<ul>
<li><p><strong>Purpose</strong>: Collects node-level metrics and logs from each node in Azure Cluster1.</p>
</li>
<li><p><strong>Configuration</strong>:</p>
<ul>
<li><p><strong>DaemonSet</strong> ensures that a collector instance runs on every node in Azure Cluster1.</p>
</li>
<li><p>Each node-specific collector gathers metrics such as CPU usage, memory consumption, and logs from the kubelet and containers.</p>
</li>
<li><p>The collected infrastructure data is forwarded to <code>Collector2</code> in AKS Cluster2.</p>
</li>
</ul>
</li>
</ul>
<p><strong>Advantages</strong>:</p>
<ul>
<li><p><strong>Comprehensive Node Coverage</strong>: Ensures that infrastructure data is collected from all nodes in Azure Cluster1.</p>
</li>
<li><p><strong>Simplicity</strong>: Focuses on infrastructure monitoring, as application telemetry is managed directly by the central collector.</p>
</li>
</ul>
<hr />
<h4 id="heading-4-configuration-in-aks-cluster2"><strong>4. Configuration in AKS Cluster2</strong></h4>
<p><strong>DaemonSet for Infrastructure Telemetry</strong>:</p>
<ul>
<li><p><strong>Purpose</strong>: Collects node-level metrics and logs from each node in AKS Cluster2.</p>
</li>
<li><p><strong>Configuration</strong>:</p>
<ul>
<li><p><strong>DaemonSet</strong> ensures that a collector instance is running on every node in AKS Cluster2.</p>
</li>
<li><p>Gathers metrics like CPU, memory, and other node-level data.</p>
</li>
</ul>
</li>
</ul>
<p><strong>Deployment for Centralized Aggregation</strong>:</p>
<ul>
<li><p><strong>Purpose</strong>: Acts as the central collector for application telemetry and aggregates data from multiple sources.</p>
</li>
<li><p><strong>Configuration</strong>:</p>
<ul>
<li><p><strong>Deployment</strong> scales horizontally to handle the influx of telemetry data from <code>Collector1</code> and directly from the application agents in Azure Cluster1.</p>
</li>
<li><p><strong>Responsibilities</strong>:</p>
<ul>
<li><p>Aggregates application MELT from <code>app1</code>, <code>app2</code>, and <code>app3</code>.</p>
</li>
<li><p>Processes infrastructure telemetry received from <code>Collector1</code> and from the DaemonSet running in AKS Cluster2.</p>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<p><strong>Advantages</strong>:</p>
<ul>
<li><p><strong>Centralized Processing</strong>: Efficiently manages and processes all telemetry data from multiple sources.</p>
</li>
<li><p><strong>Scalability</strong>: Handles a large volume of telemetry data with horizontal scaling.</p>
</li>
</ul>
<hr />
<h4 id="heading-5-summary"><strong>5. Summary</strong></h4>
<p>In this optimized telemetry setup:</p>
<ul>
<li><p><strong>Azure Cluster1</strong>:</p>
<ul>
<li><p><strong>DaemonSet</strong>: Used to collect node-specific infrastructure telemetry.</p>
</li>
<li><p><strong>Deployment</strong>: Not needed in this cluster, as application telemetry is handled directly by <code>Collector2</code>.</p>
</li>
</ul>
</li>
<li><p><strong>AKS Cluster2</strong>:</p>
<ul>
<li><p><strong>DaemonSet</strong>: Used to collect node-specific infrastructure telemetry from AKS Cluster2.</p>
</li>
<li><p><strong>Deployment</strong>: Used as the central collector to aggregate and process both application telemetry from Azure Cluster1 and infrastructure telemetry from both clusters.</p>
</li>
</ul>
</li>
</ul>
<p>This configuration ensures comprehensive monitoring and efficient telemetry management across both clusters, leveraging Kubernetes' capabilities to maintain robust observability.</p>
<hr />
]]></content:encoded></item><item><title><![CDATA[3.9 - Template Method Pattern : Behavioral Design Patterns]]></title><description><![CDATA[The Template Method Pattern is a behavioral design pattern that defines the skeleton or framework of an algorithm in a method, called the template method…]]></description><link>https://venuemmadi.hashnode.dev/39-template-method-pattern-behavioral-design-patterns</link><guid isPermaLink="true">https://venuemmadi.hashnode.dev/39-template-method-pattern-behavioral-design-patterns</guid><category><![CDATA[template method pattern]]></category><category><![CDATA[design patterns]]></category><category><![CDATA[behavioural patterns]]></category><category><![CDATA[Programming Blogs]]></category><category><![CDATA[Java]]></category><category><![CDATA[System Design]]></category><category><![CDATA[low level design]]></category><dc:creator><![CDATA[Venu Madhav Emmadi]]></dc:creator><pubDate>Sat, 24 Aug 2024 18:30:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1746296426204/7b5b12e0-2dc0-45d7-a9d6-690e2f3b9a5f.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The <strong>Template Method Pattern</strong> is a behavioral design pattern that defines the skeleton or framework of an algorithm in a method, called the template method. While the main structure of the algorithm is defined in the superclass, specific steps of the algorithm are left to be implemented by subclasses. This allows subclasses to override or extend certain parts of the algorithm without changing its overall structure.</p>
<p>The main idea behind this pattern is to break down complex algorithms into steps, some of which are fixed in the base class, while others are flexible and open for customization by subclasses.</p>
<h3 id="heading-key-components-of-the-template-method-pattern">Key Components of the Template Method Pattern</h3>
<ol>
<li><p><strong>Abstract Class (Base Class)</strong>: The abstract class contains the <strong>template method</strong>, which defines the order of execution for the steps of an algorithm. Some of these steps may be abstract, requiring subclasses to provide their specific implementations.</p>
</li>
<li><p><strong>Concrete Class (Derived Class)</strong>: The concrete class inherits from the abstract class and provides specific implementations for the abstract methods that the base class defines. It determines how certain steps are executed.</p>
</li>
<li><p><strong>Template Method</strong>: This method contains the fixed steps of the algorithm, but it allows subclasses to define the implementation of some steps by overriding specific methods.</p>
</li>
</ol>
<h3 id="heading-example-of-template-method-pattern">Example of Template Method Pattern</h3>
<p>Let's look at an example to understand how the Template Method Pattern works in practice.</p>
<h4 id="heading-1-abstract-class-defining-the-template">1. Abstract Class Defining the Template</h4>
<p>In this example, we have an abstract class <code>BaseClass</code> that defines the structure of the algorithm. The method <code>executeSteps()</code> is the template method that defines the sequence of operations (<code>operationA()</code>, <code>operationB()</code>, and <code>operationC()</code>).</p>
<pre><code class="lang-java"><span class="hljs-comment">// Abstract class defining the template</span>
<span class="hljs-keyword">abstract</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">BaseClass</span> </span>{

    <span class="hljs-comment">// Template method defining the sequence of operations</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">executeSteps</span><span class="hljs-params">()</span> </span>{
        operationA();
        operationB();
        operationC();
    }

    <span class="hljs-comment">// Abstract methods to be implemented by subclasses</span>
    <span class="hljs-function"><span class="hljs-keyword">protected</span> <span class="hljs-keyword">abstract</span> <span class="hljs-keyword">void</span> <span class="hljs-title">operationA</span><span class="hljs-params">()</span></span>;
    <span class="hljs-function"><span class="hljs-keyword">protected</span> <span class="hljs-keyword">abstract</span> <span class="hljs-keyword">void</span> <span class="hljs-title">operationB</span><span class="hljs-params">()</span></span>;
    <span class="hljs-function"><span class="hljs-keyword">protected</span> <span class="hljs-keyword">abstract</span> <span class="hljs-keyword">void</span> <span class="hljs-title">operationC</span><span class="hljs-params">()</span></span>;
}
</code></pre>
<p>Here, the <code>executeSteps()</code> method defines the order in which operations will be executed. However, it doesn't specify the details of the operations themselves. These details are left to be defined by subclasses.</p>
<h4 id="heading-2-concrete-class-implementing-the-template">2. Concrete Class Implementing the Template</h4>
<p>Next, we have a <code>SpecificClass</code> that extends <code>BaseClass</code> and provides concrete implementations for <code>operationA()</code>, <code>operationB()</code>, and <code>operationC()</code>.</p>
<pre><code class="lang-java"><span class="hljs-comment">// Concrete class implementing the template</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">SpecificClass</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">BaseClass</span> </span>{

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">protected</span> <span class="hljs-keyword">void</span> <span class="hljs-title">operationA</span><span class="hljs-params">()</span> </span>{
        System.out.println(<span class="hljs-string">"Executing Operation A"</span>);
    }

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">protected</span> <span class="hljs-keyword">void</span> <span class="hljs-title">operationB</span><span class="hljs-params">()</span> </span>{
        System.out.println(<span class="hljs-string">"Executing Operation B"</span>);
    }

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">protected</span> <span class="hljs-keyword">void</span> <span class="hljs-title">operationC</span><span class="hljs-params">()</span> </span>{
        System.out.println(<span class="hljs-string">"Executing Operation C"</span>);
    }
}
</code></pre>
<p>In this class, <code>operationA()</code>, <code>operationB()</code>, and <code>operationC()</code> are defined with specific behaviors. Whenever the template method <code>executeSteps()</code> is called, it will execute the operations in the defined sequence.</p>
<h4 id="heading-3-main-class-to-run-the-template-method">3. Main Class to Run the Template Method</h4>
<p>Finally, we have the <code>Main</code> class that demonstrates how the template method is used.</p>
<pre><code class="lang-java"><span class="hljs-comment">// Main class to run the template method</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Main</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span><span class="hljs-params">(String[] args)</span> </span>{
        BaseClass process = <span class="hljs-keyword">new</span> SpecificClass();
        process.executeSteps();  <span class="hljs-comment">// Executes the steps in the predefined order</span>
    }
}
</code></pre>
<p>When <code>process.executeSteps()</code> is called, it will trigger the execution of <code>operationA()</code>, <code>operationB()</code>, and <code>operationC()</code> in the order defined by the template method in <code>BaseClass</code>.</p>
<h3 id="heading-output-of-the-program">Output of the Program:</h3>
<pre><code class="lang-java">Executing Operation A
Executing Operation B
Executing Operation C
</code></pre>
<h3 id="heading-key-concepts-of-the-template-method-pattern">Key Concepts of the Template Method Pattern</h3>
<ol>
<li><p><strong>Predefined Algorithm Flow</strong>: The base class defines the structure and flow of the algorithm. This ensures that the algorithm remains consistent across different implementations.</p>
</li>
<li><p><strong>Flexibility in Subclasses</strong>: The details of specific steps in the algorithm are left to be implemented by subclasses. This allows for flexibility and customization without altering the overall flow.</p>
</li>
<li><p><strong>Code Reusability</strong>: By placing the common structure in the base class, the template method pattern promotes code reuse. Subclasses only need to implement specific variations of certain steps.</p>
</li>
</ol>
<h3 id="heading-benefits-of-the-template-method-pattern">Benefits of the Template Method Pattern</h3>
<ol>
<li><p><strong>Ensures Algorithm Consistency</strong>: The template method guarantees that the steps of the algorithm are executed in a specific order. Subclasses can change specific behaviors without altering the sequence of execution.</p>
</li>
<li><p><strong>Promotes Code Reuse</strong>: Common parts of the algorithm are defined in the base class, while variations can be handled in subclasses. This prevents code duplication.</p>
</li>
<li><p><strong>Easier Maintenance</strong>: The core logic is centralized in the base class, making it easier to maintain. Any changes to the overall structure of the algorithm are made in the base class, while changes to specific steps can be handled in subclasses.</p>
</li>
<li><p><strong>Flexibility and Extensibility</strong>: Subclasses can extend the base algorithm by overriding specific methods, allowing for tailored behavior without modifying the entire process.</p>
</li>
</ol>
<h3 id="heading-drawbacks-of-the-template-method-pattern">Drawbacks of the Template Method Pattern</h3>
<ol>
<li><p><strong>Inheritance-Based</strong>: The pattern heavily relies on inheritance, which can limit flexibility when dealing with complex object hierarchies. Using inheritance might lead to tight coupling between base and derived classes.</p>
</li>
<li><p><strong>Overridden Methods</strong>: If not properly documented, the flow of the algorithm can be harder to follow, as the method behavior can vary depending on which subclass is instantiated.</p>
</li>
<li><p><strong>Rigid Structure</strong>: While the pattern ensures consistency in the algorithm's flow, it might become too rigid for scenarios where greater customization or more flexible control over the algorithm is needed.</p>
</li>
</ol>
<h3 id="heading-real-world-use-cases-of-the-template-method-pattern">Real-World Use Cases of the Template Method Pattern</h3>
<ol>
<li><p><strong>Framework Design</strong>: In software frameworks, the template method pattern is widely used to provide hooks for customizing behavior without altering the overall workflow of the system. For example, GUI frameworks often define template methods for rendering windows, allowing subclasses to define specific behaviors like drawing custom components.</p>
</li>
<li><p><strong>Game Development</strong>: In game development, game engines might use the template method pattern for defining the game loop. The engine might have predefined steps such as updating physics, rendering, and handling input, but specific game behaviors (like enemy AI or player control) can be customized by overriding certain methods.</p>
</li>
<li><p><strong>Document Generation</strong>: In scenarios like generating documents or reports, the template method pattern can define a general process (such as opening, writing, and closing the document). Specific document types (like PDFs or Excel files) can be customized by subclassing and overriding methods for formatting and content.</p>
</li>
</ol>
<h3 id="heading-conclusion">Conclusion</h3>
<p>The <strong>Template Method Pattern</strong> is a powerful tool for defining the structure of an algorithm while allowing subclasses to implement specific behaviors. By enforcing a consistent order of execution for the algorithm’s steps, the pattern promotes code reuse and flexibility. At the same time, it keeps the codebase more maintainable by separating the structure of an algorithm from its concrete implementation details. Whether it's used in frameworks, game development, or document generation, this pattern provides a structured yet flexible way to manage complex algorithms in software design.</p>
]]></content:encoded></item><item><title><![CDATA[3.8 - Memento Pattern : Behavioral Design Patterns]]></title><description><![CDATA[The Memento Pattern is a behavioral design pattern that allows an object to save its state and restore it later without exposing its internal structure…]]></description><link>https://venuemmadi.hashnode.dev/38-memento-pattern-behavioral-design-patterns</link><guid isPermaLink="true">https://venuemmadi.hashnode.dev/38-memento-pattern-behavioral-design-patterns</guid><category><![CDATA[memento pattern]]></category><category><![CDATA[design patterns]]></category><category><![CDATA[behavioural patterns]]></category><category><![CDATA[System Design]]></category><category><![CDATA[low level design]]></category><dc:creator><![CDATA[Venu Madhav Emmadi]]></dc:creator><pubDate>Sat, 10 Aug 2024 18:30:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1746296369257/04e26963-ed20-4122-98b6-cf2eb97fa4d9.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The <strong>Memento Pattern</strong> is a behavioral design pattern that allows an object to save its state and restore it later without exposing its internal structure. This pattern is useful when you need to implement undo/redo functionality or save checkpoints in an application.</p>
<p>In simpler terms, the Memento Pattern captures and stores the current state of an object so that it can be reverted to that state later. The core concept is to preserve an object's state without breaking encapsulation.</p>
<h3 id="heading-key-components-of-the-memento-pattern">Key Components of the Memento Pattern:</h3>
<ol>
<li><p><strong>Memento</strong>: The memento object stores the internal state of the originator. It doesn't allow any operations or modifications to the state stored, ensuring immutability.</p>
</li>
<li><p><strong>Originator</strong>: The originator is the object whose state needs to be saved. It can create mementos and use them to restore its previous state.</p>
</li>
<li><p><strong>CareTaker</strong>: The caretaker is responsible for storing and managing mementos. It doesn’t modify or operate on the memento’s contents.</p>
</li>
</ol>
<h3 id="heading-code-example">Code Example</h3>
<p>Let’s walk through an example of the Memento Pattern using modified class names and function names for clarity.</p>
<h4 id="heading-1-memento-class">1. <strong>Memento Class</strong></h4>
<p>The <code>Snapshot</code> class stores the internal state of the <code>Document</code>. It provides a way to retrieve the stored state but doesn’t allow changes to the state.</p>
<pre><code class="lang-java"><span class="hljs-comment">// Memento class</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Snapshot</span> </span>{
    <span class="hljs-keyword">private</span> String content;

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">Snapshot</span><span class="hljs-params">(String content)</span> </span>{
        <span class="hljs-keyword">this</span>.content = content;
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">getContent</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-keyword">return</span> content;
    }
}
</code></pre>
<h4 id="heading-2-originator-class">2. <strong>Originator Class</strong></h4>
<p>The <code>Document</code> class (acting as the originator) has a <code>content</code> field representing the current state. It can save the current content to a snapshot and restore content from a snapshot.</p>
<pre><code class="lang-java"><span class="hljs-comment">// Originator class</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Document</span> </span>{
    <span class="hljs-keyword">private</span> String content;

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setContent</span><span class="hljs-params">(String content)</span> </span>{
        <span class="hljs-keyword">this</span>.content = content;
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">getContent</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-keyword">return</span> content;
    }

    <span class="hljs-comment">// Saves the current state into a snapshot (memento)</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> Snapshot <span class="hljs-title">createSnapshot</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> Snapshot(content);
    }

    <span class="hljs-comment">// Restores the content from a snapshot (memento)</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">restoreFromSnapshot</span><span class="hljs-params">(Snapshot snapshot)</span> </span>{
        content = snapshot.getContent();
    }
}
</code></pre>
<h4 id="heading-3-client-code">3. <strong>Client Code</strong></h4>
<p>The <code>MementoPatternDemo</code> class demonstrates saving and restoring the state using the Memento Pattern.</p>
<pre><code class="lang-java"><span class="hljs-comment">// Client</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MementoPatternDemo</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span><span class="hljs-params">(String[] args)</span> </span>{
        Document document = <span class="hljs-keyword">new</span> Document();

        <span class="hljs-comment">// Set initial state</span>
        document.setContent(<span class="hljs-string">"Initial Draft"</span>);

        <span class="hljs-comment">// Save the current state</span>
        Snapshot snapshot = document.createSnapshot();

        <span class="hljs-comment">// Modify the state</span>
        document.setContent(<span class="hljs-string">"Updated Draft"</span>);
        System.out.println(<span class="hljs-string">"Current Content: "</span> + document.getContent());  <span class="hljs-comment">// Output: Updated Draft</span>

        <span class="hljs-comment">// Restore to the previous state</span>
        document.restoreFromSnapshot(snapshot);
        System.out.println(<span class="hljs-string">"Restored Content: "</span> + document.getContent());  <span class="hljs-comment">// Output: Initial Draft</span>
    }
}
</code></pre>
<h3 id="heading-explanation">Explanation:</h3>
<ol>
<li><p><strong>Snapshot (Memento)</strong>: This class represents the memento object that stores the <code>content</code> of the <code>Document</code>. Once created, the snapshot cannot be modified to ensure immutability.</p>
</li>
<li><p><strong>Document (Originator)</strong>: This class represents the originator that has a state (<code>content</code>). It can create snapshots to save its current state and restore from snapshots when needed.</p>
</li>
<li><p><strong>MementoPatternDemo (Client)</strong>: This class shows how the Memento Pattern can be used to store and restore the state of the document. It demonstrates saving the current state using a snapshot, modifying the state, and then restoring it from the saved snapshot.</p>
</li>
</ol>
<h3 id="heading-benefits-of-the-memento-pattern">Benefits of the Memento Pattern:</h3>
<ol>
<li><p><strong>Encapsulation Preservation</strong>: The memento pattern keeps the internal details of the object hidden from external classes. Only the originator has access to the internal state and can save or restore it.</p>
</li>
<li><p><strong>Undo/Redo Functionality</strong>: It’s ideal for implementing undo/redo functionality by storing multiple states and reverting to the previous states.</p>
</li>
<li><p><strong>Simplifies State Management</strong>: The pattern provides a clean way to manage and restore object states, reducing the complexity of handling state transitions manually.</p>
</li>
</ol>
<h3 id="heading-drawbacks-of-the-memento-pattern">Drawbacks of the Memento Pattern:</h3>
<ol>
<li><p><strong>Memory Usage</strong>: Storing multiple mementos can consume a significant amount of memory, especially if the state is large or there are frequent changes.</p>
</li>
<li><p><strong>Complexity with Many States</strong>: Managing a large number of mementos may become challenging if you need to handle complex state changes and history tracking.</p>
</li>
<li><p><strong>Memento Visibility</strong>: The memento object needs to be carefully managed so that it is not altered by external objects, which could break the integrity of the saved state.</p>
</li>
</ol>
<h3 id="heading-real-world-use-cases">Real-World Use Cases:</h3>
<ul>
<li><p><strong>Text Editors</strong>: Many text editors implement the undo/redo functionality using the Memento Pattern. When the user makes a change, the editor saves a snapshot of the document before the change. The user can then undo the changes and revert to a previous state.</p>
</li>
<li><p><strong>Game State Saving</strong>: In video games, the Memento Pattern can be used to save the state of the game (e.g., player position, score) and allow the player to revert to that state later.</p>
</li>
<li><p><strong>Database Transactions</strong>: Some database systems use the Memento Pattern to store the state of the database before making a transaction. In case of a failure, the system can roll back to the previous state.</p>
</li>
</ul>
<h3 id="heading-enhanced-example-caretaker-for-managing-snapshots">Enhanced Example: Caretaker for Managing Snapshots</h3>
<p>In more complex scenarios, a <strong>Caretaker</strong> class may be introduced to manage multiple snapshots. It can store a list of mementos (snapshots) and restore to a specific point.</p>
<pre><code class="lang-java"><span class="hljs-comment">// Caretaker class</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Caretaker</span> </span>{
    <span class="hljs-keyword">private</span> List&lt;Snapshot&gt; snapshotHistory = <span class="hljs-keyword">new</span> ArrayList&lt;&gt;();

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">saveSnapshot</span><span class="hljs-params">(Snapshot snapshot)</span> </span>{
        snapshotHistory.add(snapshot);
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> Snapshot <span class="hljs-title">getSnapshot</span><span class="hljs-params">(<span class="hljs-keyword">int</span> index)</span> </span>{
        <span class="hljs-keyword">return</span> snapshotHistory.get(index);
    }
}

<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MementoPatternWithCaretakerDemo</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span><span class="hljs-params">(String[] args)</span> </span>{
        Document document = <span class="hljs-keyword">new</span> Document();
        Caretaker caretaker = <span class="hljs-keyword">new</span> Caretaker();

        <span class="hljs-comment">// Set and save initial state</span>
        document.setContent(<span class="hljs-string">"First Draft"</span>);
        caretaker.saveSnapshot(document.createSnapshot());

        <span class="hljs-comment">// Update and save another state</span>
        document.setContent(<span class="hljs-string">"Second Draft"</span>);
        caretaker.saveSnapshot(document.createSnapshot());

        <span class="hljs-comment">// Modify content further</span>
        document.setContent(<span class="hljs-string">"Final Draft"</span>);
        System.out.println(<span class="hljs-string">"Current Content: "</span> + document.getContent());  <span class="hljs-comment">// Output: Final Draft</span>

        <span class="hljs-comment">// Restore to the second state</span>
        document.restoreFromSnapshot(caretaker.getSnapshot(<span class="hljs-number">1</span>));
        System.out.println(<span class="hljs-string">"Restored Content: "</span> + document.getContent());  <span class="hljs-comment">// Output: Second Draft</span>
    }
}
</code></pre>
<p>In this enhanced version:</p>
<ul>
<li><p><strong>Caretaker</strong> manages multiple mementos, allowing you to go back to any previous state.</p>
</li>
<li><p>The <strong>Document</strong> still handles saving and restoring states using snapshots.</p>
</li>
</ul>
<h3 id="heading-conclusion">Conclusion:</h3>
<p>The Memento Pattern is a powerful design pattern for saving and restoring the state of objects while preserving encapsulation. By using mementos (snapshots), it allows for implementing undo/redo functionality and state rollback in applications. While it introduces additional memory usage due to saved states, it simplifies state management in scenarios where state transitions are frequent and require restoration.</p>
]]></content:encoded></item><item><title><![CDATA[3.7 - Interpreter Pattern : Behavioral Design Patterns]]></title><description><![CDATA[The Interpreter Pattern is a behavioral design pattern that defines a grammatical representation for a language and provides an interpreter to evaluate…]]></description><link>https://venuemmadi.hashnode.dev/37-interpreter-pattern-behavioral-design-patterns</link><guid isPermaLink="true">https://venuemmadi.hashnode.dev/37-interpreter-pattern-behavioral-design-patterns</guid><category><![CDATA[design patterns]]></category><category><![CDATA[interpreter pattern]]></category><category><![CDATA[behavioural patterns]]></category><category><![CDATA[Java]]></category><category><![CDATA[Programming Blogs]]></category><category><![CDATA[low level design]]></category><category><![CDATA[System Design]]></category><dc:creator><![CDATA[Venu Madhav Emmadi]]></dc:creator><pubDate>Sat, 27 Jul 2024 18:30:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1746296285627/d3047ee3-6b90-4af7-a381-0fe6a37fb867.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The <strong>Interpreter Pattern</strong> is a behavioral design pattern that defines a grammatical representation for a language and provides an interpreter to evaluate sentences in that language. This pattern is used to evaluate simple expressions or sentences that belong to a particular language or grammar. The idea is to build a hierarchical structure of expressions, where each expression implements a common interface.</p>
<h3 id="heading-key-components-of-the-interpreter-pattern">Key Components of the Interpreter Pattern:</h3>
<ol>
<li><p><strong>Abstract Expression</strong>: Declares the <code>interpret()</code> method common to all expressions.</p>
</li>
<li><p><strong>Terminal Expression</strong>: Implements the <code>interpret()</code> method to evaluate individual parts of the language, such as numbers or constants.</p>
</li>
<li><p><strong>Non-terminal Expression</strong>: Represents operators (such as addition or subtraction) that combine terminal expressions. It also implements the <code>interpret()</code> method.</p>
</li>
<li><p><strong>Client</strong>: Builds the syntax tree representing the sentence to be interpreted and evaluates the sentence by calling <code>interpret()</code> on the root expression.</p>
</li>
</ol>
<p>The pattern is typically used in situations where a grammar defines how expressions are evaluated, such as mathematical expressions, programming language interpreters, or Boolean logic evaluators.</p>
<h3 id="heading-code-example">Code Example</h3>
<p>Here’s a practical example of the Interpreter Pattern using modified class and function names for better clarity.</p>
<h4 id="heading-1-abstract-expression">1. <strong>Abstract Expression</strong></h4>
<p>The <code>MathExpression</code> interface declares the <code>evaluate()</code> method for all expressions.</p>
<pre><code class="lang-java"><span class="hljs-comment">// Abstract Expression</span>
<span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">MathExpression</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">evaluate</span><span class="hljs-params">()</span></span>;
}
</code></pre>
<h4 id="heading-2-terminal-expression">2. <strong>Terminal Expression</strong></h4>
<p>The <code>Constant</code> class is a terminal expression that represents a number. It implements the <code>evaluate()</code> method, which simply returns the value of the number.</p>
<pre><code class="lang-java"><span class="hljs-comment">// Terminal Expression</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Constant</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">MathExpression</span> </span>{
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span> value;

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">Constant</span><span class="hljs-params">(<span class="hljs-keyword">int</span> value)</span> </span>{
        <span class="hljs-keyword">this</span>.value = value;
    }

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">evaluate</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-keyword">return</span> value;
    }
}
</code></pre>
<h4 id="heading-3-non-terminal-expression">3. <strong>Non-terminal Expression</strong></h4>
<p>The <code>Addition</code> class is a non-terminal expression that represents the addition operation. It takes two <code>MathExpression</code> objects (which could be either constants or other expressions) and adds their results.</p>
<pre><code class="lang-java"><span class="hljs-comment">// Non-terminal Expression</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Addition</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">MathExpression</span> </span>{
    <span class="hljs-keyword">private</span> MathExpression leftExpression;
    <span class="hljs-keyword">private</span> MathExpression rightExpression;

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">Addition</span><span class="hljs-params">(MathExpression leftExpression, MathExpression rightExpression)</span> </span>{
        <span class="hljs-keyword">this</span>.leftExpression = leftExpression;
        <span class="hljs-keyword">this</span>.rightExpression = rightExpression;
    }

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">evaluate</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-keyword">return</span> leftExpression.evaluate() + rightExpression.evaluate();
    }
}
</code></pre>
<h4 id="heading-4-client">4. <strong>Client</strong></h4>
<p>The <code>InterpreterDemo</code> class demonstrates how to build an expression tree and interpret a mathematical expression.</p>
<pre><code class="lang-java"><span class="hljs-comment">// Client</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">InterpreterDemo</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span><span class="hljs-params">(String[] args)</span> </span>{
        <span class="hljs-comment">// (10 + (2 + 3))</span>
        MathExpression expression = <span class="hljs-keyword">new</span> Addition(<span class="hljs-keyword">new</span> Constant(<span class="hljs-number">10</span>), <span class="hljs-keyword">new</span> Addition(<span class="hljs-keyword">new</span> Constant(<span class="hljs-number">2</span>), <span class="hljs-keyword">new</span> Constant(<span class="hljs-number">3</span>)));

        <span class="hljs-keyword">int</span> result = expression.evaluate();
        System.out.println(<span class="hljs-string">"Result: "</span> + result);  <span class="hljs-comment">// Output: Result: 15</span>
    }
}
</code></pre>
<h3 id="heading-explanation">Explanation:</h3>
<ol>
<li><p><strong>MathExpression Interface</strong>: This interface defines the <code>evaluate()</code> method, which all concrete expressions (like numbers or operators) must implement.</p>
</li>
<li><p><strong>Constant</strong>: The <code>Constant</code> class is a terminal expression representing a number. Its <code>evaluate()</code> method returns the value of the number stored in the instance.</p>
</li>
<li><p><strong>Addition</strong>: The <code>Addition</code> class is a non-terminal expression that takes two expressions as its operands. When its <code>evaluate()</code> method is called, it evaluates the left and right operands and returns their sum.</p>
</li>
<li><p><strong>InterpreterDemo (Client)</strong>: This class constructs an expression tree and interprets the mathematical expression by calling <code>evaluate()</code> on the root expression. In this case, the tree represents the expression <code>10 + (2 + 3)</code>.</p>
</li>
</ol>
<h3 id="heading-benefits-of-the-interpreter-pattern">Benefits of the Interpreter Pattern:</h3>
<ol>
<li><p><strong>Easy to Extend</strong>: You can easily extend the language by adding new non-terminal expressions (e.g., subtraction, multiplication) without modifying the existing structure.</p>
</li>
<li><p><strong>Modular Structure</strong>: The pattern encourages the use of a modular and hierarchical structure, making it easy to understand and maintain.</p>
</li>
<li><p><strong>Reusable Expressions</strong>: Common expressions (like numbers or basic operations) can be reused in multiple parts of the syntax tree.</p>
</li>
</ol>
<h3 id="heading-drawbacks-of-the-interpreter-pattern">Drawbacks of the Interpreter Pattern:</h3>
<ol>
<li><p><strong>Complexity</strong>: For complex grammars or expressions, this pattern can lead to a large number of classes, making the code harder to maintain.</p>
</li>
<li><p><strong>Performance</strong>: The recursive nature of the pattern (where expressions call <code>interpret()</code> on their children) can lead to performance issues if the expression tree becomes too large or deep.</p>
</li>
</ol>
<h3 id="heading-real-world-use-cases">Real-World Use Cases:</h3>
<ul>
<li><p><strong>Mathematical Expression Evaluators</strong>: Many calculators and tools use the interpreter pattern to evaluate mathematical expressions like <code>2 + 3 * (5 - 1)</code>.</p>
</li>
<li><p><strong>Query Interpreters</strong>: In systems like SQL engines or search engines, queries are often interpreted using the interpreter pattern.</p>
</li>
<li><p><strong>Configuration Languages</strong>: Systems that need to parse and interpret configuration languages, like JSON or XML, can use this pattern.</p>
</li>
<li><p><strong>Compilers and Interpreters</strong>: Programming language interpreters use this pattern to evaluate or compile code.</p>
</li>
</ul>
<h3 id="heading-example-with-more-operations">Example with More Operations:</h3>
<p>We can easily extend the current example to handle subtraction, multiplication, or division by creating new non-terminal expression classes.</p>
<pre><code class="lang-java"><span class="hljs-comment">// Non-terminal Expression for Subtraction</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Subtraction</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">MathExpression</span> </span>{
    <span class="hljs-keyword">private</span> MathExpression leftExpression;
    <span class="hljs-keyword">private</span> MathExpression rightExpression;

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">Subtraction</span><span class="hljs-params">(MathExpression leftExpression, MathExpression rightExpression)</span> </span>{
        <span class="hljs-keyword">this</span>.leftExpression = leftExpression;
        <span class="hljs-keyword">this</span>.rightExpression = rightExpression;
    }

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">evaluate</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-keyword">return</span> leftExpression.evaluate() - rightExpression.evaluate();
    }
}
</code></pre>
<p>Now, we can combine different operations:</p>
<pre><code class="lang-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">InterpreterDemo</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span><span class="hljs-params">(String[] args)</span> </span>{
        <span class="hljs-comment">// (10 + (2 - 3))</span>
        MathExpression expression = <span class="hljs-keyword">new</span> Addition(<span class="hljs-keyword">new</span> Constant(<span class="hljs-number">10</span>), <span class="hljs-keyword">new</span> Subtraction(<span class="hljs-keyword">new</span> Constant(<span class="hljs-number">2</span>), <span class="hljs-keyword">new</span> Constant(<span class="hljs-number">3</span>)));

        <span class="hljs-keyword">int</span> result = expression.evaluate();
        System.out.println(<span class="hljs-string">"Result: "</span> + result);  <span class="hljs-comment">// Output: Result: 9</span>
    }
}
</code></pre>
<h3 id="heading-conclusion">Conclusion:</h3>
<p>The Interpreter Pattern provides a structured way to evaluate and interpret expressions or sentences in a specific language or grammar. By defining individual expression types (like constants and operations), this pattern makes it easy to evaluate complex expressions while keeping the structure modular and extensible. Although it might not be the most efficient pattern for large or complex systems, it works well for simple grammars and scenarios where expressions need to be evaluated at runtime.</p>
]]></content:encoded></item><item><title><![CDATA[3.6 - Visitor Pattern : Behavioral Design Patterns]]></title><description><![CDATA[The Visitor Pattern is a behavioral design pattern that allows adding new operations to a set of objects (elements) without modifying their structure. The…]]></description><link>https://venuemmadi.hashnode.dev/36-visitor-pattern-behavioral-design-patterns</link><guid isPermaLink="true">https://venuemmadi.hashnode.dev/36-visitor-pattern-behavioral-design-patterns</guid><category><![CDATA[design patterns]]></category><category><![CDATA[visitor-pattern]]></category><category><![CDATA[behavioural patterns]]></category><category><![CDATA[Java]]></category><category><![CDATA[Programming Blogs]]></category><dc:creator><![CDATA[Venu Madhav Emmadi]]></dc:creator><pubDate>Sat, 20 Jul 2024 18:30:00 GMT</pubDate><content:encoded><![CDATA[<p>The <strong>Visitor Pattern</strong> is a behavioral design pattern that allows adding new operations to a set of objects (elements) without modifying their structure. The pattern involves creating a visitor class that implements operations for different types of objects. This pattern promotes open/closed principle: the element classes remain unchanged, and new operations can be added via new visitor implementations.</p>
<p>This pattern is particularly useful when dealing with objects that belong to different classes but share common operations, as it separates the algorithm from the object structure.</p>
<h3 id="heading-key-components-of-the-visitor-pattern">Key Components of the Visitor Pattern:</h3>
<ol>
<li><p><strong>Visitor Interface</strong>: Declares a visit method for each type of element in the system.</p>
</li>
<li><p><strong>Concrete Visitor</strong>: Implements the visit operations for each element type.</p>
</li>
<li><p><strong>Element Interface</strong>: Defines an <code>accept()</code> method that takes a visitor as an argument.</p>
</li>
<li><p><strong>Concrete Elements</strong>: Implement the <code>accept()</code> method, which calls the appropriate <code>visit()</code> method on the visitor object.</p>
</li>
<li><p><strong>Client</strong>: Uses the visitor to apply different operations on the elements.</p>
</li>
</ol>
<h3 id="heading-code-example">Code Example</h3>
<p>Here’s an implementation of the Visitor Pattern using renamed class and function names for better understanding.</p>
<h4 id="heading-1-visitor-interface">1. <strong>Visitor Interface</strong></h4>
<p>The <code>ShapeVisitor</code> interface declares visit methods for different types of shapes.</p>
<pre><code class="lang-java"><span class="hljs-comment">// Visitor Interface</span>
<span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">ShapeVisitor</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">calculate</span><span class="hljs-params">(CircleShape circle)</span></span>;
    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">calculate</span><span class="hljs-params">(SquareShape square)</span></span>;
}
</code></pre>
<h4 id="heading-2-concrete-visitor">2. <strong>Concrete Visitor</strong></h4>
<p>The <code>AreaCalculatorVisitor</code> class implements the <code>ShapeVisitor</code> interface and calculates the area of each shape.</p>
<pre><code class="lang-java"><span class="hljs-comment">// Concrete Visitor</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">AreaCalculatorVisitor</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">ShapeVisitor</span> </span>{
    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">calculate</span><span class="hljs-params">(CircleShape circle)</span> </span>{
        <span class="hljs-keyword">double</span> area = Math.PI * circle.getRadius() * circle.getRadius();
        System.out.println(<span class="hljs-string">"Area of Circle: "</span> + area);
    }

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">calculate</span><span class="hljs-params">(SquareShape square)</span> </span>{
        <span class="hljs-keyword">double</span> area = square.getSide() * square.getSide();
        System.out.println(<span class="hljs-string">"Area of Square: "</span> + area);
    }
}
</code></pre>
<h4 id="heading-3-element-interface">3. <strong>Element Interface</strong></h4>
<p>The <code>GeometricShape</code> interface defines the <code>accept()</code> method that will be used by the visitor.</p>
<pre><code class="lang-java"><span class="hljs-comment">// Element Interface</span>
<span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">GeometricShape</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">accept</span><span class="hljs-params">(ShapeVisitor visitor)</span></span>;
}
</code></pre>
<h4 id="heading-4-concrete-elements">4. <strong>Concrete Elements</strong></h4>
<p>The <code>CircleShape</code> and <code>SquareShape</code> classes implement the <code>GeometricShape</code> interface and their respective <code>accept()</code> methods.</p>
<pre><code class="lang-java"><span class="hljs-comment">// Concrete Element - Circle</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">CircleShape</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">GeometricShape</span> </span>{
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">double</span> radius;

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">CircleShape</span><span class="hljs-params">(<span class="hljs-keyword">double</span> radius)</span> </span>{
        <span class="hljs-keyword">this</span>.radius = radius;
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">double</span> <span class="hljs-title">getRadius</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-keyword">return</span> radius;
    }

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">accept</span><span class="hljs-params">(ShapeVisitor visitor)</span> </span>{
        visitor.calculate(<span class="hljs-keyword">this</span>);  <span class="hljs-comment">// Pass the CircleShape object to the visitor</span>
    }
}

<span class="hljs-comment">// Concrete Element - Square</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">SquareShape</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">GeometricShape</span> </span>{
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">double</span> side;

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">SquareShape</span><span class="hljs-params">(<span class="hljs-keyword">double</span> side)</span> </span>{
        <span class="hljs-keyword">this</span>.side = side;
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">double</span> <span class="hljs-title">getSide</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-keyword">return</span> side;
    }

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">accept</span><span class="hljs-params">(ShapeVisitor visitor)</span> </span>{
        visitor.calculate(<span class="hljs-keyword">this</span>);  <span class="hljs-comment">// Pass the SquareShape object to the visitor</span>
    }
}
</code></pre>
<h4 id="heading-5-client">5. <strong>Client</strong></h4>
<p>The <code>VisitorDemo</code> class demonstrates how to use the visitor pattern to calculate areas of different shapes.</p>
<pre><code class="lang-java"><span class="hljs-comment">// Client Class</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">VisitorDemo</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span><span class="hljs-params">(String[] args)</span> </span>{
        <span class="hljs-comment">// Array of geometric shapes</span>
        GeometricShape[] shapes = { 
            <span class="hljs-keyword">new</span> CircleShape(<span class="hljs-number">5.0</span>), 
            <span class="hljs-keyword">new</span> SquareShape(<span class="hljs-number">4.0</span>) 
        };

        <span class="hljs-comment">// Create the visitor object</span>
        ShapeVisitor areaCalculator = <span class="hljs-keyword">new</span> AreaCalculatorVisitor();

        <span class="hljs-comment">// Apply the visitor to each shape</span>
        <span class="hljs-keyword">for</span> (GeometricShape shape : shapes) {
            shape.accept(areaCalculator);
        }
    }
}
</code></pre>
<h3 id="heading-explanation">Explanation:</h3>
<ol>
<li><p><strong>ShapeVisitor Interface</strong>: This interface defines two methods, <code>calculate(CircleShape circle)</code> and <code>calculate(SquareShape square)</code>, which are used to perform specific operations on the respective shape types.</p>
</li>
<li><p><strong>AreaCalculatorVisitor</strong>: This class implements the <code>ShapeVisitor</code> interface and defines the logic for calculating the area of a circle and a square.</p>
</li>
<li><p><strong>GeometricShape Interface</strong>: This interface contains an <code>accept()</code> method, which takes a visitor object and allows the shape to delegate operations to the visitor.</p>
</li>
<li><p><strong>CircleShape and SquareShape</strong>: These classes implement the <code>GeometricShape</code> interface. The <code>accept()</code> method calls the appropriate <code>calculate()</code> method from the visitor.</p>
</li>
<li><p><strong>Client (VisitorDemo)</strong>: The client creates a collection of shapes (<code>CircleShape</code> and <code>SquareShape</code>) and applies the <code>AreaCalculatorVisitor</code> to compute the area of each shape using the <code>accept()</code> method.</p>
</li>
</ol>
<h3 id="heading-benefits-of-the-visitor-pattern">Benefits of the Visitor Pattern:</h3>
<ol>
<li><p><strong>Open/Closed Principle</strong>: The pattern allows you to add new operations (via new visitors) without modifying the existing element classes. This makes the system open for extension but closed for modification.</p>
</li>
<li><p><strong>Separation of Concerns</strong>: Visitor logic is separated from the element structure, leading to cleaner, more maintainable code. The visitor focuses on the operation, while the element focuses on its internal data.</p>
</li>
<li><p><strong>Flexibility</strong>: You can introduce new visitors to perform different operations on the same elements without altering the element's structure or code.</p>
</li>
<li><p><strong>Easy Maintenance</strong>: Since the logic for each operation is centralized in a visitor, it becomes easier to update and maintain operations related to the objects.</p>
</li>
</ol>
<h3 id="heading-real-world-use-cases">Real-World Use Cases:</h3>
<ul>
<li><p><strong>Compilers</strong>: In compilers, the visitor pattern is used to traverse abstract syntax trees (AST) and apply operations such as type checking, code generation, or optimization on different nodes.</p>
</li>
<li><p><strong>File Systems</strong>: Visitors can be used to perform operations such as searching, deleting, or compressing files in a file system.</p>
</li>
<li><p><strong>UI Components</strong>: In UI frameworks, the visitor pattern can be used to apply various actions (e.g., rendering, resizing) on different components like buttons, text fields, or windows.</p>
</li>
</ul>
<h3 id="heading-conclusion">Conclusion:</h3>
<p>The Visitor Pattern is a powerful design pattern that allows for adding new functionality to existing class hierarchies without modifying the classes themselves. By utilizing visitors, you can decouple operations from the data structures they operate on, promoting flexibility and adherence to the open/closed principle. This pattern is especially useful when you need to perform several unrelated operations across a collection of objects without altering their code.</p>
]]></content:encoded></item><item><title><![CDATA[3.5 - Iterator Pattern: Behavioral Design Patterns]]></title><description><![CDATA[The Iterator Pattern is a behavioral design pattern that provides a way to sequentially access the elements of a collection without exposing the underlying…]]></description><link>https://venuemmadi.hashnode.dev/35-iterator-pattern-behavioral-design-patterns</link><guid isPermaLink="true">https://venuemmadi.hashnode.dev/35-iterator-pattern-behavioral-design-patterns</guid><category><![CDATA[iterator design pattern]]></category><category><![CDATA[behavioural patterns]]></category><category><![CDATA[design patterns]]></category><category><![CDATA[Java]]></category><category><![CDATA[Programming Blogs]]></category><category><![CDATA[low level design]]></category><category><![CDATA[System Design]]></category><dc:creator><![CDATA[Venu Madhav Emmadi]]></dc:creator><pubDate>Sat, 13 Jul 2024 18:30:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1746296196657/6d434ee6-7851-44df-819a-af95810809c5.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The <strong>Iterator Pattern</strong> is a behavioral design pattern that provides a way to sequentially access the elements of a collection without exposing the underlying structure. It separates the process of traversal from the actual collection, promoting loose coupling between the collection and the client.</p>
<p>The Iterator Pattern is useful when you need to iterate through a collection of objects without knowing its internal structure or implementation details, making it ideal for use with lists, arrays, trees, and more.</p>
<h3 id="heading-key-components-of-the-iterator-pattern">Key Components of the Iterator Pattern:</h3>
<ol>
<li><p><strong>Collection Interface</strong>: Declares the methods to add, remove, and create an iterator for the collection.</p>
</li>
<li><p><strong>Concrete Collection</strong>: Implements the collection interface and defines how the elements are stored and managed.</p>
</li>
<li><p><strong>Iterator Interface</strong>: Declares the methods to traverse elements of a collection.</p>
</li>
<li><p><strong>Concrete Iterator</strong>: Implements the iterator interface and provides mechanisms to traverse the specific collection.</p>
</li>
<li><p><strong>Client</strong>: Uses the collection and iterator to access the elements.</p>
</li>
</ol>
<h3 id="heading-code-example">Code Example</h3>
<p>Here’s an implementation of the Iterator Pattern using renamed class and function names for clarity.</p>
<h4 id="heading-1-collection-interface">1. <strong>Collection Interface</strong></h4>
<p>The <code>ItemCollection</code> interface declares methods for adding and removing items from the collection, as well as a method to create an iterator.</p>
<pre><code class="lang-java"><span class="hljs-comment">// Collection Interface</span>
<span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">ItemCollection</span>&lt;<span class="hljs-title">T</span>&gt; </span>{
    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">addElement</span><span class="hljs-params">(T element)</span></span>;
    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">removeElement</span><span class="hljs-params">(T element)</span></span>;
    <span class="hljs-function">Iterator&lt;T&gt; <span class="hljs-title">createIterator</span><span class="hljs-params">()</span></span>;
}
</code></pre>
<h4 id="heading-2-concrete-collection">2. <strong>Concrete Collection</strong></h4>
<p>The <code>ItemList</code> class implements the <code>ItemCollection</code> interface and uses an <code>ArrayList</code> internally to store elements. It also provides functionality to create an iterator for the collection.</p>
<pre><code class="lang-java"><span class="hljs-comment">// Concrete Collection Class</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ItemList</span>&lt;<span class="hljs-title">T</span>&gt; <span class="hljs-keyword">implements</span> <span class="hljs-title">ItemCollection</span>&lt;<span class="hljs-title">T</span>&gt; </span>{
    <span class="hljs-keyword">private</span> List&lt;T&gt; elements = <span class="hljs-keyword">new</span> ArrayList&lt;&gt;();

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">addElement</span><span class="hljs-params">(T element)</span> </span>{
        elements.add(element);
    }

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">removeElement</span><span class="hljs-params">(T element)</span> </span>{
        elements.remove(element);
    }

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> Iterator&lt;T&gt; <span class="hljs-title">createIterator</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-keyword">return</span> elements.iterator(); <span class="hljs-comment">// Using Java's built-in iterator for simplicity</span>
    }
}
</code></pre>
<h4 id="heading-3-client">3. <strong>Client</strong></h4>
<p>The <code>IteratorDemo</code> class demonstrates how to use the <code>ItemList</code> and its iterator to access the elements of the collection.</p>
<pre><code class="lang-java"><span class="hljs-comment">// Client Class</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">IteratorDemo</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span><span class="hljs-params">(String[] args)</span> </span>{
        ItemCollection&lt;String&gt; myCollection = <span class="hljs-keyword">new</span> ItemList&lt;&gt;(); <span class="hljs-comment">// Creating the collection</span>

        <span class="hljs-comment">// Adding elements to the collection</span>
        myCollection.addElement(<span class="hljs-string">"Apple"</span>);
        myCollection.addElement(<span class="hljs-string">"Banana"</span>);
        myCollection.addElement(<span class="hljs-string">"Cherry"</span>);

        <span class="hljs-comment">// Creating an iterator to traverse the collection</span>
        Iterator&lt;String&gt; iterator = myCollection.createIterator();

        <span class="hljs-comment">// Using the iterator to access elements</span>
        <span class="hljs-keyword">while</span> (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
    }
}
</code></pre>
<h3 id="heading-explanation">Explanation:</h3>
<ol>
<li><p><strong>ItemCollection Interface</strong>: The interface defines three methods—<code>addElement()</code>, <code>removeElement()</code>, and <code>createIterator()</code>. The <code>createIterator()</code> method returns an iterator for traversing the elements in the collection.</p>
</li>
<li><p><strong>ItemList Class</strong>: This is the concrete implementation of the <code>ItemCollection</code> interface. It uses a list (<code>ArrayList</code>) to store the elements and provides the necessary methods to add, remove, and create an iterator.</p>
</li>
<li><p><strong>Iterator</strong>: In this case, we’re using Java’s built-in <code>Iterator</code>, which provides the basic functionality for traversing the elements in the collection. The iterator offers methods such as <code>hasNext()</code> to check if more elements are available and <code>next()</code> to access the next element.</p>
</li>
<li><p><strong>Client (IteratorDemo)</strong>: This class demonstrates how the collection and iterator work together. After adding elements to the collection, the client uses the iterator to access and print each element sequentially.</p>
</li>
</ol>
<h3 id="heading-benefits-of-the-iterator-pattern">Benefits of the Iterator Pattern:</h3>
<ol>
<li><p><strong>Decoupling</strong>: The iterator pattern decouples the client from the internal structure of the collection. The client does not need to know how the collection is implemented or how elements are stored; it simply uses the iterator to access elements.</p>
</li>
<li><p><strong>Uniform Traversal</strong>: Different types of collections (e.g., lists, arrays, trees) can provide their own iterators, allowing clients to traverse them in a uniform manner.</p>
</li>
<li><p><strong>Flexibility</strong>: Iterators provide a flexible way to traverse a collection in various ways, such as forward, backward, or even skipping elements, without changing the collection’s structure.</p>
</li>
<li><p><strong>Single Responsibility</strong>: The iterator pattern follows the Single Responsibility Principle, as the collection is responsible for storing and managing elements, while the iterator is responsible for traversal.</p>
</li>
</ol>
<h3 id="heading-real-world-use-cases">Real-World Use Cases:</h3>
<ul>
<li><p><strong>Java Collections</strong>: In Java, all the <code>Collection</code> classes (e.g., <code>ArrayList</code>, <code>HashSet</code>) use the iterator pattern. The <code>Iterator</code> interface in Java allows you to iterate over any collection without knowing its specific implementation.</p>
</li>
<li><p><strong>File Systems</strong>: Iterators can be used to traverse files and directories, providing a way to access files in a file system structure.</p>
</li>
<li><p><strong>Tree Structures</strong>: In data structures such as trees, different types of iterators (e.g., pre-order, in-order, post-order) can be used to traverse the nodes.</p>
</li>
</ul>
<h3 id="heading-conclusion">Conclusion:</h3>
<p>The Iterator Pattern is a useful tool when you want to provide a uniform way to traverse different types of collections without exposing their internal implementation. It allows for more flexible and scalable code, as it separates the collection’s responsibility for storing elements from the logic of iterating over them. By using iterators, you can create a clean, maintainable way to access elements in any type of collection.</p>
]]></content:encoded></item><item><title><![CDATA[3.4 - Chain of Responsibility Pattern: Behavioral Design Patterns]]></title><description><![CDATA[The Chain of Responsibility Pattern is a behavioral design pattern that allows multiple objects to handle a request in a chain structure. The request gets…]]></description><link>https://venuemmadi.hashnode.dev/34-chain-of-responsibility-pattern-behavioral-design-patterns</link><guid isPermaLink="true">https://venuemmadi.hashnode.dev/34-chain-of-responsibility-pattern-behavioral-design-patterns</guid><category><![CDATA[behavioural patterns]]></category><category><![CDATA[design patterns]]></category><category><![CDATA[chain of responsibility]]></category><category><![CDATA[Java]]></category><category><![CDATA[Programming Blogs]]></category><category><![CDATA[low level design]]></category><category><![CDATA[System Design]]></category><dc:creator><![CDATA[Venu Madhav Emmadi]]></dc:creator><pubDate>Sat, 06 Jul 2024 18:30:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1746296088022/74585aa4-5bc6-43fd-9383-571b90fc50bf.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The <strong>Chain of Responsibility Pattern</strong> is a behavioral design pattern that allows multiple objects to handle a request in a chain structure. The request gets passed along the chain until it is handled by one of the objects. This pattern promotes loose coupling and allows multiple handlers to process the request without the sender needing to know who will handle it.</p>
<h3 id="heading-components-of-the-chain-of-responsibility-pattern">Components of the Chain of Responsibility Pattern:</h3>
<ol>
<li><p><strong>Handler Interface</strong>: Declares the method to handle requests and allows setting the next handler in the chain.</p>
</li>
<li><p><strong>Concrete Handlers</strong>: Implement the handler interface and define the request handling logic. Each concrete handler is responsible for handling certain types of requests and passing along unhandled requests to the next handler in the chain.</p>
</li>
<li><p><strong>Request</strong>: Encapsulates the request details, such as the type or other relevant information.</p>
</li>
<li><p><strong>Client</strong>: Creates and configures the chain of handlers, then submits requests for processing.</p>
</li>
</ol>
<h3 id="heading-code-example">Code Example</h3>
<p>Below is an implementation of the Chain of Responsibility Pattern with renamed class and function names to enhance clarity.</p>
<h4 id="heading-1-handler-interface">1. <strong>Handler Interface</strong></h4>
<p>The <code>Processor</code> interface defines the methods for setting the next processor in the chain and for handling requests.</p>
<pre><code class="lang-java"><span class="hljs-comment">// Handler Interface</span>
<span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">Processor</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">setNextProcessor</span><span class="hljs-params">(Processor processor)</span></span>;
    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">processRequest</span><span class="hljs-params">(TaskRequest request)</span></span>;
}
</code></pre>
<h4 id="heading-2-concrete-handlers">2. <strong>Concrete Handlers</strong></h4>
<p>The <code>TaskHandlerA</code> and <code>TaskHandlerB</code> classes implement the <code>Processor</code> interface. Each class processes a specific type of request and forwards unhandled requests to the next processor in the chain.</p>
<pre><code class="lang-java"><span class="hljs-comment">// Concrete Handler A</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">TaskHandlerA</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Processor</span> </span>{
    <span class="hljs-keyword">private</span> Processor nextProcessor;

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setNextProcessor</span><span class="hljs-params">(Processor processor)</span> </span>{
        <span class="hljs-keyword">this</span>.nextProcessor = processor;
    }

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">processRequest</span><span class="hljs-params">(TaskRequest request)</span> </span>{
        <span class="hljs-keyword">if</span> (request.getRequestType().equals(TaskType.TYPE_A)) {
            System.out.println(<span class="hljs-string">"TaskHandlerA is processing request of Type A"</span>);
            <span class="hljs-comment">// Handle request logic here</span>
        } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (nextProcessor != <span class="hljs-keyword">null</span>) {
            nextProcessor.processRequest(request);
        }
    }
}

<span class="hljs-comment">// Concrete Handler B</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">TaskHandlerB</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Processor</span> </span>{
    <span class="hljs-keyword">private</span> Processor nextProcessor;

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setNextProcessor</span><span class="hljs-params">(Processor processor)</span> </span>{
        <span class="hljs-keyword">this</span>.nextProcessor = processor;
    }

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">processRequest</span><span class="hljs-params">(TaskRequest request)</span> </span>{
        <span class="hljs-keyword">if</span> (request.getRequestType().equals(TaskType.TYPE_B)) {
            System.out.println(<span class="hljs-string">"TaskHandlerB is processing request of Type B"</span>);
            <span class="hljs-comment">// Handle request logic here</span>
        } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (nextProcessor != <span class="hljs-keyword">null</span>) {
            nextProcessor.processRequest(request);
        }
    }
}
</code></pre>
<h4 id="heading-3-request">3. <strong>Request</strong></h4>
<p>The <code>TaskRequest</code> class represents the request being sent along the chain. It contains details about the request type.</p>
<pre><code class="lang-java"><span class="hljs-comment">// Request class</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">TaskRequest</span> </span>{
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> TaskType requestType;

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">TaskRequest</span><span class="hljs-params">(TaskType requestType)</span> </span>{
        <span class="hljs-keyword">this</span>.requestType = requestType;
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> TaskType <span class="hljs-title">getRequestType</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-keyword">return</span> requestType;
    }
}
</code></pre>
<h4 id="heading-4-enum-for-request-type">4. <strong>Enum for Request Type</strong></h4>
<p>The <code>TaskType</code> enum defines the types of requests that can be processed.</p>
<pre><code class="lang-java"><span class="hljs-comment">// Enum for Request Types</span>
<span class="hljs-class"><span class="hljs-keyword">enum</span> <span class="hljs-title">TaskType</span> </span>{
    TYPE_A, TYPE_B
}
</code></pre>
<h4 id="heading-5-client">5. <strong>Client</strong></h4>
<p>The <code>ChainDemo</code> class sets up the chain of responsibility by creating handlers and linking them. It then submits requests to be processed.</p>
<pre><code class="lang-java"><span class="hljs-comment">// Client class</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ChainDemo</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span><span class="hljs-params">(String[] args)</span> </span>{
        <span class="hljs-comment">// Create handlers</span>
        Processor handlerA = <span class="hljs-keyword">new</span> TaskHandlerA();
        Processor handlerB = <span class="hljs-keyword">new</span> TaskHandlerB();

        <span class="hljs-comment">// Set up the chain of processors</span>
        handlerA.setNextProcessor(handlerB);

        <span class="hljs-comment">// Create requests</span>
        TaskRequest request1 = <span class="hljs-keyword">new</span> TaskRequest(TaskType.TYPE_A);
        TaskRequest request2 = <span class="hljs-keyword">new</span> TaskRequest(TaskType.TYPE_B);
        TaskRequest request3 = <span class="hljs-keyword">new</span> TaskRequest(TaskType.TYPE_A);

        <span class="hljs-comment">// Process requests through the chain</span>
        handlerA.processRequest(request1);
        handlerA.processRequest(request2);
        handlerA.processRequest(request3);
    }
}
</code></pre>
<h3 id="heading-explanation">Explanation:</h3>
<ol>
<li><p><strong>Processor Interface</strong>: The <code>Processor</code> interface declares methods for setting the next processor and processing requests. It ensures that all handlers in the chain can pass requests along the chain if they can't handle them.</p>
</li>
<li><p><strong>TaskHandlerA and TaskHandlerB</strong>: These are concrete handlers that implement the <code>Processor</code> interface. Each handler checks if the request type matches what it can handle. If it can, it processes the request; otherwise, it forwards the request to the next processor.</p>
</li>
<li><p><strong>TaskRequest</strong>: The <code>TaskRequest</code> class represents the request and holds information about the request type (either <code>TYPE_A</code> or <code>TYPE_B</code>).</p>
</li>
<li><p><strong>TaskType</strong>: An enum that defines the possible types of requests (<code>TYPE_A</code> and <code>TYPE_B</code>).</p>
</li>
<li><p><strong>ChainDemo</strong>: The client that creates and links the processors, submits requests, and starts the chain.</p>
</li>
</ol>
<h3 id="heading-benefits-of-the-chain-of-responsibility-pattern">Benefits of the Chain of Responsibility Pattern:</h3>
<ol>
<li><p><strong>Loose Coupling</strong>: The sender of a request does not need to know which object will handle the request or how many objects are in the chain. It only needs to know the starting point of the chain.</p>
</li>
<li><p><strong>Flexibility</strong>: You can dynamically modify the chain by adding, removing, or changing the order of handlers without affecting other parts of the code.</p>
</li>
<li><p><strong>Responsibility Division</strong>: This pattern allows you to divide the processing logic across multiple objects, each responsible for handling a specific type of request. This helps with the Single Responsibility Principle.</p>
</li>
<li><p><strong>Scalability</strong>: The chain can be easily extended by adding new handlers that can process different types of requests, making it more scalable for complex systems.</p>
</li>
</ol>
<h3 id="heading-real-world-use-cases">Real-World Use Cases:</h3>
<ul>
<li><p><strong>Technical Support Systems</strong>: Requests for technical support are often processed by multiple levels of support, from frontline support agents to specialized experts.</p>
</li>
<li><p><strong>Event Handling</strong>: In UI frameworks, events (like mouse clicks or keyboard input) are handled by a chain of components. If one component doesn’t handle the event, it gets passed to the next.</p>
</li>
<li><p><strong>Authentication Middleware</strong>: In web applications, authentication and authorization are often processed through a chain of middleware functions, each checking specific security aspects of the request.</p>
</li>
</ul>
<h3 id="heading-conclusion">Conclusion:</h3>
<p>The Chain of Responsibility Pattern is a powerful tool for structuring code where multiple objects may need to handle a request. It simplifies complex decision-making processes, promotes loose coupling, and allows for greater flexibility in request handling. By using this pattern, you can create a robust and maintainable system that can easily evolve to accommodate new types of requests or changes in handling logic.</p>
]]></content:encoded></item><item><title><![CDATA[3.3 - Command Pattern: Behavioral Design Patterns]]></title><description><![CDATA[In software development, the Command Pattern is a behavioral design pattern used to encapsulate a request as an object, thereby allowing us to parameterize…]]></description><link>https://venuemmadi.hashnode.dev/33-command-pattern-behavioral-design-patterns</link><guid isPermaLink="true">https://venuemmadi.hashnode.dev/33-command-pattern-behavioral-design-patterns</guid><category><![CDATA[design patterns]]></category><category><![CDATA[command design pattern]]></category><category><![CDATA[behavioural patterns]]></category><category><![CDATA[low level design]]></category><category><![CDATA[System Design]]></category><dc:creator><![CDATA[Venu Madhav Emmadi]]></dc:creator><pubDate>Sat, 22 Jun 2024 18:30:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1746295945437/dd9e41af-3281-4451-9a76-8f6ae696b216.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In software development, the <strong>Command Pattern</strong> is a behavioral design pattern used to encapsulate a request as an object, thereby allowing us to parameterize clients with different requests, queue or log requests, and support undoable operations. It decouples the sender of a request from its receiver by introducing a layer of abstraction.</p>
<p>Let's walk through an example of how the Command Pattern works.</p>
<h3 id="heading-components-of-the-command-pattern">Components of the Command Pattern:</h3>
<ol>
<li><p><strong>Command Interface</strong>: Declares a method for executing a command.</p>
</li>
<li><p><strong>Concrete Command</strong>: Implements the command interface and defines the relationship between the receiver and an action.</p>
</li>
<li><p><strong>Receiver</strong>: Knows how to perform the operations associated with carrying out a request.</p>
</li>
<li><p><strong>Invoker</strong>: Asks the command to carry out the request.</p>
</li>
<li><p><strong>Client</strong>: The entity that creates and configures command objects.</p>
</li>
</ol>
<h3 id="heading-code-example">Code Example</h3>
<p>Below is an implementation of the Command Pattern with renamed functions and class names for clarity.</p>
<h4 id="heading-1-command-interface">1. <strong>Command Interface</strong></h4>
<p>The <code>Task</code> interface declares a method for executing a command.</p>
<pre><code class="lang-java"><span class="hljs-comment">// Command Interface</span>
<span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">Task</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">execute</span><span class="hljs-params">()</span></span>;
}
</code></pre>
<h4 id="heading-2-concrete-command">2. <strong>Concrete Command</strong></h4>
<p>The <code>ConcreteTask</code> class implements the <code>Task</code> interface. It encapsulates a receiver object and calls its method when the command is executed.</p>
<pre><code class="lang-java"><span class="hljs-comment">// Concrete Command</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ConcreteTask</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Task</span> </span>{
    <span class="hljs-keyword">private</span> Executor executor;

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">ConcreteTask</span><span class="hljs-params">(Executor executor)</span> </span>{
        <span class="hljs-keyword">this</span>.executor = executor;
    }

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">execute</span><span class="hljs-params">()</span> </span>{
        executor.performOperation();
    }
}
</code></pre>
<h4 id="heading-3-receiver">3. <strong>Receiver</strong></h4>
<p>The <code>Executor</code> class contains the actual logic to perform the operation. In this case, it simply prints out a message indicating the action performed.</p>
<pre><code class="lang-java"><span class="hljs-comment">// Receiver</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Executor</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">performOperation</span><span class="hljs-params">()</span> </span>{
        System.out.println(<span class="hljs-string">"Operation executed by the Executor"</span>);
    }
}
</code></pre>
<h4 id="heading-4-invoker">4. <strong>Invoker</strong></h4>
<p>The <code>ActionInvoker</code> class is responsible for executing commands. It doesn't know anything about the concrete command or receiver—it only knows about the <code>Task</code> interface.</p>
<pre><code class="lang-java"><span class="hljs-comment">// Invoker</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ActionInvoker</span> </span>{
    <span class="hljs-keyword">private</span> Task task;

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setTask</span><span class="hljs-params">(Task task)</span> </span>{
        <span class="hljs-keyword">this</span>.task = task;
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">executeTask</span><span class="hljs-params">()</span> </span>{
        task.execute();
    }
}
</code></pre>
<h4 id="heading-5-client">5. <strong>Client</strong></h4>
<p>The <code>ClientApp</code> class ties everything together. It creates the receiver (<code>Executor</code>), command (<code>ConcreteTask</code>), and invoker (<code>ActionInvoker</code>), and demonstrates how the command is executed.</p>
<pre><code class="lang-java"><span class="hljs-comment">// Client</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ClientApp</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span><span class="hljs-params">(String[] args)</span> </span>{
        Executor executor = <span class="hljs-keyword">new</span> Executor();         <span class="hljs-comment">// Create the receiver</span>
        Task task = <span class="hljs-keyword">new</span> ConcreteTask(executor);     <span class="hljs-comment">// Create the command and associate it with the receiver</span>
        ActionInvoker invoker = <span class="hljs-keyword">new</span> ActionInvoker(); <span class="hljs-comment">// Create the invoker</span>

        invoker.setTask(task);                     <span class="hljs-comment">// Assign the command to the invoker</span>
        invoker.executeTask();                     <span class="hljs-comment">// Execute the command</span>
    }
}
</code></pre>
<h3 id="heading-explanation">Explanation:</h3>
<ol>
<li><p><strong>Task Interface</strong>: Defines the <code>execute()</code> method, which is implemented by concrete tasks.</p>
</li>
<li><p><strong>ConcreteTask</strong>: Implements the <code>Task</code> interface and holds a reference to the receiver (<code>Executor</code>). When the <code>execute()</code> method is called, it triggers the appropriate action in the receiver.</p>
</li>
<li><p><strong>Executor</strong>: Contains the actual business logic that gets executed when a command is invoked.</p>
</li>
<li><p><strong>ActionInvoker</strong>: Holds a command and executes it without needing to know the details of the operation or the receiver.</p>
</li>
<li><p><strong>ClientApp</strong>: Sets up the interaction between the command, receiver, and invoker, and triggers the operation.</p>
</li>
</ol>
<h3 id="heading-benefits-of-the-command-pattern">Benefits of the Command Pattern:</h3>
<ol>
<li><p><strong>Decoupling</strong>: The command pattern decouples the object that invokes the operation from the one that knows how to perform it.</p>
</li>
<li><p><strong>Parameterization</strong>: You can parameterize objects with operations, allowing dynamic behavior at runtime.</p>
</li>
<li><p><strong>Undo/Redo Operations</strong>: This pattern can be extended to support undoable operations by storing the previous state of a command.</p>
</li>
<li><p><strong>Extensibility</strong>: New commands can be added easily without modifying existing code.</p>
</li>
</ol>
<h3 id="heading-real-world-use-cases">Real-World Use Cases:</h3>
<ul>
<li><p><strong>GUI Buttons</strong>: When buttons in a graphical user interface are clicked, they can be configured to perform different actions without the button needing to know the details of the action.</p>
</li>
<li><p><strong>Transaction Systems</strong>: Where commands represent operations like debit and credit, which can be logged or undone.</p>
</li>
<li><p><strong>Macro Commands</strong>: Multiple commands can be executed in sequence as part of a larger operation.</p>
</li>
</ul>
<h3 id="heading-conclusion">Conclusion:</h3>
<p>The Command Pattern is a powerful design tool that helps you encapsulate requests as objects, allowing you to decouple the sender of a request from its receiver. It is ideal for scenarios where you need to issue requests to objects without knowing anything about the operations being requested or their receivers. This flexibility makes it a popular pattern in many real-world applications.</p>
]]></content:encoded></item><item><title><![CDATA[3.2 - Strategy Pattern: A Behavioral Design Patterns]]></title><description><![CDATA[When designing complex software systems, it is crucial to maintain flexibility and reduce tightly coupled code. Behavioral design patterns help us achieve…]]></description><link>https://venuemmadi.hashnode.dev/32-exploring-the-strategy-pattern-in-behavioral-design-patterns</link><guid isPermaLink="true">https://venuemmadi.hashnode.dev/32-exploring-the-strategy-pattern-in-behavioral-design-patterns</guid><category><![CDATA[design patterns]]></category><category><![CDATA[Behavioral Design Pattern]]></category><category><![CDATA[StrategyPattern]]></category><category><![CDATA[Java]]></category><category><![CDATA[Programming Blogs]]></category><category><![CDATA[low level design]]></category><category><![CDATA[System Design]]></category><dc:creator><![CDATA[Venu Madhav Emmadi]]></dc:creator><pubDate>Sat, 15 Jun 2024 18:30:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1746295877783/893eb015-69c5-4b64-ac97-5485184fa50d.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>When designing complex software systems, it is crucial to maintain flexibility and reduce tightly coupled code. Behavioral design patterns help us achieve this by defining how classes and objects interact with one another. Among these patterns, the <strong>Strategy Pattern</strong> is a powerful tool that enables an algorithm's behavior to be selected at runtime, promoting flexibility and reusability.</p>
<h2 id="heading-what-is-the-strategy-pattern">What is the Strategy Pattern?</h2>
<p>The Strategy Pattern is a behavioral design pattern that allows you to define a family of algorithms, encapsulate each one, and make them interchangeable. The key aspect of this pattern is that it enables the client to choose an algorithm from a set of algorithms dynamically, ensuring that the class is not dependent on specific implementations of an algorithm.</p>
<p>The core idea is that the strategy (algorithm) can vary independently from the clients that use it, making it a perfect fit for scenarios where the business logic depends on a changing algorithm.</p>
<h3 id="heading-real-world-example">Real-World Example</h3>
<p>Let's take a simple example of filtering a list of integers. Based on different strategies, we can filter the integers in different ways. We will apply the Strategy Pattern to handle these filters, where each filter is a separate strategy.</p>
<h3 id="heading-step-by-step-breakdown">Step-by-Step Breakdown</h3>
<ol>
<li><strong>Define the Strategy Interface</strong></li>
</ol>
<p>We need an interface that will define the filter method. Each concrete strategy will implement this interface.</p>
<pre><code class="lang-java"><span class="hljs-keyword">package</span> strategyPattern;

<span class="hljs-keyword">import</span> java.util.List;

<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">FilterStrategy</span> </span>{
    <span class="hljs-function">List&lt;Integer&gt; <span class="hljs-title">filter</span><span class="hljs-params">(List&lt;Integer&gt; intList)</span></span>;
}
</code></pre>
<ol start="2">
<li><strong>Implement Different Filter Strategies</strong></li>
</ol>
<p>Now, we will create several classes, each implementing the <code>FilterStrategy</code> interface with a different filtering criterion.</p>
<pre><code class="lang-java"><span class="hljs-keyword">package</span> strategyPattern;

<span class="hljs-keyword">import</span> java.util.List;
<span class="hljs-keyword">import</span> java.util.stream.Collectors;

<span class="hljs-comment">// Strategy to filter numbers greater than 20</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">GreaterThanTwentyFilter</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">FilterStrategy</span> </span>{
    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> List&lt;Integer&gt; <span class="hljs-title">filter</span><span class="hljs-params">(List&lt;Integer&gt; intList)</span> </span>{
        <span class="hljs-keyword">return</span> intList.stream().filter(x -&gt; x &gt; <span class="hljs-number">20</span>).collect(Collectors.toList());
    }
}

<span class="hljs-comment">// Strategy to filter numbers divisible by 200</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">DivisibleBy200Filter</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">FilterStrategy</span> </span>{
    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> List&lt;Integer&gt; <span class="hljs-title">filter</span><span class="hljs-params">(List&lt;Integer&gt; intList)</span> </span>{
        <span class="hljs-keyword">return</span> intList.stream().filter(x -&gt; x % <span class="hljs-number">200</span> == <span class="hljs-number">0</span>).collect(Collectors.toList());
    }
}

<span class="hljs-comment">// Strategy to filter numbers less than 5000</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">LessThan5000Filter</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">FilterStrategy</span> </span>{
    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> List&lt;Integer&gt; <span class="hljs-title">filter</span><span class="hljs-params">(List&lt;Integer&gt; intList)</span> </span>{
        <span class="hljs-keyword">return</span> intList.stream().filter(x -&gt; x &lt; <span class="hljs-number">5000</span>).collect(Collectors.toList());
    }
}
</code></pre>
<ol start="3">
<li><strong>Context Class</strong></li>
</ol>
<p>The context class is responsible for maintaining a reference to the chosen strategy and delegating the operation to the selected algorithm.</p>
<pre><code class="lang-java"><span class="hljs-keyword">package</span> strategyPattern;

<span class="hljs-keyword">import</span> java.util.List;

<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">NumberFilterContext</span> </span>{
    <span class="hljs-keyword">private</span> FilterStrategy strategy;

    <span class="hljs-comment">// Setting the strategy at runtime</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setStrategy</span><span class="hljs-params">(FilterStrategy strategy)</span> </span>{
        <span class="hljs-keyword">this</span>.strategy = strategy;
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> List&lt;Integer&gt; <span class="hljs-title">executeStrategy</span><span class="hljs-params">(List&lt;Integer&gt; intList)</span> </span>{
        <span class="hljs-keyword">return</span> strategy.filter(intList);
    }
}
</code></pre>
<ol start="4">
<li><strong>Client Code (Main Method)</strong></li>
</ol>
<p>Finally, the client code chooses the strategy dynamically based on requirements and applies it.</p>
<pre><code class="lang-java"><span class="hljs-keyword">package</span> strategyPattern;

<span class="hljs-keyword">import</span> java.util.List;

<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">StrategyPatternDemo</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span><span class="hljs-params">(String[] args)</span> </span>{
        List&lt;Integer&gt; intList = List.of(<span class="hljs-number">100</span>, <span class="hljs-number">2</span>, <span class="hljs-number">300</span>, <span class="hljs-number">67</span>, <span class="hljs-number">56</span>, <span class="hljs-number">34</span>, <span class="hljs-number">12</span>, <span class="hljs-number">34</span>, <span class="hljs-number">33</span>, <span class="hljs-number">21</span>, <span class="hljs-number">66</span>, <span class="hljs-number">78</span>, <span class="hljs-number">79</span>, <span class="hljs-number">98</span>, <span class="hljs-number">56</span>, <span class="hljs-number">78</span>, <span class="hljs-number">65</span>);

        <span class="hljs-comment">// Create context</span>
        NumberFilterContext context = <span class="hljs-keyword">new</span> NumberFilterContext();

        <span class="hljs-comment">// Strategy 1: Numbers greater than 20</span>
        context.setStrategy(<span class="hljs-keyword">new</span> GreaterThanTwentyFilter());
        List&lt;Integer&gt; result1 = context.executeStrategy(intList);
        System.out.println(<span class="hljs-string">"Filtered with GreaterThanTwentyFilter: "</span> + result1);

        <span class="hljs-comment">// Strategy 2: Numbers divisible by 200</span>
        context.setStrategy(<span class="hljs-keyword">new</span> DivisibleBy200Filter());
        List&lt;Integer&gt; result2 = context.executeStrategy(intList);
        System.out.println(<span class="hljs-string">"Filtered with DivisibleBy200Filter: "</span> + result2);

        <span class="hljs-comment">// Strategy 3: Numbers less than 5000</span>
        context.setStrategy(<span class="hljs-keyword">new</span> LessThan5000Filter());
        List&lt;Integer&gt; result3 = context.executeStrategy(intList);
        System.out.println(<span class="hljs-string">"Filtered with LessThan5000Filter: "</span> + result3);
    }
}
</code></pre>
<h3 id="heading-advantages-of-the-strategy-pattern">Advantages of the Strategy Pattern</h3>
<ol>
<li><p><strong>Flexibility</strong>: You can change the strategy without modifying the client code, making it highly flexible.</p>
</li>
<li><p><strong>Reusability</strong>: Different strategies are encapsulated into separate classes, improving code reusability.</p>
</li>
<li><p><strong>Open-Closed Principle</strong>: The Strategy Pattern adheres to the Open-Closed Principle by allowing new strategies to be added without changing existing code.</p>
</li>
</ol>
<h3 id="heading-use-cases">Use Cases</h3>
<p>The Strategy Pattern is highly useful in scenarios where:</p>
<ul>
<li><p>You have multiple ways of performing the same action, such as sorting or filtering, and want to switch between them dynamically.</p>
</li>
<li><p>You want to avoid multiple <code>if-else</code> or <code>switch-case</code> conditions that decide which algorithm to use.</p>
</li>
</ul>
<h3 id="heading-conclusion">Conclusion</h3>
<p>The Strategy Pattern is an excellent way to allow dynamic selection of algorithms at runtime, offering clean separation between the client and the specific implementations. This ensures that your code remains flexible, maintainable, and adheres to fundamental design principles.</p>
<p>By encapsulating each filtering strategy separately, as demonstrated in our example, you can now easily add or modify filters without changing the core logic. This leads to clean, testable, and scalable code.</p>
]]></content:encoded></item><item><title><![CDATA[3.1 - Observer Pattern: A Behavioral Design Pattern]]></title><description><![CDATA[In software design, patterns provide solutions to common problems that developers face while building applications. One such design pattern that helps with…]]></description><link>https://venuemmadi.hashnode.dev/31-observer-pattern-a-behavioral-design-pattern</link><guid isPermaLink="true">https://venuemmadi.hashnode.dev/31-observer-pattern-a-behavioral-design-pattern</guid><category><![CDATA[Observer Pattern]]></category><category><![CDATA[design patterns]]></category><category><![CDATA[behavioural patterns]]></category><category><![CDATA[Programming Blogs]]></category><category><![CDATA[Java]]></category><category><![CDATA[System Design]]></category><category><![CDATA[low level design]]></category><dc:creator><![CDATA[Venu Madhav Emmadi]]></dc:creator><pubDate>Sat, 08 Jun 2024 18:30:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1746295818622/822b95cb-6276-491b-8103-edb15493ce2e.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In software design, patterns provide solutions to common problems that developers face while building applications. One such design pattern that helps with the communication between objects is the <strong>Observer Pattern</strong>, which falls under the <strong>Behavioral Design Patterns</strong> category.</p>
<p>In this blog, we’ll explore the Observer Pattern, how it works, and walk through an example implementation using the weather station analogy.</p>
<h2 id="heading-what-is-the-observer-pattern">What is the Observer Pattern?</h2>
<p>The <strong>Observer Pattern</strong> defines a one-to-many dependency between objects, where one object (the <strong>Subject</strong>) notifies other dependent objects (the <strong>Observers</strong>) about any state changes. This pattern is useful when the change in one object needs to be reflected in several others without creating a tightly coupled system.</p>
<h3 id="heading-key-components">Key Components:</h3>
<ol>
<li><p><strong>Subject</strong>: The object being observed. It maintains a list of observers and notifies them when its state changes.</p>
</li>
<li><p><strong>Observer</strong>: The objects that need to stay updated when the subject changes. They implement an update mechanism to receive notifications from the subject.</p>
</li>
<li><p><strong>Concrete Subject</strong>: The subject that sends updates when there are changes.</p>
</li>
<li><p><strong>Concrete Observer</strong>: The observer that performs actions when it receives updates from the subject.</p>
</li>
</ol>
<h3 id="heading-use-cases">Use Cases:</h3>
<ul>
<li><p>A weather station system where various displays (temperature, humidity, etc.) need real-time weather updates.</p>
</li>
<li><p>A stock market monitoring system where stock prices change and notify all investors of updates.</p>
</li>
<li><p>Notification systems where changes (e.g., new content, messages, etc.) notify subscribers.</p>
</li>
</ul>
<p>Let’s take a weather station system as our example to illustrate the Observer Pattern.</p>
<h2 id="heading-example-a-weather-station-with-observers">Example: A Weather Station with Observers</h2>
<p>We will simulate a <strong>Weather Station</strong> as the <strong>Subject</strong>, which will notify registered observers (like displays for different cities) whenever there’s a weather update.</p>
<h3 id="heading-step-1-define-the-publisher-interface">Step 1: Define the Publisher Interface</h3>
<p>The <strong>Publisher</strong> interface defines methods for adding, removing, and notifying subscribers.</p>
<pre><code class="lang-java"><span class="hljs-comment">// Publisher interface</span>
<span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">NewsAgency</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">addSubscriber</span><span class="hljs-params">(NewsSubscriber subscriber)</span></span>;
    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">removeSubscriber</span><span class="hljs-params">(NewsSubscriber subscriber)</span></span>;
    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">notifySubscribers</span><span class="hljs-params">(String news)</span></span>;
}
</code></pre>
<h3 id="heading-step-2-implement-the-concrete-publisher">Step 2: Implement the Concrete Publisher</h3>
<p>The <code>CityNewsAgency</code> class implements the <code>NewsAgency</code> interface. It maintains a list of subscribers and broadcasts news updates to them.</p>
<pre><code class="lang-java"><span class="hljs-keyword">import</span> java.util.ArrayList;
<span class="hljs-keyword">import</span> java.util.List;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">CityNewsAgency</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">NewsAgency</span> </span>{
    <span class="hljs-keyword">private</span> List&lt;NewsSubscriber&gt; subscribers = <span class="hljs-keyword">new</span> ArrayList&lt;&gt;();

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">addSubscriber</span><span class="hljs-params">(NewsSubscriber subscriber)</span> </span>{
        subscribers.add(subscriber);
    }

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">removeSubscriber</span><span class="hljs-params">(NewsSubscriber subscriber)</span> </span>{
        subscribers.remove(subscriber);
    }

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">notifySubscribers</span><span class="hljs-params">(String news)</span> </span>{
        <span class="hljs-keyword">for</span> (NewsSubscriber subscriber : subscribers) {
            subscriber.receiveUpdate(news);
        }
    }

    <span class="hljs-comment">// Method to publish new news and notify all subscribers</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">publishNews</span><span class="hljs-params">(String newsUpdate)</span> </span>{
        notifySubscribers(newsUpdate);
    }
}
</code></pre>
<h3 id="heading-step-3-define-the-subscriber-interface">Step 3: Define the Subscriber Interface</h3>
<p>The <code>NewsSubscriber</code> interface defines how subscribers receive news updates from the publisher.</p>
<pre><code class="lang-java"><span class="hljs-comment">// Subscriber interface</span>
<span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">NewsSubscriber</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">receiveUpdate</span><span class="hljs-params">(String news)</span></span>;
}
</code></pre>
<h3 id="heading-step-4-implement-concrete-subscribers">Step 4: Implement Concrete Subscribers</h3>
<p>In this step, we create <code>RegionalSubscriber</code> as a concrete subscriber class that prints news updates for a specific region.</p>
<pre><code class="lang-java"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">RegionalSubscriber</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">NewsSubscriber</span> </span>{
    <span class="hljs-keyword">private</span> String region;

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">RegionalSubscriber</span><span class="hljs-params">(String region)</span> </span>{
        <span class="hljs-keyword">this</span>.region = region;
    }

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">receiveUpdate</span><span class="hljs-params">(String news)</span> </span>{
        System.out.println(<span class="hljs-string">"News for "</span> + region + <span class="hljs-string">": "</span> + news);
    }
}
</code></pre>
<h3 id="heading-step-5-testing-the-observer-pattern-with-different-names">Step 5: Testing the Observer Pattern with Different Names</h3>
<p>Now let’s create a main program to tie everything together.</p>
<pre><code class="lang-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">NewsSystem</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span><span class="hljs-params">(String[] args)</span> </span>{
        <span class="hljs-comment">// Create the news agency (publisher)</span>
        CityNewsAgency newsAgency = <span class="hljs-keyword">new</span> CityNewsAgency();

        <span class="hljs-comment">// Create subscribers for different regions</span>
        NewsSubscriber subscriber1 = <span class="hljs-keyword">new</span> RegionalSubscriber(<span class="hljs-string">"Region X"</span>);
        NewsSubscriber subscriber2 = <span class="hljs-keyword">new</span> RegionalSubscriber(<span class="hljs-string">"Region Y"</span>);

        <span class="hljs-comment">// Add subscribers to the news agency</span>
        newsAgency.addSubscriber(subscriber1);
        newsAgency.addSubscriber(subscriber2);

        <span class="hljs-comment">// Publish news and notify all subscribers</span>
        newsAgency.publishNews(<span class="hljs-string">"New policies introduced today."</span>);
    }
}
</code></pre>
<h3 id="heading-output">Output:</h3>
<pre><code class="lang-java">News <span class="hljs-keyword">for</span> Region X: New policies introduced today.
News <span class="hljs-keyword">for</span> Region Y: New policies introduced today.
</code></pre>
<h3 id="heading-step-6-removing-a-subscriber">Step 6: Removing a Subscriber</h3>
<p>To demonstrate removing a subscriber, we remove one and publish another update.</p>
<pre><code class="lang-java">newsAgency.removeSubscriber(subscriber1);
newsAgency.publishNews(<span class="hljs-string">"Rain expected in the northern areas."</span>);
</code></pre>
<h3 id="heading-output-1">Output:</h3>
<pre><code class="lang-java">News <span class="hljs-keyword">for</span> Region Y: Rain expected in the northern areas.
</code></pre>
<h2 id="heading-benefits-of-the-observer-pattern">Benefits of the Observer Pattern</h2>
<ol>
<li><p><strong>Loose Coupling</strong>: The subject and observers are loosely coupled. The subject doesn’t need to know the concrete implementation of the observers, which promotes flexibility and reusability.</p>
</li>
<li><p><strong>Dynamic Relationships</strong>: Observers can be added or removed at runtime, making the system dynamic and flexible.</p>
</li>
<li><p><strong>Efficiency</strong>: Observers only receive notifications when there is an update, making it more efficient in event-driven systems.</p>
</li>
</ol>
<h2 id="heading-when-to-use-the-observer-pattern">When to Use the Observer Pattern?</h2>
<ul>
<li><p>When a one-to-many relationship is needed between objects.</p>
</li>
<li><p>When you need to decouple an object from its dependents but still need them to stay in sync.</p>
</li>
<li><p>When changes in one part of the system should trigger updates in other parts.</p>
</li>
</ul>
<h2 id="heading-conclusion">Conclusion</h2>
<p>The Observer Pattern implemented here with different class names and method names follows the same principles, making it a flexible and decoupled solution for maintaining multiple dependent objects in sync with one main object. Whether it's for weather updates or news distribution, the pattern can be adapted to suit various real-world applications.</p>
]]></content:encoded></item><item><title><![CDATA[3. Behavioral Design Patterns: A Comprehensive Overview]]></title><description><![CDATA[Inside the field of program designing, plan designs are crucial assets for settling normal issues that emerge all through the advancement stage. Behavioral…]]></description><link>https://venuemmadi.hashnode.dev/3-behavioral-design-patterns-a-comprehensive-overview</link><guid isPermaLink="true">https://venuemmadi.hashnode.dev/3-behavioral-design-patterns-a-comprehensive-overview</guid><category><![CDATA[behavioural patterns]]></category><category><![CDATA[design patterns]]></category><category><![CDATA[Programming Blogs]]></category><category><![CDATA[Java]]></category><category><![CDATA[LLD]]></category><category><![CDATA[low level design]]></category><category><![CDATA[System Design]]></category><dc:creator><![CDATA[Venu Madhav Emmadi]]></dc:creator><pubDate>Sat, 01 Jun 2024 18:30:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1746295751231/dc9ae0b3-9f7e-4776-8b60-a4c5315ccdba.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Inside the field of program designing, plan designs are crucial assets for settling normal issues that emerge all through the advancement stage. Behavioral design pattern are striking among them due to their emphasis on object-to-object communication and interaction. They offer ways to handle obligations, classes and object communication, and calculations in an effective way.</p>
<p>We`ll dive into behavioral design patterns in this thorough introduction, looking at their types, traits, and practical uses.</p>
<h3 id="heading-understanding-behavioral-design-patterns"><strong>Understanding Behavioral Design Patterns</strong></h3>
<p>The delegation of tasks among objects and the encapsulation of behavior within an object are the main concerns of behavioral design patterns. They concentrate on how objects divide up work among themselves and interact to accomplish a particular goal. By encouraging loose coupling and strong cohesion, these patterns help create software components that are adaptable and reusable.</p>
<h3 id="heading-types-of-behavioral-design-patterns"><strong>Types of Behavioral Design Patterns</strong></h3>
<ol>
<li><p><strong>Observer Pattern:</strong> This design pattern creates an object-to-many relationship. All of an object's dependents are automatically notified and updated when an object changes in state.</p>
<p> UI frameworks and event handling systems both make extensive use of this paradigm.</p>
</li>
<li><p><strong>The Strategy Pattern:</strong> encompasses all of the algorithms in a family and defines them such that they can be substituted for one another. It promotes flexibility and ease of maintenance by enabling the algorithm to change independently of the clients who use it.</p>
</li>
<li><p><strong>Command Pattern:</strong> This pattern allows clients to be parameterized with queues, requests, and operations by encapsulating a request as an object. In addition to enabling undoable operations, it allows clients to be parameterized with queues, requests, and operations.</p>
</li>
<li><p><strong>Chain of Responsibility Pattern:</strong> Depending on the kind of request, the Chain of Responsibility pattern separates the sender and the recipient. The request can be handled by several objects, and the sender doesn't have to know which object will handle it in the end.</p>
</li>
<li><p><strong>Iterator pattern:</strong> offers a method for sequentially accessing an aggregate object's elements without disclosing its underlying form. By severing the client's connection to the collection, it permits traversal without disclosing the implementation.</p>
</li>
<li><p><strong>Visitor Pattern:</strong> An action to be carried out on components of an object structure is represented by the Visitor pattern. It permits new operations to be added without changing the classes of the items they act on.</p>
</li>
<li><p><strong>Interpreter Pattern:</strong> This pattern offers a means of assessing sentences in a language and specifies a syntax for interpreting it. It is helpful in defining DSLs (Domain-Specific Languages), or simple languages.</p>
</li>
<li><p><strong>Memento Pattern:</strong> An object's state can be changed back to a prior state using the Memento pattern. It permits the internal state of an object to be later recovered by externalizing and capturing it without breaking encapsulation.</p>
</li>
</ol>
<h3 id="heading-real-world-applications"><strong>Real-World Applications</strong></h3>
<ul>
<li><p><strong>User Interface Design</strong>: Observer pattern is extensively used in user interface development to handle events such as button clicks, mouse movements, and keyboard inputs.</p>
</li>
<li><p><strong>Payment Systems</strong>: Strategy pattern can be seen in payment processing systems where different payment methods (credit card, PayPal, etc.) are interchangeable and can be selected at runtime.</p>
</li>
<li><p><strong>Command Line Interfaces</strong>: Command pattern finds application in command-line interfaces where user commands are encapsulated as objects and executed by invokers.</p>
</li>
<li><p><strong>Middleware</strong>: Chain of Responsibility pattern is employed in middleware systems to process requests by multiple components sequentially until one of them handles the request.</p>
</li>
<li><p><strong>Data Structures</strong>: Iterator pattern is commonly used in various data structures like lists, trees, and maps to traverse and access elements without exposing the underlying structure.</p>
</li>
<li><p><strong>Compilers and Interpreters</strong>: Interpreter pattern is utilized in compilers and interpreters to parse and evaluate expressions in programming languages.</p>
</li>
</ul>
<h3 id="heading-conclusion"><strong>Conclusion</strong></h3>
<p>Using behavioral design principles can help create software systems that are scalable, flexible, and maintainable. Developers can increase the quality of their software products by promoting separation of concerns, enhancing code reusability, and putting these patterns into practice.</p>
<p>Behavioral design patterns offer a comprehensive toolkit for tackling a wide range of software engineering difficulties, whether it's handling system events, implementing algorithms, or managing user interactions.</p>
]]></content:encoded></item><item><title><![CDATA[2.7 Proxy Pattern - Structural Design Pattern]]></title><description><![CDATA[The Proxy Pattern gives another item a stand-in or surrogate to manage access to it. This blog post will examine the Proxy Pattern, explain its…]]></description><link>https://venuemmadi.hashnode.dev/27-proxy-pattern-structural-design-pattern</link><guid isPermaLink="true">https://venuemmadi.hashnode.dev/27-proxy-pattern-structural-design-pattern</guid><category><![CDATA[design patterns]]></category><category><![CDATA[proxy design pattern]]></category><category><![CDATA[structural design pattern]]></category><category><![CDATA[Java]]></category><category><![CDATA[Programming Blogs]]></category><category><![CDATA[low level design]]></category><category><![CDATA[System Design]]></category><dc:creator><![CDATA[Venu Madhav Emmadi]]></dc:creator><pubDate>Sat, 18 May 2024 18:30:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1746295360522/688667e9-c802-40ef-9a3c-48b593ba6e39.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The Proxy Pattern gives another item a stand-in or surrogate to manage access to it. This blog post will examine the Proxy Pattern, explain its composition, and look at an example of Java code that demonstrates how it is used.</p>
<h3 id="heading-what-is-the-proxy-pattern"><strong>What is the Proxy Pattern?</strong></h3>
<p>An item known as the genuine subject is accessed through a surrogate or placeholder that is provided by the Proxy Pattern. The primary goal of employing a proxy is to control access to the true subject by adding a layer of indirection. This has multiple applications, including data caching, slow initialization, access control, logging, and more.</p>
<h3 id="heading-structure-of-proxy-pattern"><strong>Structure of Proxy Pattern</strong></h3>
<p>The Structural Proxy Pattern involves the following components:</p>
<ol>
<li><p><strong>Subject</strong>: This is an interface that defines the common interface for the RealSubject and Proxy classes. It allows the Proxy to be used anywhere the RealSubject is expected.</p>
</li>
<li><p><strong>RealSubject</strong>: This is the real object that the Proxy represents. It implements the Subject interface and provides the actual functionality.</p>
</li>
<li><p><strong>Proxy</strong>: This is the surrogate class that acts as an intermediary between the client and the RealSubject. It maintains a reference to the RealSubject and controls access to it, optionally performing additional functionality before or after forwarding the request to the RealSubject.</p>
</li>
</ol>
<h3 id="heading-java-code-example"><strong>Java Code Example</strong></h3>
<p>Let's illustrate the Proxy Pattern with a simple example in Java. Consider a scenario where we have a <code>Image</code> interface representing an image and a <code>RealImage</code> class representing the actual image file. We'll create a <code>ProxyImage</code> class to control access to the <code>RealImage</code> object.</p>
<pre><code class="lang-java"><span class="hljs-comment">// Subject Interface</span>
<span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">Image</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">display</span><span class="hljs-params">()</span></span>;
}
<span class="hljs-comment">// RealSubject Class</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">RealImage</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Image</span> </span>{
    <span class="hljs-keyword">private</span> String filename;
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">RealImage</span><span class="hljs-params">(String filename)</span> </span>{
        <span class="hljs-keyword">this</span>.filename = filename;
        loadImageFromDisk();
    }
    <span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title">loadImageFromDisk</span><span class="hljs-params">()</span> </span>{
        System.out.println(<span class="hljs-string">"Loading image: "</span> + filename);
    }
    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">display</span><span class="hljs-params">()</span> </span>{
        System.out.println(<span class="hljs-string">"Displaying image: "</span> + filename);
    }
}
<span class="hljs-comment">// Proxy Class</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ProxyImage</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Image</span> </span>{
    <span class="hljs-keyword">private</span> RealImage realImage;
    <span class="hljs-keyword">private</span> String filename;

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">ProxyImage</span><span class="hljs-params">(String filename)</span> </span>{
        <span class="hljs-keyword">this</span>.filename = filename;
    }
    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">display</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-keyword">if</span> (realImage == <span class="hljs-keyword">null</span>) {
            realImage = <span class="hljs-keyword">new</span> RealImage(filename);
        }
        realImage.display();
    }
}
<span class="hljs-comment">// Client Class</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ProxyPatternExample</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span><span class="hljs-params">(String[] args)</span> </span>{
        <span class="hljs-comment">// Client uses Proxy to access RealSubject</span>
        Image image1 = <span class="hljs-keyword">new</span> ProxyImage(<span class="hljs-string">"test1.jpg"</span>);
        Image image2 = <span class="hljs-keyword">new</span> ProxyImage(<span class="hljs-string">"test2.jpg"</span>);
        <span class="hljs-comment">// Image 1 will be loaded from disk</span>
        image1.display();
        <span class="hljs-comment">// Image 1 will be displayed without loading from disk again</span>
        image1.display();
        <span class="hljs-comment">// Image 2 will be loaded from disk</span>
        image2.display();
    }
}
</code></pre>
<p>In this example, <code>RealImage</code> represents the actual image file, and <code>ProxyImage</code> controls access to it. The first time an image is displayed, it is loaded from the disk, and subsequent display requests for the same image are served from memory, demonstrating lazy loading behavior.</p>
<p><strong>Output:</strong></p>
<p>Loading image: test1.jpg</p>
<p>Displaying image: test1.jpg</p>
<p>Displaying image: test1.jpg</p>
<p>Loading image: test2.jpg</p>
<p>Displaying image: test2.jpg</p>
<h3 id="heading-conclusion"><strong>Conclusion</strong></h3>
<p>Access to objects can be managed in a flexible manner with the Structural Proxy Pattern, enabling the transparent integration of new functionality. You can improve the behavior of the original object without modifying its code by employing a proxy. Java applications can benefit from more modular, maintainable, and effective code if the Proxy Pattern is understood and used.</p>
]]></content:encoded></item><item><title><![CDATA[2.6 Flyweight Pattern - Structural Design Pattern]]></title><description><![CDATA[The Structural Flyweight Pattern is a structural design pattern used in software design that shares similar data among several objects in an effort to…]]></description><link>https://venuemmadi.hashnode.dev/26-flyweight-pattern-structural-design-pattern</link><guid isPermaLink="true">https://venuemmadi.hashnode.dev/26-flyweight-pattern-structural-design-pattern</guid><category><![CDATA[flyweight pattern]]></category><category><![CDATA[design patterns]]></category><category><![CDATA[structural design pattern]]></category><category><![CDATA[Java]]></category><category><![CDATA[Programming Blogs]]></category><category><![CDATA[System Design]]></category><category><![CDATA[low level design]]></category><dc:creator><![CDATA[Venu Madhav Emmadi]]></dc:creator><pubDate>Sat, 11 May 2024 18:30:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1746295281989/d1942410-2824-4091-a5f3-336dd9585ec5.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The Structural Flyweight Pattern is a structural design pattern used in software design that shares similar data among several objects in an effort to reduce memory usage and enhance performance. When working with numerous similar objects that share a lot of shared state, it is quite helpful. This pattern optimizes application efficiency and lowers memory consumption by sharing data rather than copying it.</p>
<h2 id="heading-overview-of-the-flyweight-pattern"><strong>Overview of the Flyweight Pattern</strong></h2>
<p>The Flyweight Pattern achieves its goal by splitting object state into intrinsic and extrinsic parts.</p>
<ul>
<li><p><strong>Intrinsic state</strong> represents the data shared across multiple objects and can be shared. This state is stored in the flyweight objects.</p>
</li>
<li><p><strong>Extrinsic state</strong> represents the context-dependent state that varies between objects and cannot be shared. This state needs to be supplied externally whenever a flyweight object is used.</p>
</li>
</ul>
<p>By separating intrinsic and extrinsic state, the Flyweight Pattern enables efficient memory usage and allows a large number of lightweight objects to share common state.</p>
<h2 id="heading-use-cases"><strong>Use Cases</strong></h2>
<p>The Flyweight Pattern comes in handy especially when:</p>
<ul>
<li><p>There are a lot of objects that must be made.</p>
</li>
<li><p>The abundance of comparable objects results in high storage costs.</p>
</li>
<li><p>One can make the majority of the object state external.</p>
<p>  Graphical applications are common examples, where a huge number of comparable items, such as text editor characters, image pixels, or graphical primitives, need to be managed effectively.</p>
</li>
</ul>
<h2 id="heading-implementation-in-java"><strong>Implementation in Java</strong></h2>
<p>Let's illustrate the Flyweight Pattern with a simple example. Consider a text editor where we want to display different characters efficiently.</p>
<pre><code class="lang-java"><span class="hljs-keyword">import</span> java.util.HashMap;
<span class="hljs-keyword">import</span> java.util.Map;
<span class="hljs-comment">// Flyweight interface</span>
<span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">Character</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">display</span><span class="hljs-params">(String font)</span></span>;
}
<span class="hljs-comment">// Concrete flyweight</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">CharacterImpl</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Character</span> </span>{
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> <span class="hljs-keyword">char</span> symbol;

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">CharacterImpl</span><span class="hljs-params">(<span class="hljs-keyword">char</span> symbol)</span> </span>{
        <span class="hljs-keyword">this</span>.symbol = symbol;
    }
    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">display</span><span class="hljs-params">(String font)</span> </span>{
        System.out.println(<span class="hljs-string">"Character: "</span> + symbol + <span class="hljs-string">", Font: "</span> + font);
    }
}
<span class="hljs-comment">// Flyweight factory</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">CharacterFactory</span> </span>{
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> Map&lt;Character, Character&gt; characters = <span class="hljs-keyword">new</span> HashMap&lt;&gt;();
    <span class="hljs-function"><span class="hljs-keyword">public</span> Character <span class="hljs-title">getCharacter</span><span class="hljs-params">(<span class="hljs-keyword">char</span> symbol)</span> </span>{
        Character character = characters.get(symbol);
        <span class="hljs-keyword">if</span> (character == <span class="hljs-keyword">null</span>) {
            character = <span class="hljs-keyword">new</span> CharacterImpl(symbol);
            characters.put(symbol, character);
        }
        <span class="hljs-keyword">return</span> character;
    }
}
<span class="hljs-comment">// Client</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">TextEditor</span> </span>{
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> CharacterFactory characterFactory = <span class="hljs-keyword">new</span> CharacterFactory();
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">displayCharacter</span><span class="hljs-params">(<span class="hljs-keyword">char</span> symbol, String font)</span> </span>{
        Character character = characterFactory.getCharacter(symbol);
        character.display(font);
    }
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span><span class="hljs-params">(String[] args)</span> </span>{
        TextEditor editor = <span class="hljs-keyword">new</span> TextEditor();
        editor.displayCharacter(<span class="hljs-string">'A'</span>, <span class="hljs-string">"Arial"</span>);
        editor.displayCharacter(<span class="hljs-string">'B'</span>, <span class="hljs-string">"Times New Roman"</span>);
        editor.displayCharacter(<span class="hljs-string">'A'</span>, <span class="hljs-string">"Verdana"</span>);
        editor.displayCharacter(<span class="hljs-string">'C'</span>, <span class="hljs-string">"Courier New"</span>);
    }
}
</code></pre>
<p>In this example, <code>Character</code> is the flyweight interface, <code>CharacterImpl</code> is the concrete flyweight class representing a character, and <code>CharacterFactory</code> is the flyweight factory responsible for creating and managing flyweight objects. The <code>TextEditor</code> class acts as the client and demonstrates how to use flyweight objects efficiently.</p>
<ol>
<li><p><strong>Intrinsic State (Character Symbol)</strong>:</p>
<ul>
<li><p>The character symbol (e.g., 'A', 'B', 'C') is intrinsic state as it is shared across multiple objects.</p>
</li>
<li><p>This state is stored within the flyweight objects (<code>CharacterImpl</code> objects) since it is common and can be shared among them.</p>
</li>
<li><p>In the <code>CharacterImpl</code> class, the <code>symbol</code> variable holds this intrinsic state.</p>
</li>
</ul>
</li>
<li><p><strong>Extrinsic State (Font)</strong>:</p>
<ul>
<li><p>The font (e.g., "Arial", "Times New Roman", etc.) is extrinsic state as it varies between different objects.</p>
</li>
<li><p>This state cannot be shared among different flyweight objects; it needs to be supplied externally whenever a flyweight object is used.</p>
</li>
<li><p>In the <code>TextEditor</code> class, the <code>displayCharacter</code> method supplies the font as a parameter whenever a character is displayed. This font is extrinsic state that varies between different invocations of the method.</p>
</li>
</ul>
</li>
</ol>
<p><strong>Output:</strong></p>
<p>Character: A, Font: Arial</p>
<p>Character: B, Font: Times New Roman</p>
<p>Character: A, Font: Verdana</p>
<p>Character: C, Font: Courier New</p>
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>An effective method for maximizing memory use and enhancing performance in applications handling a high volume of comparable objects is the structural flyweight pattern. It allows for more effective resource use without compromising flexibility or functionality by separating intrinsic and extrinsic state and sharing common state among multiple objects. The Flyweight Pattern can significantly increase the scalability and performance of applications when used wisely.</p>
]]></content:encoded></item><item><title><![CDATA[2.5 Facade Pattern - Structural Design Pattern]]></title><description><![CDATA[The Facade Pattern is unique among these patterns in that it is a structural pattern that streamlines the communication between complex subsystems and…]]></description><link>https://venuemmadi.hashnode.dev/25-facade-pattern-structural-design-pattern</link><guid isPermaLink="true">https://venuemmadi.hashnode.dev/25-facade-pattern-structural-design-pattern</guid><category><![CDATA[design patterns]]></category><category><![CDATA[structural design pattern]]></category><category><![CDATA[facade-pattern]]></category><category><![CDATA[Java]]></category><category><![CDATA[Programming Blogs]]></category><category><![CDATA[System Design]]></category><category><![CDATA[low level design]]></category><dc:creator><![CDATA[Venu Madhav Emmadi]]></dc:creator><pubDate>Sat, 04 May 2024 18:30:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1746295165152/635dbe8b-bc2e-429d-903a-4cecca4a3bfc.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The Facade Pattern is unique among these patterns in that it is a structural pattern that streamlines the communication between complex subsystems and client code. The Facade Pattern simplifies a system's complexity by offering a single interface, which makes it easier to use.</p>
<p>This blog article will examine the principles and advantages of the Facade Pattern and provide samples of Java code to show how it is implemented.</p>
<h3 id="heading-understanding-the-facade-pattern"><strong>Understanding the Facade Pattern</strong></h3>
<p>A structural design pattern called the facade pattern offers a condensed interface to a complicated system of classes, libraries, or APIs. It serves as a front, providing a uniform interface for client programs while concealing the intricacies of the underlying system.</p>
<p>Important Elements:</p>
<ol>
<li><p><strong>Facade</strong>: The focal point of the design is the facade. It conceals the intricacies of the subsystem and offers the client a streamlined interface.</p>
</li>
<li><p><strong>Subsystems:</strong> The different classes or parts that comprise the complex system are called subsystems. For the benefit of the client, the facade communicates with various subsystems.</p>
</li>
</ol>
<h4 id="heading-benefits-of-facade-pattern">Benefits of Facade Pattern:</h4>
<ul>
<li><p><strong>Simplified Interface:</strong> By offering a high-level interface, Facade makes it easier to use a complex system.</p>
</li>
<li><p><strong>Decoupling:</strong> It facilitates flexibility and simpler maintenance by severing the client code from the specifics of the subsystems' implementation.</p>
</li>
<li><p><strong>Encapsulation:</strong> To improve code structure and abstraction, Facade encapsulates the intricacies within the subsystems.</p>
</li>
</ul>
<h3 id="heading-implementation-example-in-java"><strong>Implementation Example in Java</strong></h3>
<p>Let's consider a scenario where we have a multimedia subsystem consisting of multiple components such as a video player, an audio player, and a display system. We'll create a facade to provide a simple interface for playing multimedia content.</p>
<pre><code class="lang-java"><span class="hljs-comment">// Subsystem: VideoPlayer</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">VideoPlayer</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">playVideo</span><span class="hljs-params">(String filename)</span> </span>{
        System.out.println(<span class="hljs-string">"Playing video: "</span> + filename);
    }
}
<span class="hljs-comment">// Subsystem: AudioPlayer</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">AudioPlayer</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">playAudio</span><span class="hljs-params">(String filename)</span> </span>{
        System.out.println(<span class="hljs-string">"Playing audio: "</span> + filename);
    }
}
<span class="hljs-comment">// Subsystem: DisplaySystem</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">DisplaySystem</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">display</span><span class="hljs-params">(String content)</span> </span>{
        System.out.println(<span class="hljs-string">"Displaying: "</span> + content);
    }
}
<span class="hljs-comment">// Facade: MultimediaFacade</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MultimediaFacade</span> </span>{
    <span class="hljs-keyword">private</span> VideoPlayer videoPlayer;
    <span class="hljs-keyword">private</span> AudioPlayer audioPlayer;
    <span class="hljs-keyword">private</span> DisplaySystem displaySystem;
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">MultimediaFacade</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-keyword">this</span>.videoPlayer = <span class="hljs-keyword">new</span> VideoPlayer();
        <span class="hljs-keyword">this</span>.audioPlayer = <span class="hljs-keyword">new</span> AudioPlayer();
        <span class="hljs-keyword">this</span>.displaySystem = <span class="hljs-keyword">new</span> DisplaySystem();
    }
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">playMedia</span><span class="hljs-params">(String videoFile, String audioFile, String content)</span> </span>{
        videoPlayer.playVideo(videoFile);
        audioPlayer.playAudio(audioFile);
        displaySystem.display(content);
    }
}
<span class="hljs-comment">// Client Code</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">FacadePatternExample</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span><span class="hljs-params">(String[] args)</span> </span>{
        MultimediaFacade multimediaFacade = <span class="hljs-keyword">new</span> MultimediaFacade();
        multimediaFacade.playMedia(<span class="hljs-string">"movie.mp4"</span>, <span class="hljs-string">"song.mp3"</span>, <span class="hljs-string">"Presentation slides"</span>);
    }
}
</code></pre>
<p>In this example, <code>MultimediaFacade</code> serves as a facade that simplifies the usage of multimedia subsystems. The client code interacts only with the facade, which internally handles the complexities of video playback, audio playback, and display.</p>
<p><strong>output:</strong></p>
<p>Playing video: <a target="_blank" href="http://movie.mp">movie.mp</a>4</p>
<p>Playing audio: <a target="_blank" href="http://song.mp">song.mp</a>3</p>
<p>Displaying: Presentation slides</p>
<h3 id="heading-conclusion"><strong>Conclusion</strong></h3>
<p>In software design, the Facade Pattern is a potent tool for streamlining interactions with intricate systems. It encourages decoupling, encapsulation, and code structure by offering a single interface. The Java Facade Pattern is a vital tool for any software developer's toolbox since it can result in codebases that are easier to maintain and clean.</p>
]]></content:encoded></item></channel></rss>