<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Charles Koffler</title>
    <description>The latest articles on DEV Community by Charles Koffler (@charles_koffler_bcabc582b).</description>
    <link>https://dev.to/charles_koffler_bcabc582b</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3217531%2F9cf9858a-92c1-4615-840f-3e8b88dabc3b.jpg</url>
      <title>DEV Community: Charles Koffler</title>
      <link>https://dev.to/charles_koffler_bcabc582b</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/charles_koffler_bcabc582b"/>
    <language>en</language>
    <item>
      <title>A Semantic Approach to WPF and MVVM with Clprolf framework</title>
      <dc:creator>Charles Koffler</dc:creator>
      <pubDate>Sat, 13 Jun 2026 17:10:32 +0000</pubDate>
      <link>https://dev.to/charles_koffler_bcabc582b/a-semantic-approach-to-wpf-and-mvvm-with-clprolf-framework-220h</link>
      <guid>https://dev.to/charles_koffler_bcabc582b/a-semantic-approach-to-wpf-and-mvvm-with-clprolf-framework-220h</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;WPF and the MVVM (Model-View-ViewModel) pattern are powerful tools for desktop development. However, as applications grow, the technical plumbing—commands, data binding, notifications—can sometimes cloud the architectural intent. We can easily lose track of the conceptual meaning of our classes behind their technical implementations.&lt;/p&gt;

&lt;p&gt;To bring more clarity to my desktop architectures, let's try a lightweight framework &lt;strong&gt;Clprolf&lt;/strong&gt;. The goal is simple: use basic custom C# attributes to give every class a clear, human-readable role, and enforce these boundaries with automated architecture tests using &lt;strong&gt;ArchUnitNET&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Here is how it looks in practice.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Core Concepts: Agents and Workers
&lt;/h2&gt;

&lt;p&gt;Instead of categorizing code strictly by technical layers, Clprolf looks at the application as a team of actors working together:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Agents:&lt;/strong&gt; Core components that carry an identity, state, representation, or behavioral intention.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Workers:&lt;/strong&gt; Quiet executors or infrastructure tools that handle background or mechanical tasks.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When applied to WPF and MVVM, the system naturally organizes into three distinct types of Agents:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Domain Agents (&lt;code&gt;User&lt;/code&gt;):&lt;/strong&gt; The pure business entities holding the core data and identity.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Presentation Agents (&lt;code&gt;UserViewModel&lt;/code&gt;):&lt;/strong&gt; The ambassadors between the user and the system, orchestrating data and validating user intentions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;System-Oriented Agents (&lt;code&gt;UserWindow&lt;/code&gt; &amp;amp; &lt;code&gt;RelayCommand&lt;/code&gt;):&lt;/strong&gt; Noble UI components whose purpose is to interact with and feed the hidden, native rendering engine of the .NET framework.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The Code in Action
&lt;/h2&gt;

&lt;p&gt;Here is a streamlined look at how a standard CRUD ViewModel expresses its semantic role through attributes and clean design:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Collections.ObjectModel&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.ComponentModel&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Windows.Input&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Clprolf.ArchUnitNet.Attributes&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;Clprolf.Example.WPF.Mvvm.Impl&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ClAgent&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;// Marked as a Presentation Agent&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserViewModel&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IUserViewModel&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;event&lt;/span&gt; &lt;span class="n"&gt;PropertyChangedEventHandler&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;PropertyChanged&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;// ObservableCollection handles UI notification for list updates&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;ObservableCollection&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Users&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;_selectedUser&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;SelectedUser&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;get&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_selectedUser&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;set&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_selectedUser&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;_selectedUser&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                    &lt;span class="nf"&gt;OnPropertyChanged&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;nameof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SelectedUser&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
                    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_selectedUser&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;NewUserName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_selectedUser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;_newUserName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Empty&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;NewUserName&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;get&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_newUserName&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;set&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_newUserName&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;_newUserName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                    &lt;span class="nf"&gt;OnPropertyChanged&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;nameof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NewUserName&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// Intention Agents (CRUD Commands)&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;ICommand&lt;/span&gt; &lt;span class="n"&gt;AddCommand&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;UserViewModel&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;AddCommand&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;RelayCommand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ExecuteAdd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CanExecuteAdd&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="c1"&gt;// Initial data seeding&lt;/span&gt;
            &lt;span class="c1"&gt;// (In a full production setup, this would be fetched from a Repository Worker)&lt;/span&gt;
            &lt;span class="n"&gt;Users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;User&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Alice"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
            &lt;span class="n"&gt;Users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;User&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Bob"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;ExecuteAdd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;object&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;parameter&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;User&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NewUserName&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
            &lt;span class="n"&gt;NewUserName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Empty&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
            &lt;span class="c1"&gt;// Save to repository worker here...&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;CanExecuteAdd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;object&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;parameter&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsNullOrWhiteSpace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NewUserName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;OnPropertyChanged&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;propertyName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;PropertyChanged&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;Invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;PropertyChangedEventArgs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;propertyName&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Architecture Blueprint
&lt;/h2&gt;

&lt;p&gt;To see how this language structures a real application, here is the exact layout of the WPF project. Notice how the namespaces map directly to our semantic roles rather than generic UI folders:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Clprolf.Example.WPF/
│
├── App.xaml.cs                     --&amp;gt; [ClWorker] (Application Bootstrapper)
│
├── Entities/
│   └── User.cs                     --&amp;gt; [ClAgent] (Domain Identity)
│
├── Mvvm/
│   ├── IUserViewModel.cs           --&amp;gt; [ClFamily] [ClAgent] (Contract)
│   └── Impl/
│       └── UserViewModel.cs        --&amp;gt; [ClAgent] (Presentation Ambassador)
│
└── Agents/
    └── Impl/
        └── SystemOriented/
            ├── UserWindow.xaml.cs  --&amp;gt; [ClSystem] (UI Component)
            ├── RelayCommand.cs     --&amp;gt; [ClSystem] (Intention Driver)

    └── Traits/
        └── IClNotifyPropertyChanged.cs --&amp;gt; [ClTrait][ClAgent]

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, every single component—from the window to the command framework—has been assigned a strict semantic responsibility.&lt;/p&gt;




&lt;h2&gt;
  
  
  Wiring the Ecosystem Together
&lt;/h2&gt;

&lt;p&gt;To understand how these Agents interact, look at how the application starts. &lt;/p&gt;

&lt;p&gt;First, we have our &lt;code&gt;UserWindow&lt;/code&gt;, a &lt;strong&gt;System-Oriented Agent&lt;/strong&gt; designed to serve the native WPF rendering engine by hosting the visual tree and binding the context:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ClSystem&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;partial&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserWindow&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Window&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;UserWindow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;UserViewModel&lt;/span&gt; &lt;span class="n"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;InitializeComponent&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;DataContext&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, we have the &lt;code&gt;App.xaml.cs&lt;/code&gt;. This is not an Agent; it has no business intent. It is a &lt;strong&gt;Clprolf Worker&lt;/strong&gt;—an automated executor whose only job is to assemble the pieces, inject the dependencies, and start the factory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ClWorker&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;partial&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;App&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Application&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;OnStartup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;StartupEventArgs&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;base&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;OnStartup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;vm&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;UserViewModel&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;userWin&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;UserWindow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;userWin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Show&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// The worker hands over control to the System Agents&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Guarding the Architecture with ArchUnitNET
&lt;/h2&gt;

&lt;p&gt;To ensure these semantic boundaries are never violated during development, we use automated architecture tests. For instance, we can write a rule ensuring that any interface marked as a &lt;strong&gt;Trait&lt;/strong&gt; (a reusable structural behavior) only extends other Traits or external system interfaces, preventing illegal coupling with hard Agents.&lt;/p&gt;

&lt;p&gt;Here is the condition that enforces this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ClAgent&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="k"&gt;sealed&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TraitInterfacesMustExtendOnlyTraitInterfacesCondition&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ICondition&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Interface&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Description&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"extend only trait interfaces"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ConditionResult&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;Check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Interface&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Architecture&lt;/span&gt; &lt;span class="n"&gt;architecture&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;interf&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;interf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsTrait&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ConditionResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;interf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;$"&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;interf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FullName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; is ignored (Not a [ClTrait] interface)"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;interf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ImplementedInterfaces&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsNullOrEmpty&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ConditionResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;interf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;$"&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;interf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FullName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; has no parent interface"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;allParentsAreTraitsOrExternal&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;interf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ImplementedInterfaces&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;All&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parent&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; 
                &lt;span class="n"&gt;interf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;HasInterfaceBypass&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="n"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsTrait&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="n"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsClprolf&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;faultyParent&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;interf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ImplementedInterfaces&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FirstOrDefault&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parent&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; 
                &lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="n"&gt;interf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;HasInterfaceBypass&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="n"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsTrait&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsClprolf&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ConditionResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="n"&gt;interf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                &lt;span class="n"&gt;allParentsAreTraitsOrExternal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;allParentsAreTraitsOrExternal&lt;/span&gt; 
                    &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="s"&gt;$"All parent interfaces of &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;interf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FullName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; are traits or external third-party interfaces."&lt;/span&gt;
                    &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;$"&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;interf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FullName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; is a trait interface but it inherits from &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;faultyParent&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="n"&gt;FullName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; which is NEITHER a trait interface NOR an external system interface"&lt;/span&gt;
            &lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;CheckEmpty&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;By mapping the technical structure of MVVM into a simple, unified vocabulary of &lt;strong&gt;Agents&lt;/strong&gt; and &lt;strong&gt;Workers&lt;/strong&gt;, the cognitive load drops. The architecture stops being just about "WPF mechanics" and becomes a clear map of responsibilities.&lt;/p&gt;

&lt;p&gt;The main benefit of this approach is consistency: whether you are looking at a desktop view-model, a web API controller, or a console application, the semantic definitions remain the same.&lt;/p&gt;




</description>
      <category>dotnet</category>
      <category>csharp</category>
      <category>architecture</category>
      <category>oop</category>
    </item>
    <item>
      <title>Securing Your Spring Boot Architecture: A Pragmatic Approach with Clprolf</title>
      <dc:creator>Charles Koffler</dc:creator>
      <pubDate>Thu, 11 Jun 2026 12:39:31 +0000</pubDate>
      <link>https://dev.to/charles_koffler_bcabc582b/securing-your-spring-boot-architecture-a-pragmatic-approach-with-clprolf-5ade</link>
      <guid>https://dev.to/charles_koffler_bcabc582b/securing-your-spring-boot-architecture-a-pragmatic-approach-with-clprolf-5ade</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Spring Boot is an incredible framework. It gives developers immense freedom to build and scale applications quickly. However, in large teams or complex environments, this absolute freedom can sometimes lead to architectural drift. Spring cares about making your application work, but it doesn't enforce code symmetry or strict layering.&lt;/p&gt;

&lt;p&gt;How can we ensure our architecture remains clean, maintainable, and predictable over time?&lt;/p&gt;

&lt;p&gt;In this article, we'll share a real-world example of how we achieved &lt;strong&gt;psychological safety&lt;/strong&gt; for our development team by pairing Spring Boot with &lt;strong&gt;Clprolf&lt;/strong&gt;, a lightweight semantic framework designed to enforce architectural rules through automated tests.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Core Concept: Architectural Psychological Safety
&lt;/h2&gt;

&lt;p&gt;When a project grows, the mental load on tech leads and developers increases. You worry about whether a junior developer accidentally bypassed a service layer, or if a database entity is leaking into a controller.&lt;/p&gt;

&lt;p&gt;Instead of relying solely on code reviews, we can use a declarative approach. By using semantic annotations, we tell our framework &lt;em&gt;what&lt;/em&gt; a class is supposed to be, and automated tests verify that the rules are never broken.&lt;/p&gt;




&lt;h2&gt;
  
  
  A Practical Example: The Weather Observation API
&lt;/h2&gt;

&lt;p&gt;Let’s look at a concrete implementation: a clean, batch-optimized Weather API. We organized our components using Clprolf's core concepts: &lt;code&gt;@ClAgent&lt;/code&gt; (for functional components), &lt;code&gt;@ClFamily&lt;/code&gt; (for contracts/interfaces), and &lt;code&gt;@ClWorker&lt;/code&gt; (for specialized execution units).&lt;/p&gt;

&lt;h3&gt;
  
  
  1. The Pure Contract (Interface)
&lt;/h3&gt;

&lt;p&gt;Our controller interface is completely decoupled from the Web framework. It expresses pure business intent and is tagged as a framework family contract.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;org.clprolf.weatherapp.controllers&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.clprolf.framework.ClAgent&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.clprolf.framework.ClFamily&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.clprolf.weatherapp.entities.Observation&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.http.ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.List&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@ClAgent&lt;/span&gt;
&lt;span class="nd"&gt;@ClFamily&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;ClprolfWeatherController&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Observation&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;getObsByStation&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;station&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Observation&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;createObservation&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Observation&lt;/span&gt; &lt;span class="n"&gt;observation&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Observation&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;getAllObs&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. The Spring Boot Implementation
&lt;/h3&gt;

&lt;p&gt;The implementation handles the HTTP plumbing. Notice how clean it remains, focusing only on routing and database interaction via the repository (&lt;code&gt;ObservationDao&lt;/code&gt;).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;org.clprolf.weatherapp.controllers.impl&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;jakarta.validation.Valid&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.clprolf.framework.ClAgent&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.clprolf.weatherapp.controllers.ClprolfWeatherController&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.clprolf.weatherapp.entities.Observation&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.clprolf.weatherapp.repos.ObservationDao&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.beans.factory.annotation.Autowired&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.http.HttpStatus&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.http.ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.web.bind.annotation.*&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.List&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@ClAgent&lt;/span&gt;
&lt;span class="nd"&gt;@RestController&lt;/span&gt;
&lt;span class="nd"&gt;@RequestMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/weatherapi/observations"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ClprolfWeatherControllerImpl&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;ClprolfWeatherController&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Autowired&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;ObservationDao&lt;/span&gt; &lt;span class="n"&gt;obsDao&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@GetMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"get/station/{station}"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Observation&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;getObsByStation&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@PathVariable&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;station&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Observation&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;observations&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;obsDao&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findByIdStation&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;station&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;observations&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isEmpty&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;notFound&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ok&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;observations&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@PostMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"create"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Observation&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;createObservation&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@Valid&lt;/span&gt; &lt;span class="nd"&gt;@RequestBody&lt;/span&gt; &lt;span class="nc"&gt;Observation&lt;/span&gt; &lt;span class="n"&gt;observation&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;Observation&lt;/span&gt; &lt;span class="n"&gt;savedObservation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;obsDao&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;save&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;observation&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;HttpStatus&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;CREATED&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;savedObservation&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@GetMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"all"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Observation&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;getAllObs&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Observation&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;allObservations&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;obsDao&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findAll&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;allObservations&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isEmpty&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;noContent&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;ResponseEntity&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ok&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;allObservations&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;💡 A Note on the Service Layer &amp;amp; Clprolf&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For brevity, this CRUD example connects the Controller directly to the Worker (DAO). In a real-world application, you would naturally introduce a Service layer to handle specific business rules. &lt;/p&gt;

&lt;p&gt;In the Clprolf ecosystem, this Service would simply be another &lt;code&gt;@ClAgent&lt;/code&gt;. It is the core Domain Agent executing its specific functional job, sitting between the API entrypoint (the Controller) and the infrastructure worker (the DAO).&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  3. The Data Access Layer &amp;amp; Composite Identity
&lt;/h3&gt;

&lt;p&gt;To keep our database layer optimized for high-volume weather data, we separated the identity from the entity. Here is our immutable composite ID (&lt;code&gt;ObservationId&lt;/code&gt;) and its corresponding data access object (&lt;code&gt;ObservationDao&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Notice how Clprolf's annotations (&lt;code&gt;@ClAgent&lt;/code&gt;, &lt;code&gt;@ClWorker&lt;/code&gt;) live alongside standard JPA annotations, cleanly documenting the role of each class.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;org.clprolf.weatherapp.entities&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;jakarta.persistence.Column&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;jakarta.persistence.Embeddable&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.clprolf.framework.ClAgent&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.time.OffsetDateTime&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.Objects&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@ClAgent&lt;/span&gt;
&lt;span class="nd"&gt;@Embeddable&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ObservationId&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Column&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;station&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;OffsetDateTime&lt;/span&gt; &lt;span class="n"&gt;dayUTC&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Leveraging Java 8+ time types for strict UTC handling&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getStation&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;station&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;OffsetDateTime&lt;/span&gt; &lt;span class="nf"&gt;getDayUTC&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;dayUTC&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Object&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;getClass&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getClass&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="nc"&gt;ObservationId&lt;/span&gt; &lt;span class="n"&gt;that&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ObservationId&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;Objects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;station&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;that&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;station&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nc"&gt;Objects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dayUTC&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;that&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;dayUTC&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;hashCode&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;Objects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;hash&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;station&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dayUTC&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the Data Access Object (DAO) interface, tagged as a framework worker component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;org.clprolf.weatherapp.repos&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.List&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.clprolf.framework.ClFamily&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.clprolf.framework.ClWorker&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.clprolf.weatherapp.entities.Observation&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.clprolf.weatherapp.entities.ObservationId&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.data.jpa.repository.JpaRepository&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.stereotype.Repository&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@ClWorker&lt;/span&gt;
&lt;span class="nd"&gt;@ClFamily&lt;/span&gt;
&lt;span class="nd"&gt;@Repository&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;ObservationDao&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;JpaRepository&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Observation&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;ObservationId&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Observation&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;findByIdStation&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;station&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Automated Enforcement in the CI/CD Pipeline
&lt;/h2&gt;

&lt;p&gt;The real magic happens behind the scenes. We use ArchUnit rules integrated into our test suite to ensure that no one violates the design patterns.&lt;/p&gt;

&lt;p&gt;For instance, we enforce that specific trait interfaces extend only other trait interfaces. If a rule cannot be evaluated yet (e.g., if a project doesn't use traits on day one), we safely allow it to bypass without breaking the CI build using &lt;code&gt;.allowEmptyShould(true)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Here is a glimpse of how strict structural checks are written:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ArchTest&lt;/span&gt;
&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;ArchRule&lt;/span&gt; &lt;span class="n"&gt;trait_interfaces_must_extend_only_trait_interfaces&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
        &lt;span class="n"&gt;classes&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;that&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;areInterfaces&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;and&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;areAnnotatedWith&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ClTrait&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;should&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ArchCondition&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;JavaClass&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;"extend only @ClTrait"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                    &lt;span class="nd"&gt;@Override&lt;/span&gt;
                    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;check&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;JavaClass&lt;/span&gt; &lt;span class="n"&gt;trait&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;ConditionEvents&lt;/span&gt; &lt;span class="n"&gt;events&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;JavaClass&lt;/span&gt; &lt;span class="n"&gt;parent&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;trait&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getRawInterfaces&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                            &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;parent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isAnnotatedWith&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ClTrait&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                                      &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;parent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isAnnotatedWith&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ClFree&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                                      &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;parent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isAnnotatedWith&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ClFamily&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;parent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isAnnotatedWith&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ClTrait&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

                            &lt;span class="n"&gt;events&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;SimpleConditionEvent&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;trait&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ok&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;trait&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getName&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" extends "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;parent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getName&lt;/span&gt;&lt;span class="o"&gt;()));&lt;/span&gt;
                        &lt;span class="o"&gt;}&lt;/span&gt;
                    &lt;span class="o"&gt;}&lt;/span&gt;
                &lt;span class="o"&gt;})&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;allowEmptyShould&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Prevents blocking the CI pipeline prematurely&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;By combining the runtime power of Spring Boot with the architectural guardrails of Clprolf, we created a safe environment for our team. Senior developers can rest assured that the design pattern is respected, and junior developers receive immediate, automated feedback on their code structure before it even reaches a human code review.&lt;/p&gt;

&lt;p&gt;It’s not about restricting creativity; it’s about removing the anxiety of architectural erosion.&lt;/p&gt;




</description>
      <category>springboot</category>
      <category>java</category>
      <category>cleancode</category>
    </item>
    <item>
      <title>Introducing the ArchUnit Checker for the Clprolf Framework</title>
      <dc:creator>Charles Koffler</dc:creator>
      <pubDate>Mon, 01 Jun 2026 07:34:53 +0000</pubDate>
      <link>https://dev.to/charles_koffler_bcabc582b/introducing-the-archunit-checker-for-the-clprolf-framework-145b</link>
      <guid>https://dev.to/charles_koffler_bcabc582b/introducing-the-archunit-checker-for-the-clprolf-framework-145b</guid>
      <description>&lt;p&gt;One of the most interesting aspects of architectural frameworks is not the rules themselves, but the ability to verify that those rules are actually being followed.&lt;/p&gt;

&lt;p&gt;The Clprolf Framework now includes automated checker extensions for both &lt;strong&gt;Java&lt;/strong&gt; and &lt;strong&gt;.NET (C#)&lt;/strong&gt; projects. Rather than relying solely on documentation, Clprolf's structural principles can be validated automatically during development and continuous integration.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Clprolf?
&lt;/h2&gt;

&lt;p&gt;Clprolf ("Clear PROgramming Language and Framework") is a lightweight object-oriented framework built around a simple idea:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A class should clearly express its primary role.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To make this explicit, Clprolf distinguishes between business-oriented classes and technical classes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Classes        Interfaces
--------        ----------
Agent           Family
Worker          Trait
Draft           Free

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The framework is based on two fundamental principles:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Separate business concerns (Agents) from technical concerns (Workers).&lt;/li&gt;
&lt;li&gt;Preserve the conceptual domain through inheritance.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Bringing Architecture into the Build Process
&lt;/h2&gt;

&lt;p&gt;Architectural guidelines are often written down, discussed, and eventually forgotten. The Clprolf checker takes a different approach: architectural rules become executable tests.&lt;/p&gt;

&lt;p&gt;By using &lt;strong&gt;ArchUnit&lt;/strong&gt; in Java and &lt;strong&gt;ArchUnitNET&lt;/strong&gt; in C# .NET, violations can be detected automatically from your favorite IDE (IntelliJ IDEA, Visual Studio), build tools (Maven, dotnet CLI), or any CI/CD pipeline.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ecosystem Symmetry (.NET vs Java)
&lt;/h3&gt;

&lt;p&gt;The framework maintains absolute functional parity between ecosystems. The syntax effortlessly mirrors each language's native style:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;In Java (ArchUnit):&lt;/strong&gt; Marked using &lt;code&gt;@Annotation&lt;/code&gt; syntax.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;In .NET (ArchUnitNET):&lt;/strong&gt; Marked using native C# &lt;code&gt;[Attribute]&lt;/code&gt; syntax enclosed in brackets.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Core Rules
&lt;/h2&gt;

&lt;p&gt;The checker validates the framework's core rules through 8 mandatory semantic tests (&lt;code&gt;ClprolfArchTest&lt;/code&gt; in Java, or its xUnit equivalent in .NET).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;In this section:&lt;/strong&gt;&lt;br&gt;
To keep the documentation simple, the optional &lt;code&gt;ClSystem&lt;/code&gt; annotation is not included in the rules' descriptions. It is seamlessly handled by the checker as an independent role.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  1. A class cannot mix roles (&lt;code&gt;clprolf_classes_must_not_mix_agent_and_worker&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;A class cannot be annotated as both Agent and Worker.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Java&lt;/span&gt;
&lt;span class="nd"&gt;@ClAgent&lt;/span&gt; &lt;span class="nd"&gt;@ClWorker&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;InvalidClass&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// C#&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ClAgent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ClWorker&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;InvalidClass&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A class must have a single primary responsibility.&lt;/p&gt;




&lt;h3&gt;
  
  
  2. Inheritance must not mix domains (&lt;code&gt;agent_worker_inheritance_must_not_mix&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;A Worker class cannot inherit from an Agent class, and vice versa. This ensures that inheritance strictly preserves the conceptual domain. Forcing an override is possible locally using &lt;code&gt;@ClBypass&lt;/code&gt; (or &lt;code&gt;[ClBypass]&lt;/code&gt;).&lt;/p&gt;




&lt;h3&gt;
  
  
  3. Family interfaces must match implementation roles (&lt;code&gt;family_role_must_match_implementation&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;A class implementing a &lt;code&gt;@ClFamily&lt;/code&gt; (or &lt;code&gt;[ClFamily]&lt;/code&gt;) interface must have a role compatible with the target role of that interface. For example, an Agent family interface must be implemented by an Agent class.&lt;/p&gt;




&lt;h3&gt;
  
  
  4. Trait interfaces must extend only trait interfaces (&lt;code&gt;trait_interfaces_must_extend_only_trait_interfaces&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;A &lt;code&gt;@ClTrait&lt;/code&gt; interface can only inherit from other &lt;code&gt;@ClTrait&lt;/code&gt; interfaces. A trait remains a trait throughout the contract hierarchy.&lt;/p&gt;




&lt;h3&gt;
  
  
  5. Clprolf interfaces must declare a target role (&lt;code&gt;clprolf_interfaces_must_have_target_role&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;Every Family and Trait interface must explicitly declare its target domain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;code&gt;Family&lt;/code&gt; interface must declare exactly one target role: Agent or Worker.&lt;/li&gt;
&lt;li&gt;A &lt;code&gt;Trait&lt;/code&gt; interface must declare at least one target role (Agent, Worker, or exceptionally both for cross-cutting capabilities).&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  6. Inheriting interface roles must match trait target roles (&lt;code&gt;inheriting_interface_role_must_match_trait_interface_target_role&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;When an interface (Family or Trait) inherits from a Trait, its target role must be compatible with that trait. Cross-cutting traits (annotated as both Agent and Worker) are universally compatible.&lt;/p&gt;




&lt;h3&gt;
  
  
  7. Family target roles must match inherited family interfaces (&lt;code&gt;family_interface_target_role_must_match_inherited_family_interface&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;When a Family interface inherits from another Family interface, both must share compatible target roles to preserve the conceptual domain across contract hierarchies.&lt;/p&gt;




&lt;h3&gt;
  
  
  8. Direct trait implementation must respect trait roles (&lt;code&gt;trait_interface_role_must_match_direct_implementation&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;While direct implementation of a Trait by a concrete class is tolerated in standard mode, the class role must match the trait's target role.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Valid: Payable is an Agent trait&lt;/span&gt;
&lt;span class="nd"&gt;@ClAgent&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Order&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Payable&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Optional Strict Validation
&lt;/h2&gt;

&lt;p&gt;A second test suite, &lt;code&gt;ClprolfStrictArchTest&lt;/code&gt; (available in both GitHub repositories), adds 4 strict rules for teams demanding absolute classification. These can also be run standalone to audit technical debt on existing legacy codebases.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Every class must declare a role (&lt;code&gt;optional_all_classes_should_have_clprolf_role&lt;/code&gt;):&lt;/strong&gt; All classes must explicitly be tagged as Agent, Worker, or Draft.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Every interface must declare a role (&lt;code&gt;optional_all_interfaces_should_have_clprolf_role&lt;/code&gt;):&lt;/strong&gt; All interfaces must explicitly be tagged as Family, Trait, or Free.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No direct trait implementation (&lt;code&gt;optional_class_should_not_implement_trait_directly&lt;/code&gt;):&lt;/strong&gt; Classes are forbidden from implementing a Trait directly; traits must be inherited through a Family interface.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Single Family interface implementation (&lt;code&gt;optional_class_must_implement_only_one_family_interface&lt;/code&gt;):&lt;/strong&gt; A class can only implement one primary Family interface, effectively mimicking single inheritance patterns. Multiple inheritance is cleanly shifted into the Family interface itself:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// C# Strict Pattern&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ClAgent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ClFamily&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;IHorse&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IAnimal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IMammal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IPayable&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ClAgent&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Horse&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IHorse&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Explicit Escapes: Granular Bypasses
&lt;/h2&gt;

&lt;p&gt;Clprolf values pragmatism over dogmatism. When edge cases occur (such as integrating legacy code or external libraries), developers can explicitly sign off on architectural exceptions using precise, language-native operators:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;@ClBypass&lt;/code&gt; / `[ClBypass]&lt;/strong&gt;`: Overrides role mismatches between Agent and Worker domains.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;@ClInterfaceBypass&lt;/code&gt; / `[ClInterfaceBypass]&lt;/strong&gt;`: Overrides structural interface constraints (e.g., forcing multiple family implementations or uncommon interface inheritances).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The checkers are highly intelligent: utilizing a bypass does not blind the parser. It merely allows that specific exception while continuing to recursively validate the rest of the inheritance chain.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why It Matters
&lt;/h2&gt;

&lt;p&gt;Many frameworks provide architectural recommendations that eventually become shelfware.&lt;/p&gt;

&lt;p&gt;Clprolf goes one step further by making those recommendations automatically verifiable across the industry's two most prominent enterprise ecosystems. Whether your infrastructure runs on Spring Boot, .NET Core, or a microservice mix of both, Clprolf provides an identical, lightweight, and executable guardrail to help teams maintain structural consistency as codebases evolve.&lt;/p&gt;

</description>
      <category>java</category>
      <category>architecture</category>
      <category>oop</category>
      <category>csharp</category>
    </item>
    <item>
      <title>Clprolf — Official Documentation</title>
      <dc:creator>Charles Koffler</dc:creator>
      <pubDate>Mon, 25 May 2026 16:47:03 +0000</pubDate>
      <link>https://dev.to/charles_koffler_bcabc582b/clprolf-minimalist-mf8</link>
      <guid>https://dev.to/charles_koffler_bcabc582b/clprolf-minimalist-mf8</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Clprolf&lt;/strong&gt; ("Clear PROgramming Language and Framework") is a homegrown architectural framework, for Java and C# .NET. Its motto is "Don't use it - You don't need it!".&lt;/p&gt;

&lt;p&gt;Its goal is to make certain object-oriented programming best practices explicit, without introducing heavy architecture or a steep learning curve.&lt;br&gt;
Thus, the framework helps adhere to the well-known SOLID principles.&lt;/p&gt;

&lt;p&gt;Clprolf is based on a simple idea:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A class should clearly express its primary role.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The framework helps to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;separate business logic from technical code,&lt;/li&gt;
&lt;li&gt;limit architectural drift,&lt;/li&gt;
&lt;li&gt;make inheritance more coherent,&lt;/li&gt;
&lt;li&gt;improve system readability.&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;
  
  
  In Java (ArchUnit)
&lt;/h3&gt;

&lt;p&gt;In the Java ecosystem, components are marked using annotations:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.clprolf.framework.ClAgent&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@ClAgent&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CarImpl&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Car&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Agent logic...&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  In C# (ArchUnitNET)
&lt;/h3&gt;

&lt;p&gt;In the .NET ecosystem, the strict equivalent uses &lt;strong&gt;C# Attributes&lt;/strong&gt; enclosed in brackets &lt;code&gt;[...]&lt;/code&gt; placed directly above the class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Clprolf.ArchUnitNet.Attributes&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;MyApp.Agents&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ClAgent&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Car&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ICar&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Agent logic...&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  💡 Note for Framework Users (.NET vs Java)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Syntax:&lt;/strong&gt; Java's &lt;code&gt;@Annotation&lt;/code&gt; becomes &lt;code&gt;[Attribute]&lt;/code&gt; in C#.&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  I) The Two Fundamental Principles
&lt;/h1&gt;

&lt;p&gt;Clprolf is built around two central principles.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. A class is either business/conceptual or technical
&lt;/h2&gt;

&lt;p&gt;Every class belongs to one of the following worlds:&lt;/p&gt;

&lt;h3&gt;
  
  
  Business / Domain World
&lt;/h3&gt;

&lt;p&gt;The class represents a business or conceptual responsibility.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;order management,&lt;/li&gt;
&lt;li&gt;business logic,&lt;/li&gt;
&lt;li&gt;simulation,&lt;/li&gt;
&lt;li&gt;functional orchestration,&lt;/li&gt;
&lt;li&gt;but also system-oriented agents.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These classes are declared using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ClAgent&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Technical World
&lt;/h3&gt;

&lt;p&gt;The class performs a technical task executed by the system:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;database access (via system agents),&lt;/li&gt;
&lt;li&gt;networking (often by utilizing low-level agents),&lt;/li&gt;
&lt;li&gt;file handling (most frequently with system-oriented agents),&lt;/li&gt;
&lt;li&gt;display / rendering,&lt;/li&gt;
&lt;li&gt;infrastructure,&lt;/li&gt;
&lt;li&gt;no conceptual domain; it is just the system executing technical agents or starting an application,&lt;/li&gt;
&lt;li&gt;generally a system technical service associated with an agent.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These classes are declared using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ClWorker&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. Inheritance must preserve the domain
&lt;/h2&gt;

&lt;p&gt;A class should only inherit from another class belonging to the same conceptual domain.&lt;/p&gt;

&lt;p&gt;Otherwise:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;composition should be used.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This principle prevents incoherent hierarchies and mixed responsibilities.&lt;/p&gt;




&lt;h1&gt;
  
  
  II) Progressive Adoption and Customization
&lt;/h1&gt;

&lt;p&gt;The framework offers total flexibility in both its deployment strategy and its terminology.&lt;/p&gt;




&lt;h2&gt;
  
  
  II.1) Step-by-Step Adoption
&lt;/h2&gt;

&lt;p&gt;Integrating Clprolf into a project can be done incrementally. There is no need to enforce every rule from day one.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Step 1: Classes First.&lt;/strong&gt; You can focus exclusively on the core separation between &lt;code&gt;@ClAgent&lt;/code&gt; (or &lt;code&gt;ClSystem&lt;/code&gt;) and &lt;code&gt;@ClWorker&lt;/code&gt;. This allows the team to master the class splitting without initial friction.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Step 2: Interfaces Later (Optional).&lt;/strong&gt; The interface model (&lt;code&gt;ClFamily&lt;/code&gt;, &lt;code&gt;ClTrait&lt;/code&gt;) can be introduced at a later stage.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;If you find the Clprolf interface system too disruptive compared to your habits or traditional OOP practices, you can choose to ignore it entirely. The framework remains fully functional and highly effective just for your classes.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  II.2) Tailoring the Terminology
&lt;/h2&gt;

&lt;p&gt;If the default vocabulary of Clprolf does not fit your team's nomenclature, the framework is completely agnostic regarding name choices. Since the ArchUnit checker targets the actual declaration types, a simple &lt;strong&gt;automated refactoring (Rename)&lt;/strong&gt; in your IDE is all it takes to adapt the framework to your company's culture.&lt;/p&gt;

&lt;p&gt;Here are a few examples of alternative naming conventions:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Default Role&lt;/th&gt;
&lt;th&gt;Conceptual Alternative&lt;/th&gt;
&lt;th&gt;Technical Alternative&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;@ClAgent&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;@ClConcept&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;@ClDomain&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;@ClWorker&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;@ClMechanism&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;@ClInfrastructure&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;@ClSystem&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;@ClBridge&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;@ClLowLevel&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h1&gt;
  
  
  III) Class Types
&lt;/h1&gt;

&lt;p&gt;Clprolf contains only three class types.&lt;/p&gt;




&lt;h2&gt;
  
  
  III.1) &lt;code&gt;ClAgent&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Represents a business or conceptual class.&lt;/p&gt;

&lt;p&gt;An &lt;code&gt;agent&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;contains business or conceptual logic,&lt;/li&gt;
&lt;li&gt;orchestrates processes,&lt;/li&gt;
&lt;li&gt;makes decisions,&lt;/li&gt;
&lt;li&gt;avoids heavy technical code, which is often delegated to an associated worker,&lt;/li&gt;
&lt;li&gt;can be system-oriented, such as &lt;code&gt;Connection&lt;/code&gt; or &lt;code&gt;Socket&lt;/code&gt; (in which case &lt;code&gt;ClSystem&lt;/code&gt; can also be used).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ClAgent&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrderProcessor&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;OrderRepository&lt;/span&gt; &lt;span class="n"&gt;repository&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;process&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Order&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;total&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Error&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;repository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;save&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: Entities are considered agents because they possess a domain, even without methods.&lt;/p&gt;




&lt;h2&gt;
  
  
  III.2) &lt;code&gt;ClWorker&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Represents a system service.&lt;/p&gt;

&lt;p&gt;A worker class is primarily intended to support agent classes rather than be organized around a class domain.&lt;/p&gt;

&lt;p&gt;Workers provide technical and infrastructure services. They may coordinate or use low-level agents (system agents) such as &lt;code&gt;File&lt;/code&gt;, &lt;code&gt;Connection&lt;/code&gt;, &lt;code&gt;Random&lt;/code&gt;, &lt;code&gt;Logger&lt;/code&gt;, or &lt;code&gt;Parser&lt;/code&gt;, but unlike those classes, a worker is not organized around a class domain of its own.&lt;/p&gt;

&lt;p&gt;Instead, it exists to support other components through technical mechanisms, infrastructure access, application startup, operating-system interaction, or similar responsibilities.&lt;/p&gt;

&lt;p&gt;A &lt;code&gt;worker&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is a system service;&lt;/li&gt;
&lt;li&gt;Provides technical support;&lt;/li&gt;
&lt;li&gt;Manages infrastructure and execution mechanisms;&lt;/li&gt;
&lt;li&gt;Contains technical code;&lt;/li&gt;
&lt;li&gt;Uses system abstractions, but is not one itself;&lt;/li&gt;
&lt;li&gt;Is often there to assist an agent class (including system agents) with rendering/display, direct database access, etc.;&lt;/li&gt;
&lt;li&gt;Allows for the separation of domain/functional code from purely technical code.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  III.3) The Optional &lt;code&gt;ClSystem&lt;/code&gt; Role
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;@ClSystem&lt;/code&gt; annotation (or &lt;code&gt;[ClSystem]&lt;/code&gt; attribute in C#) can be used for system-oriented agents. However, it is not mandatory, keeping the framework as simple as possible.&lt;br&gt;
If used, mixing inheritance between standard agents and system-oriented agents is strictly forbidden. The checker will then treat them as a completely independent role.&lt;br&gt;
Developers who prefer to explicitly declare and finely control system-oriented agents (such as &lt;code&gt;File&lt;/code&gt;) can annotate them as &lt;code&gt;ClSystem&lt;/code&gt; instead of &lt;code&gt;ClAgent&lt;/code&gt;.&lt;br&gt;
Note that classes imposed by third-party frameworks—such as &lt;strong&gt;Controllers&lt;/strong&gt;, &lt;strong&gt;Routing&lt;/strong&gt;, or &lt;strong&gt;Middlewares&lt;/strong&gt; (&lt;em&gt;Filters/Interceptors&lt;/em&gt; in Java)—can also be considered &lt;code&gt;ClSystem&lt;/code&gt; classes.&lt;br&gt;
&lt;code&gt;ClSystem&lt;/code&gt; provides a more technical perspective for those who prefer not to view system-oriented agents as pure agents, allowing them to be separated from more traditional agents.&lt;/p&gt;


&lt;h2&gt;
  
  
  III.4) &lt;code&gt;ClDraft&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;An object without a defined role. Normally, it shouldn't be essential.&lt;/p&gt;

&lt;p&gt;Used:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;during prototyping,&lt;/li&gt;
&lt;li&gt;during refactoring,&lt;/li&gt;
&lt;li&gt;when the role is not yet clear.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ClDraft&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TemporaryManager&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;ClDraft&lt;/code&gt; enables a flexible approach similar to classical OOP.&lt;/p&gt;




&lt;h2&gt;
  
  
  III.5) Primary Domain and Technical Code
&lt;/h2&gt;

&lt;p&gt;Clprolf encourages moving as much technical code as possible from &lt;code&gt;agent&lt;/code&gt; classes into &lt;code&gt;worker&lt;/code&gt; classes.&lt;/p&gt;

&lt;p&gt;However, an &lt;code&gt;agent&lt;/code&gt; may contain a reasonable amount of technical code when doing so improves simplicity or readability.&lt;/p&gt;

&lt;p&gt;An &lt;code&gt;agent&lt;/code&gt; always has a primary domain representing its central responsibility.&lt;/p&gt;

&lt;p&gt;Secondary responsibilities may exist as long as they remain consistent with that primary domain.&lt;/p&gt;




&lt;h3&gt;
  
  
  III.6) An "Opinionated" Framework for the Agent/Worker Choice
&lt;/h3&gt;

&lt;p&gt;Some responsibilities can be interpreted in different ways depending on the architectural vision adopted.&lt;/p&gt;

&lt;p&gt;For example, a connection can be represented:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;as an &lt;code&gt;agent&lt;/code&gt; (or &lt;code&gt;ClSystem&lt;/code&gt;), if viewed as a functional abstraction;&lt;/li&gt;
&lt;li&gt;or as a &lt;code&gt;worker&lt;/code&gt;, if considered a purely technical mechanism.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, in such cases, the Clprolf framework imposes the use of an agent. For example, for a &lt;code&gt;Connection&lt;/code&gt; class:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;an &lt;code&gt;agent&lt;/code&gt; to represent the connection (though you can also choose &lt;code&gt;ClSystem&lt;/code&gt;),&lt;/li&gt;
&lt;li&gt;and delegate the technical code to one or more &lt;code&gt;worker&lt;/code&gt; classes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is why Clprolf can be described as an "opinionated" framework.&lt;br&gt;
As soon as a domain can be identified, it must be chosen over the worker perspective. This choice is argued by the fact that agents and abstractions are easier to manipulate and facilitate design.&lt;br&gt;
However, declaring the &lt;code&gt;Connection&lt;/code&gt; class as a &lt;code&gt;ClAgent&lt;/code&gt; (or &lt;code&gt;ClSystem&lt;/code&gt;) does not preclude it from having a worker for its own technical needs.&lt;/p&gt;


&lt;h3&gt;
  
  
  Java Example Confirming the Clprolf Vision: &lt;code&gt;java.io.File&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;The recent OpenJDK implementation of &lt;code&gt;java.io.File&lt;/code&gt; reveals a fairly long class of about 2,000 lines. The class delegates all purely technical, non-domain-related work to an attribute that acts as the strict equivalent of a worker (&lt;code&gt;FileSystem&lt;/code&gt;).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;FileSystem&lt;/span&gt; &lt;span class="no"&gt;FS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;DefaultFileSystem&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getFileSystem&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;delete&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;isInvalid&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;FS&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;delete&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;       CLPROLF CONCEPT                        JAVA SOURCE CODE (OpenJDK)
┌──────────────────────────┐            ┌──────────────────────────┐
│ @ClAgent (@ClSystem)     │             │       java.io.File       │
│      (System Agent)      │            │                          │
│ Represents the concept   │            │ Manages the file         │
│ of a file and its path.  │            │ abstraction and status.  │
│ Conceptual methods       │            │ Conceptual methods       │
└────────────┬─────────────┘            └────────────┬─────────────┘
             │                                       │
             │ delegates to                          │ calls
             ▼                                       ▼
┌──────────────────────────┐            ┌──────────────────────────┐
│        @ClWorker         │            │    java.io.FileSystem    │
│    (Low-Level Worker)    │            │       (FS variable)      │
│ Performs OS-specific     │            │ OS-specific implement.   │
│ validation and access.   │            │ (WinNT/UnixFileSystem).  │
└──────────────────────────┘            └──────────────────────────┘

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Note: &lt;code&gt;java.io.UnixFileSystem&lt;/code&gt; and &lt;code&gt;WinNTFileSystem&lt;/code&gt; contain many &lt;code&gt;native&lt;/code&gt; methods.&lt;/em&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  IV) Inheritance
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;Class inheritance can be forced using &lt;code&gt;@ClBypass&lt;/code&gt; above the class, but this should be rare.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Valid Example
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ClAgent&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Animal&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;@ClAgent&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Dog&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Animal&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Discouraged Example
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ClWorker&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ClientRepository&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;@ClAgent&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Dog&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;ClientRepository&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, the domains are incompatible.&lt;/p&gt;

&lt;p&gt;Composition should be used instead.&lt;/p&gt;

&lt;p&gt;Inheritance can be forced using &lt;code&gt;@ClBypass&lt;/code&gt; above the class.&lt;/p&gt;




&lt;h1&gt;
  
  
  V) Flexibility
&lt;/h1&gt;

&lt;p&gt;Clprolf is flexible.&lt;/p&gt;

&lt;p&gt;The developer therefore keeps their freedom:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;mixing responsibilities when necessary,&lt;/li&gt;
&lt;li&gt;progressive migration,&lt;/li&gt;
&lt;li&gt;compatibility with existing code,&lt;/li&gt;
&lt;li&gt;while always maintaining a primary domain.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The framework mainly acts as:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;a structural guide.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  VI) Interfaces
&lt;/h1&gt;

&lt;p&gt;In Clprolf, interfaces are viewed as:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;abstract forms of inheritance.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;They therefore participate in the structural continuity of the system.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ClFamily = primary family interface
ClTrait  = trait, shared capability between families
ClDraft = unrestricted interface
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In Clprolf, interfaces are not viewed as simple technical contracts.&lt;/p&gt;

&lt;p&gt;Both &lt;code&gt;extends&lt;/code&gt; and &lt;code&gt;implements&lt;/code&gt; relationships are considered genuine conceptual inheritance relationships.&lt;/p&gt;




&lt;h2&gt;
  
  
  VI.1) &lt;code&gt;ClFamily&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;An interface representing an abstract family.&lt;/p&gt;

&lt;p&gt;Used for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;polymorphism,&lt;/li&gt;
&lt;li&gt;decoupling,&lt;/li&gt;
&lt;li&gt;implementation variants.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Family interfaces also have a target role:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ClAgent&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;or &lt;code&gt;ClWorker&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Example
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ClAgent&lt;/span&gt;
&lt;span class="nd"&gt;@ClFamily&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;Animal&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;eat&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;quantity&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The hierarchy of &lt;code&gt;ClFamily&lt;/code&gt; interfaces naturally reflects the hierarchy of concrete classes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ClAgent&lt;/span&gt;
&lt;span class="nd"&gt;@ClFamily&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;Horse&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Animal&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;jump&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which may lead to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ClAgent&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AnimalImpl&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Animal&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="o"&gt;(...)&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ClAgent&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;HorseImpl&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;AnimalImpl&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Horse&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="o"&gt;(...)&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  VI.2) &lt;code&gt;ClTrait&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;An interface representing a shared capability across multiple &lt;code&gt;ClFamily&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Traits also use a target role:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ClAgent&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ClWorker&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note: a &lt;code&gt;@ClTrait&lt;/code&gt; may be annotated with both &lt;code&gt;@ClAgent&lt;/code&gt; and &lt;code&gt;@ClWorker&lt;/code&gt;.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This exception is reserved for genuinely cross-cutting traits that can be used by both agents and workers.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  Business Example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ClAgent&lt;/span&gt;
&lt;span class="nd"&gt;@ClTrait&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;Payable&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;pay&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Technical Example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ClWorker&lt;/span&gt;
&lt;span class="nd"&gt;@ClTrait&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;Persistable&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  VI.3) Illustration of the Interface Family / Implementation Parallel
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[ABSTRACT WORLD / INTERFACES]          │    [CONCRETE WORLD / CLASSES]
                                       │
       @ClAgent @ClFamily              │        @ClAgent
        interface Animal               │       class AnimalImpl
               ▲                       │               ▲
               │ (extends)             │               │ (extends)
               │                       │               │
       @ClAgent @ClFamily              │        @ClAgent
         interface Horse               │       class HorseImpl
               ▲                       │               ▼ (implements)
               │                       │       👉 implements Horse
               └───────────────────────┼───────  (and extends AnimalImpl)
                (Structural Inheritance)│
                                       │
 ──────────────────────────────────────┴─────────────────────────────────
  👉 THE TRAIT (Cross-cutting):

       @ClAgent @ClTrait               │
        interface Jumpable             │
               ▲                       │
               │ (inherited by Family) │
               │                       │
     Horse extends Jumpable            │
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  VI.4) &lt;code&gt;ClFree&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;A generic interface without a specific role. It shouldn't be necessary.&lt;/p&gt;

&lt;p&gt;Allows flexibility.&lt;/p&gt;




&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ClFree&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;ExternalApi&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  VI.5) Using Interfaces
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;In Clprolf, &lt;code&gt;Family&lt;/code&gt; interfaces closely resemble pure abstract classes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They are intended to be implemented by one or more future Clprolf classes. Therefore, they have a target role (&lt;code&gt;agent&lt;/code&gt; or &lt;code&gt;worker&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;A class can only implement a single main &lt;code&gt;Family&lt;/code&gt; at a time, and the class role must match the target role of the interface. Clprolf thus uses single implementation for interfaces, in the same way that Java uses single inheritance for classes. Indeed, a &lt;code&gt;Family&lt;/code&gt; is always the structural reflection of its implementation. This notably allows for systematic loose coupling.&lt;br&gt;
However, multiple implementation is not removed, but rather shifted to the &lt;code&gt;Family&lt;/code&gt; implemented by the class.&lt;br&gt;
&lt;strong&gt;This might seem restrictive and unconventional, but it only applies in strict mode, which is not the default. This prevents multiple implementations of the same family from repeating a multi-contract declaration, and helps developers quickly understand what the classes actually implement.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Trait&lt;/code&gt; interfaces express a common functionality across multiple &lt;code&gt;Family&lt;/code&gt; interfaces.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A &lt;code&gt;Trait&lt;/code&gt; therefore represents a cross-cutting trait shared among several families.&lt;/p&gt;

&lt;p&gt;Normally, a &lt;code&gt;Trait&lt;/code&gt; can only be inherited by a &lt;code&gt;Family&lt;/code&gt; interface, and not directly implemented by a class. This prevents a trait from being separated from its family interface, and clarifies class implementations (especially when a family has multiple implementations).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;However, this only applies in strict mode, which is not the default.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Concrete class
    ↓ implements
ClFamily
    ↓ inherits from
ClTrait

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: A &lt;code&gt;Family&lt;/code&gt; interface can inherit from multiple &lt;code&gt;Family&lt;/code&gt; or &lt;code&gt;Trait&lt;/code&gt; interfaces.&lt;br&gt;
A &lt;code&gt;Trait&lt;/code&gt; interface can only inherit from other &lt;code&gt;Traits&lt;/code&gt;, because a trait remains a trait.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Interface inheritance can still be forced using &lt;code&gt;@ClInterfaceBypass&lt;/code&gt; above the interface (or &lt;code&gt;@ClBypass&lt;/code&gt; to force inheritance between different target roles). However, these bypasses should be rare.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  VI.6) A Real-World Example of &lt;code&gt;ClFamily&lt;/code&gt; and &lt;code&gt;ClTrait&lt;/code&gt; Interfaces
&lt;/h2&gt;

&lt;p&gt;Let's look at this real-world example, which utilizes a design perfectly applicable to the Clprolf Framework:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.tngtech.archunit.lang&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@ClAgent&lt;/span&gt; &lt;span class="nd"&gt;@ClFamily&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;ArchRule&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;CanBeEvaluated&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;CanOverrideDescription&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ArchRule&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="c1"&gt;//(…)&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.tngtech.archunit.library&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Architectures&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="c1"&gt;//(…)&lt;/span&gt;
&lt;span class="nd"&gt;@ClAgent&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LayeredArchitecture&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;ArchRule&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="c1"&gt;// (…)&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;In this example, &lt;code&gt;CanBeEvaluated&lt;/code&gt; and &lt;code&gt;CanOverrideDescription&lt;/code&gt; act as &lt;code&gt;@ClTrait&lt;/code&gt; interfaces, while &lt;code&gt;ArchRule&lt;/code&gt; formalizes the &lt;code&gt;@ClFamily&lt;/code&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  VI.7) Note on Clprolf and the Interface Segregation Principle (ISP)
&lt;/h2&gt;

&lt;p&gt;Clprolf inherently respects the ISP; it is simply a matter of adapting the design of your classes and interfaces using the appropriate families and traits:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ClAgent&lt;/span&gt;
&lt;span class="nd"&gt;@ClTrait&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;Scanner&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;scan&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Document&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;@ClAgent&lt;/span&gt;
&lt;span class="nd"&gt;@ClTrait&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;Fax&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;fax&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Document&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;@ClAgent&lt;/span&gt;
&lt;span class="nd"&gt;@ClTrait&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;Printer&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Document&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;@ClAgent&lt;/span&gt;
&lt;span class="nd"&gt;@ClFamily&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;OldPrinter&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Printer&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;@ClAgent&lt;/span&gt;
&lt;span class="nd"&gt;@ClFamily&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;ModernPrinter&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;OldPrinter&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Scanner&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Fax&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;@ClAgent&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OldPrinterImpl&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;OldPrinter&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// (...)&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;@ClAgent&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ModernPrinterImpl&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;ModernPrinter&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// (...)&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  VII) General Architecture
&lt;/h1&gt;

&lt;p&gt;Clprolf naturally encourages a simple architecture.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;agent
    ↓ delegates to
worker
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;agent&lt;/code&gt; classes contain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;business rules,&lt;/li&gt;
&lt;li&gt;decisions,&lt;/li&gt;
&lt;li&gt;orchestration.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;worker&lt;/code&gt; classes perform:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;technical work,&lt;/li&gt;
&lt;li&gt;system access,&lt;/li&gt;
&lt;li&gt;machine operations.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;An &lt;code&gt;agent&lt;/code&gt; delegates technical code to one or more &lt;code&gt;worker&lt;/code&gt; classes.&lt;/p&gt;

&lt;p&gt;A worker serves the agent.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌────────────────────────────────────────────────────┐
│                       AGENT                        │
│       conceptual behavior, domain responsibility   │
│                                                    │
└─────────────────────────┬──────────────────────────┘
                          │
                          │ uses / delegates to
                          ▼
┌────────────────────────────────────────────────────┐
│                       WORKER                       │
│          system service for technical execution      │
│               serving an agent                     │
└─────────────────────────┬──────────────────────────┘
                          │
                          │ may use
                          ▼
┌────────────────────────────────────────────────────┐
│              (SYSTEM-ORIENTED) AGENT (ClSystem)    │
│   conceptual object connected to system behavior   │
│   examples: stream, socket, thread, file, window   │
└─────────────────────────┬──────────────────────────┘
                          │
                          │ delegates low-level work to
                          ▼
┌────────────────────────────────────────────────────┐
│                    (LOW-LEVEL) WORKER              │
│     native call, rendering, I/O, OS/runtime work   │
└────────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  VIII) Purpose of the framework
&lt;/h1&gt;

&lt;p&gt;Clprolf does not aim to replace classical OOP.&lt;/p&gt;

&lt;p&gt;It aims to make certain important distinctions explicit:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;business vs technical,&lt;/li&gt;
&lt;li&gt;coherent inheritance vs composition,&lt;/li&gt;
&lt;li&gt;primary responsibility of a class.&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  IX) ArchUnit Checker
&lt;/h1&gt;

&lt;p&gt;An ArchUnit-based checker is available for the Clprolf Framework on GitHub. It is open-source and consists of two classes: &lt;code&gt;ClprolfArchTest&lt;/code&gt; and &lt;code&gt;ClprolfStrictArchTest&lt;/code&gt;. It validates semantic rules.&lt;br&gt;
The rules in &lt;code&gt;ClprolfStrictArchTest&lt;/code&gt; are optional. Likewise, it is easy to change the annotation names if you prefer a different vocabulary.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Java Version (ArchUnit)
&lt;/h2&gt;

&lt;p&gt;Available on GitHub, the Java checker is open-source and centers around two main test classes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;ClprolfArchTest&lt;/code&gt;&lt;/strong&gt;: Validates the standard and fundamental semantic rules of the framework.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;ClprolfStrictArchTest&lt;/code&gt;&lt;/strong&gt;: Gathers optional, more rigid constraints for demanding projects (such as forbidding a class from directly implementing a &lt;code&gt;ClTrait&lt;/code&gt;).
The checkers (both Java and .NET) also contain the definitions for Clprolf annotations (or attributes).&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;In this section:&lt;/strong&gt;&lt;br&gt;
To keep the documentation simple, the optional &lt;code&gt;ClSystem&lt;/code&gt; annotation is not included in the rules' descriptions. It is seamlessly handled by the checker as an independent role.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  2. C# .NET Version (ArchUnitNET)
&lt;/h2&gt;

&lt;p&gt;The port of the .NET extension is available and published on GitHub.&lt;/p&gt;

&lt;p&gt;The Visual Studio solution (2022 to date) contains a project with the framework and ArchUnit rules, along with an xUnit project for the tests.&lt;br&gt;
A third example project is also included. There are currently 8 mandatory tests and 4 strict tests.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rules to Follow
&lt;/h2&gt;

&lt;h3&gt;
  
  
  clprolf_classes_must_not_mix_agent_and_worker:
&lt;/h3&gt;

&lt;p&gt;A class cannot be annotated as both &lt;code&gt;@ClAgent&lt;/code&gt; and &lt;code&gt;@ClWorker&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  agent_worker_inheritance_must_not_mix
&lt;/h3&gt;

&lt;p&gt;A &lt;code&gt;@ClWorker&lt;/code&gt; class cannot inherit from a &lt;code&gt;@ClAgent&lt;/code&gt; class, and vice versa.&lt;/p&gt;

&lt;h3&gt;
  
  
  family_role_must_match_implementation
&lt;/h3&gt;

&lt;p&gt;The target role of a &lt;code&gt;@ClFamily&lt;/code&gt; interface must match the role of the implementing class (&lt;code&gt;@ClAgent&lt;/code&gt; or &lt;code&gt;@ClWorker&lt;/code&gt;). Bypassing is possible using &lt;code&gt;@ClBypass&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  (non-strict mode) trait_interface_role_must_match_direct_implementation
&lt;/h3&gt;

&lt;p&gt;A class that directly implements a trait must have a compatible role (unless bypassed with &lt;code&gt;@ClBypass&lt;/code&gt;). Forbidden in strict mode.&lt;/p&gt;

&lt;h3&gt;
  
  
  trait_interfaces_must_extend_only_trait_interfaces
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;@ClTrait&lt;/code&gt; interfaces can only inherit from other &lt;code&gt;@ClTrait&lt;/code&gt; interfaces. Bypassing is possible using &lt;code&gt;@ClInterfaceBypass&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  clprolf_interfaces_must_have_target_role
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;@ClFamily&lt;/code&gt; interfaces must have exactly one target role: &lt;code&gt;@ClAgent&lt;/code&gt; or &lt;code&gt;@ClWorker&lt;/code&gt;.&lt;br&gt;
&lt;code&gt;@ClTrait&lt;/code&gt; interfaces must have at least one target role: &lt;code&gt;@ClAgent&lt;/code&gt;, &lt;code&gt;@ClWorker&lt;/code&gt;, or exceptionally both.&lt;/p&gt;

&lt;h3&gt;
  
  
  inheriting_interface_role_must_match_trait_interface_target_role
&lt;/h3&gt;

&lt;p&gt;Interfaces (family or trait) that inherit from a trait must have a role compatible with that trait (unless bypassed with &lt;code&gt;@ClBypass&lt;/code&gt;).&lt;/p&gt;

&lt;h3&gt;
  
  
  family_interface_target_role_must_match_inherited_family_interface
&lt;/h3&gt;

&lt;p&gt;Family interfaces inherited by another family interface must have a compatible role, unless &lt;code&gt;@ClBypass&lt;/code&gt; is used.&lt;/p&gt;

&lt;p&gt;Stricter Rules:&lt;/p&gt;

&lt;h3&gt;
  
  
  optional_all_classes_should_have_clprolf_role
&lt;/h3&gt;

&lt;p&gt;All classes must have a Clprolf role (&lt;code&gt;@ClAgent&lt;/code&gt;, &lt;code&gt;@ClWorker&lt;/code&gt;, or &lt;code&gt;@ClDraft&lt;/code&gt;).&lt;/p&gt;

&lt;h3&gt;
  
  
  optional_all_interfaces_should_have_clprolf_role
&lt;/h3&gt;

&lt;p&gt;All interfaces must have a Clprolf role (&lt;code&gt;@ClFamily&lt;/code&gt;, &lt;code&gt;@ClTrait&lt;/code&gt;, or &lt;code&gt;@ClFree&lt;/code&gt;).&lt;/p&gt;

&lt;h3&gt;
  
  
  optional_class_should_not_implement_trait_directly
&lt;/h3&gt;

&lt;p&gt;A class cannot directly implement a &lt;code&gt;@ClTrait&lt;/code&gt; interface (unless &lt;code&gt;@ClInterfaceBypass&lt;/code&gt; is used).&lt;/p&gt;

&lt;h3&gt;
  
  
  optional_class_must_implement_only_one_family_interface (OPTIONAL)
&lt;/h3&gt;

&lt;p&gt;A Clprolf class can only implement a single &lt;code&gt;@ClFamily&lt;/code&gt; interface. Bypassing is possible using &lt;code&gt;@ClInterfaceBypass&lt;/code&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  X) Clprolf and the SOLID Principles
&lt;/h1&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;S&lt;/strong&gt; — Single Responsibility Principle (SRP)
&lt;/h2&gt;

&lt;p&gt;The framework naturally &lt;strong&gt;helps apply&lt;/strong&gt; the Single Responsibility Principle (SRP). Indeed, each class possesses its own conceptual or business domain, which is strictly preserved during inheritance. Adhering strictly to Clprolf makes achieving this even easier.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;O&lt;/strong&gt; — Open-Closed Principle (OCP)
&lt;/h2&gt;

&lt;p&gt;This principle encourages us to anticipate future evolutions as extensions rather than code corrections. The Clprolf framework &lt;strong&gt;facilitates&lt;/strong&gt; extensions through the strict separation of conceptual domains and workers. &lt;code&gt;ClFamily&lt;/code&gt; interfaces promote clear visibility of the interfaces used within classes and push for well-thought-out features. &lt;code&gt;ClTrait&lt;/code&gt; interfaces allow us to keep &lt;code&gt;ClFamily&lt;/code&gt; interfaces even simpler and purer, while enabling traits to be shared and reused seamlessly.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;L&lt;/strong&gt; — Liskov Substitution Principle (LSP)
&lt;/h2&gt;

&lt;p&gt;Clprolf enforces inheritance that remains strictly within the same conceptual domain, alongside the separation between &lt;code&gt;ClAgent&lt;/code&gt; and &lt;code&gt;ClWorker&lt;/code&gt;. Thus, Liskov's LSP principle is more easily taken into account, as a &lt;code&gt;Square&lt;/code&gt; class does not share the same conceptual domain as a &lt;code&gt;Rectangle&lt;/code&gt;.&lt;br&gt;
Indeed, a &lt;code&gt;Giraffe&lt;/code&gt; class belongs to the same domain as an &lt;code&gt;Animal&lt;/code&gt;, from which it inherits its natural behaviors. Conversely, a &lt;code&gt;Square&lt;/code&gt; class does not share the true nature of a &lt;code&gt;Rectangle&lt;/code&gt; (it cannot have independent length and width). In Clprolf, they therefore do not belong to the same conceptual domain, which prevents abusive inheritance and avoids LSP violations.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;I&lt;/strong&gt; — Interface Segregation Principle (ISP)
&lt;/h2&gt;

&lt;p&gt;This principle states that a client should not be forced to implement methods it does not use. With Clprolf, interfaces are custom-tailored for the client, and traits are highly precise. Furthermore, inheritance between interfaces is strictly controlled, thereby promoting compliance with the ISP.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;D&lt;/strong&gt; — Dependency Injection (DI)
&lt;/h2&gt;

&lt;p&gt;Dependency injection implies loose coupling with implementations. This loose coupling is encouraged and facilitated by &lt;code&gt;ClFamily&lt;/code&gt; interfaces, which are intimately bound to their respective classes.&lt;/p&gt;

&lt;h2&gt;
  
  
  "Favoring Composition over Inheritance"
&lt;/h2&gt;

&lt;p&gt;The Clprolf framework ensures that inheritance is used sparingly and with precision, while relying on composition for everything else. It offers a practical and intuitive way to choose between the two.&lt;/p&gt;

&lt;h1&gt;
  
  
  XI) Clprolf and Existing Architectures
&lt;/h1&gt;

&lt;p&gt;Clprolf is compatible with existing architectural approaches such as Domain-Driven Design (DDD), Model-View-Controller (MVC), Clean Architecture, Hexagonal Architecture, and others.&lt;br&gt;
Rather than replacing these architectures, Clprolf acts as an additional layer between Object-Oriented Programming (OOP) and software architecture. Its purpose is to complement, clarify, and reinforce existing architectural principles by making class roles and inheritance relationships more explicit.&lt;br&gt;
In this way, Clprolf helps improve architectural consistency while remaining fully compatible with established design practices.&lt;br&gt;
Furthermore, Clprolf is not just meant for enterprise software, but for all types of applications, including simulations and scientific applications.&lt;/p&gt;

&lt;h1&gt;
  
  
  XII) Summary
&lt;/h1&gt;

&lt;p&gt;Clprolf introduces very few concepts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Classes
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ClAgent
ClWorker
ClSystem
ClDraft
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Interfaces
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ClFamily
ClTrait
ClFree
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Two Fundamental Rules
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Separate business and technical concerns.
2. Inherit only within the same domain.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>architecture</category>
      <category>java</category>
      <category>cleancoding</category>
      <category>csharp</category>
    </item>
    <item>
      <title>Clprolf — Quick Start</title>
      <dc:creator>Charles Koffler</dc:creator>
      <pubDate>Thu, 16 Apr 2026 10:43:05 +0000</pubDate>
      <link>https://dev.to/charles_koffler_bcabc582b/clprolf-a-new-way-to-express-your-talent-with-oop-52ih</link>
      <guid>https://dev.to/charles_koffler_bcabc582b/clprolf-a-new-way-to-express-your-talent-with-oop-52ih</guid>
      <description>&lt;p&gt;Clprolf stands for CLear PROgramming Language and Framework.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"Don't use it - You don't need it!"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Clprolf is both a Java and C# architectural framework designed to make architectural intent visible within object-oriented systems.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It acts as a lightweight structural layer between pure OOP and your architecture (DDD, Clean, Hexagonal, etc.).&lt;/p&gt;




&lt;h2&gt;
  
  
  🎯 The Problem
&lt;/h2&gt;

&lt;p&gt;In traditional object-oriented systems, class responsibilities often become unclear over time. A class may start with a well-defined purpose, but gradually accumulate business rules, technical implementation details, and unrelated infrastructure logic. As systems grow, architectural intent drifts.&lt;/p&gt;




&lt;h2&gt;
  
  
  💡 The Clprolf Approach
&lt;/h2&gt;

&lt;p&gt;Clprolf encourages developers to identify and express the primary responsibility of each class. The framework is based on a simple idea:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;A class should clearly express its primary role.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🧱 Class Roles
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;ClAgent&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Represents a business or conceptual class. It contains business logic, orchestrates processes, and makes decisions. Entities and DTOs are classified as agents since they represent domain data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ClAgent&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrderProcessor&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;OrderRepository&lt;/span&gt; &lt;span class="n"&gt;repository&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;process&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Order&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;total&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Error&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;repository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;save&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;ClWorker&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Represents a technical service or infrastructure class. It exists solely to support agents through technical mechanisms (database access, application startup, OS interactions, parsing). It is not organized around a business domain.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ClWorker&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrderRepository&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Order&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Direct database access code here&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;ClSystem&lt;/code&gt; (Optional)
&lt;/h3&gt;

&lt;p&gt;Represents a system-oriented agent or components at the boundaries of the application (e.g., Sockets, Files, HTTP Controllers, Middlewares). It bridges system behaviors and naturally orchestrates or uses standard agents.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;ClDraft&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;An object without a defined role yet. Used during prototyping or heavy refactoring when the destination of the class isn't clear.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧩 Flexibility &amp;amp; Tailored Adoption
&lt;/h2&gt;

&lt;p&gt;Clprolf acts primarily as a structural guide rather than a rigid architectural framework. It is designed to adapt to your project, not the other way around.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Step-by-Step Integration
&lt;/h3&gt;

&lt;p&gt;You don't have to adopt everything on day one:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Step 1: Classes First.&lt;/strong&gt; Focus exclusively on separating &lt;code&gt;@ClAgent&lt;/code&gt; (or &lt;code&gt;ClSystem&lt;/code&gt;) and &lt;code&gt;@ClWorker&lt;/code&gt;. This allows your team to clean up the codebase without friction.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Step 2: Interfaces Later (Optional).&lt;/strong&gt; The interface system (&lt;code&gt;ClFamily&lt;/code&gt;, &lt;code&gt;ClTrait&lt;/code&gt;) can be introduced in a second phase. If you find it too unconventional for your habits, you can completely ignore it. The framework remains 100% effective just with class annotations.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Custom Terminology (Agnostic Naming)
&lt;/h3&gt;

&lt;p&gt;If the words &lt;code&gt;Agent&lt;/code&gt; or &lt;code&gt;Worker&lt;/code&gt; do not match your team's culture, you can change them! Because the automated ArchUnit checker relies on the underlying types, a simple &lt;strong&gt;automated Rename&lt;/strong&gt; in your IDE allows you to adapt the vocabulary:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Default Role&lt;/th&gt;
&lt;th&gt;Conceptual Alternative&lt;/th&gt;
&lt;th&gt;Technical Alternative&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;@ClAgent&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;@ClConcept&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;@ClDomain&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;@ClWorker&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;@ClMechanism&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;@ClInfrastructure&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;@ClSystem&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;@ClBridge&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;@ClLowLevel&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  🧠 Inheritance &amp;amp; Domain Preservation
&lt;/h2&gt;

&lt;p&gt;Clprolf enforces inheritance &lt;strong&gt;only&lt;/strong&gt; between classes belonging to the same conceptual domain.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ✅ VALID: Same domain continuity&lt;/span&gt;
&lt;span class="nd"&gt;@ClAgent&lt;/span&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Animal&lt;/span&gt; &lt;span class="o"&gt;{}&lt;/span&gt;
&lt;span class="nd"&gt;@ClAgent&lt;/span&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Dog&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Animal&lt;/span&gt; &lt;span class="o"&gt;{}&lt;/span&gt;

&lt;span class="c1"&gt;// ❌ DISCOURAGED: Mixing technical and conceptual worlds&lt;/span&gt;
&lt;span class="nd"&gt;@ClWorker&lt;/span&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AppLauncher&lt;/span&gt; &lt;span class="o"&gt;{}&lt;/span&gt;
&lt;span class="nd"&gt;@ClAgent&lt;/span&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Dog&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;AppLauncher&lt;/span&gt; &lt;span class="o"&gt;{}&lt;/span&gt; &lt;span class="c1"&gt;// Use Composition instead!&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🔗 Interfaces
&lt;/h2&gt;

&lt;p&gt;Clprolf extends this philosophy to abstractions by introducing three categories, which also declare a target role (&lt;code&gt;@ClAgent&lt;/code&gt; or &lt;code&gt;@ClWorker&lt;/code&gt;) to maintain structural continuity:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;ClFamily&lt;/code&gt;&lt;/strong&gt;: Represents an abstract family of related implementations (mirrors pure abstract classes).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;ClTrait&lt;/code&gt;&lt;/strong&gt;: Represents a cross-cutting, shared capability across multiple families.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;ClFree&lt;/code&gt;&lt;/strong&gt;: A generic, unrestricted interface for external integrations.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🛠 nighttime Automated Validation (ArchUnit &amp;amp; ArchUnitNET)
&lt;/h2&gt;

&lt;p&gt;Clprolf includes an open-source semantic checker for Java and .NET. &lt;strong&gt;It does not enforce rigid package structures.&lt;/strong&gt; It only ensures your classes respect their declared identities and inheritance rules through 8 standard automated tests.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔚 In One Sentence
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Clprolf makes explicit what many developers already try to enforce implicitly.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>programming</category>
      <category>oop</category>
      <category>java</category>
      <category>designpatterns</category>
    </item>
    <item>
      <title>🧱 Two Structural Principles Behind Clprolf</title>
      <dc:creator>Charles Koffler</dc:creator>
      <pubDate>Tue, 24 Feb 2026 12:48:40 +0000</pubDate>
      <link>https://dev.to/charles_koffler_bcabc582b/two-structural-principles-behind-clprolf-1kg5</link>
      <guid>https://dev.to/charles_koffler_bcabc582b/two-structural-principles-behind-clprolf-1kg5</guid>
      <description>&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Clprolf builds upon classical Object-Oriented Programming.&lt;/p&gt;

&lt;p&gt;To fully understand this article, readers should already be familiar with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the fundamentals of OOP,&lt;/li&gt;
&lt;li&gt;inheritance and composition,&lt;/li&gt;
&lt;li&gt;common design principles such as SRP,&lt;/li&gt;
&lt;li&gt;the guideline "favor composition over inheritance".&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Clprolf is built around two central principles.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. A class is either business/conceptual or technical
&lt;/h2&gt;

&lt;p&gt;Every class belongs to one of the following worlds:&lt;/p&gt;

&lt;h3&gt;
  
  
  Business / Domain World
&lt;/h3&gt;

&lt;p&gt;The class represents a business or conceptual responsibility.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;order management,&lt;/li&gt;
&lt;li&gt;business logic,&lt;/li&gt;
&lt;li&gt;simulation,&lt;/li&gt;
&lt;li&gt;functional orchestration,&lt;/li&gt;
&lt;li&gt;but also system-oriented agents.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These classes are declared using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ClAgent&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Technical World
&lt;/h3&gt;

&lt;p&gt;The class performs a technical task executed by the system:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;database access (via system agents),&lt;/li&gt;
&lt;li&gt;networking (often by utilizing low-level agents),&lt;/li&gt;
&lt;li&gt;file handling (most frequently with system-oriented agents),&lt;/li&gt;
&lt;li&gt;display / rendering,&lt;/li&gt;
&lt;li&gt;infrastructure,&lt;/li&gt;
&lt;li&gt;no conceptual domain; it is just the system executing technical agents or starting an application,&lt;/li&gt;
&lt;li&gt;generally a system technical service associated with an agent.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These classes are declared using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ClWorker&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. Inheritance must preserve the domain
&lt;/h2&gt;

&lt;p&gt;A class should only inherit from another class belonging to the same conceptual domain.&lt;/p&gt;

&lt;p&gt;Otherwise:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;composition should be used.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This principle prevents incoherent hierarchies and mixed responsibilities.&lt;/p&gt;




&lt;h2&gt;
  
  
  Relation to SRP
&lt;/h2&gt;

&lt;p&gt;The Single Responsibility Principle (SRP) states that a class should have only one reason to change.&lt;/p&gt;

&lt;p&gt;The concept of class domain provides a structural way to think about that responsibility.&lt;/p&gt;

&lt;p&gt;If a class remains organized around a single domain, its evolution tends to remain coherent.&lt;/p&gt;

&lt;p&gt;Clprolf does not replace SRP.&lt;/p&gt;

&lt;p&gt;Instead, it provides a vocabulary for expressing responsibility through domain continuity.&lt;/p&gt;




&lt;h2&gt;
  
  
  Relation to "Favor Composition Over Inheritance"
&lt;/h2&gt;

&lt;p&gt;The guideline "favor composition over inheritance" is widely accepted in object-oriented design.&lt;/p&gt;

&lt;p&gt;Clprolf introduces a structural criterion for applying it.&lt;/p&gt;

&lt;p&gt;When inheritance preserves the same class domain, it may be appropriate.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Animal
  └─ Dog
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Both classes belong to the same conceptual domain.&lt;/p&gt;

&lt;p&gt;However:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Dog
  └─ DatabaseConnection
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;introduces a different domain.&lt;/p&gt;

&lt;p&gt;In such cases, composition generally provides a clearer relationship.&lt;/p&gt;

&lt;p&gt;The principle does not eliminate developer judgment.&lt;/p&gt;

&lt;p&gt;It simply evaluates inheritance through domain continuity.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why This Matters
&lt;/h2&gt;

&lt;p&gt;As systems evolve, responsibilities tend to drift.&lt;/p&gt;

&lt;p&gt;Classes gradually accumulate unrelated concerns and architectural intent becomes harder to identify.&lt;/p&gt;

&lt;p&gt;By making domains explicit and by relating inheritance to domain continuity, Clprolf encourages structures that remain understandable over time.&lt;/p&gt;

&lt;p&gt;The goal is not to restrict developers.&lt;/p&gt;

&lt;p&gt;The goal is to make architectural decisions visible and easier to reason about.&lt;/p&gt;




&lt;h2&gt;
  
  
  Closing
&lt;/h2&gt;

&lt;p&gt;These two principles form the foundation of Clprolf.&lt;/p&gt;

&lt;p&gt;They define how classes are interpreted and how inheritance is understood within the framework.&lt;/p&gt;

&lt;p&gt;From them emerge the structural distinctions that Clprolf makes explicit:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;domain-oriented classes (&lt;code&gt;ClAgent&lt;/code&gt;),&lt;/li&gt;
&lt;li&gt;technical support classes (&lt;code&gt;ClWorker&lt;/code&gt;),&lt;/li&gt;
&lt;li&gt;coherent inheritance,&lt;/li&gt;
&lt;li&gt;explicit architectural responsibilities.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Everything else in Clprolf builds upon these two ideas.&lt;/p&gt;

</description>
      <category>java</category>
      <category>oop</category>
      <category>architecture</category>
      <category>programming</category>
    </item>
    <item>
      <title>Preventing Architectural Drift in Object-Oriented Systems with Clprolf framework</title>
      <dc:creator>Charles Koffler</dc:creator>
      <pubDate>Sun, 15 Feb 2026 12:32:55 +0000</pubDate>
      <link>https://dev.to/charles_koffler_bcabc582b/preventing-architectural-drift-in-object-oriented-systems-a-structural-approach-with-clprolf-360h</link>
      <guid>https://dev.to/charles_koffler_bcabc582b/preventing-architectural-drift-in-object-oriented-systems-a-structural-approach-with-clprolf-360h</guid>
      <description>&lt;h2&gt;
  
  
  A Structural Approach with Clprolf framework
&lt;/h2&gt;

&lt;p&gt;Most large object-oriented systems do not collapse because developers lack expressive tools.&lt;/p&gt;

&lt;p&gt;They collapse because of &lt;strong&gt;architectural drift&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A class is created with a clear intention.&lt;br&gt;
Over time, new responsibilities are added.&lt;br&gt;
Technical code enters domain classes.&lt;br&gt;
Domain decisions appear inside infrastructure classes.&lt;br&gt;
Inheritance is used for convenience instead of conceptual coherence.&lt;/p&gt;

&lt;p&gt;The name of the class remains the same.&lt;/p&gt;

&lt;p&gt;But its role has changed.&lt;/p&gt;

&lt;p&gt;This is not necessarily a failure of developers.&lt;br&gt;
It is often a structural weakness of unconstrained class design.&lt;/p&gt;

&lt;p&gt;When the role of a class is only implicit, nothing prevents that role from drifting silently.&lt;/p&gt;

&lt;p&gt;Clprolf addresses this problem by making the primary role of each class explicit.&lt;/p&gt;


&lt;h2&gt;
  
  
  1. Declaring the role of a class
&lt;/h2&gt;

&lt;p&gt;In classical object-oriented programming, a class is often introduced only by its name:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Sorter&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The name may suggest an intention, but the architecture does not know what kind of class it is.&lt;/p&gt;

&lt;p&gt;Is it a domain object?&lt;br&gt;
Is it a technical utility?&lt;br&gt;
Is it an application coordinator?&lt;br&gt;
Is it infrastructure?&lt;/p&gt;

&lt;p&gt;Clprolf makes the role explicit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ClAgent&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Sorter&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ClWorker&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Sorter&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The class is no longer only a named container.&lt;/p&gt;

&lt;p&gt;It declares its primary architectural role.&lt;/p&gt;

&lt;p&gt;An &lt;code&gt;agent&lt;/code&gt; carries conceptual meaning, domain behavior, application logic, simulation logic, or coordination.&lt;/p&gt;

&lt;p&gt;A &lt;code&gt;worker&lt;/code&gt; performs technical execution, for an agent( I/O, rendering, persistence, networking), launching, or system access.&lt;/p&gt;

&lt;p&gt;The class becomes a class with a declared place in the architecture.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. From description to commitment
&lt;/h2&gt;

&lt;p&gt;A class name describes.&lt;/p&gt;

&lt;p&gt;A Clprolf class role commits.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ClAgent&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrderProcessor&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;means:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This class carries conceptual or application responsibility.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ClWorker&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrderRepository&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;means:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This class performs technical work.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That distinction matters because architectural drift often begins when a class slowly stops matching its original meaning.&lt;/p&gt;

&lt;p&gt;A service starts doing persistence.&lt;br&gt;
A repository starts making business decisions.&lt;br&gt;
A UI class becomes the brain of the application.&lt;br&gt;
A technical helper becomes a hidden domain object.&lt;/p&gt;

&lt;p&gt;In traditional OOP, these shifts can happen silently.&lt;/p&gt;

&lt;p&gt;In Clprolf framework, they become visible because the class has already declared what kind of role it is supposed to play.&lt;/p&gt;

&lt;p&gt;The declaration does not remove human judgment.&lt;/p&gt;

&lt;p&gt;But it gives judgment a structure.&lt;/p&gt;


&lt;h2&gt;
  
  
  3. Structural discipline, not convention
&lt;/h2&gt;

&lt;p&gt;Many architectural principles already tell developers what to do:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;separate concerns;&lt;/li&gt;
&lt;li&gt;avoid God Objects;&lt;/li&gt;
&lt;li&gt;respect layers;&lt;/li&gt;
&lt;li&gt;apply SOLID;&lt;/li&gt;
&lt;li&gt;keep technical code away from domain logic;&lt;/li&gt;
&lt;li&gt;prefer composition when inheritance is conceptually wrong.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These principles are valuable, but they are often expressed as advice.&lt;/p&gt;

&lt;p&gt;Clprolf framework turns part of this advice into structure.&lt;/p&gt;

&lt;p&gt;It does not rely only on naming conventions or team memory.&lt;/p&gt;

&lt;p&gt;It makes role separation visible in the code itself.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ClAgent&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CheckoutService&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ClWorker&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PaymentRepository&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The reader immediately sees the difference:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;CheckoutService&lt;/code&gt; carries application meaning;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;PaymentRepository&lt;/code&gt; performs technical work.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The code does not merely follow a convention.&lt;/p&gt;

&lt;p&gt;It expresses an architectural decision.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Inheritance must respect the declared role
&lt;/h2&gt;

&lt;p&gt;Architectural drift becomes especially dangerous through inheritance.&lt;/p&gt;

&lt;p&gt;Inheritance is not just a way to reuse code.&lt;/p&gt;

&lt;p&gt;It expresses conceptual continuity.&lt;/p&gt;

&lt;p&gt;If a class inherits from another class, it says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I belong to the same conceptual family.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is why Clprolf enforces a simple rule:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A class should inherit only from another class belonging to the same coherent domain.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ClAgent&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Animal&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;@ClAgent&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Dog&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Animal&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is coherent.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Dog&lt;/code&gt; remains in the same conceptual domain as &lt;code&gt;Animal&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;But this is not coherent:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ClWorker&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AnimalWorker&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;@ClAgent&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Dog&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;AnimalWorker&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This inheritance mixes unrelated roles.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Dog&lt;/code&gt; is a conceptual object.&lt;br&gt;
&lt;code&gt;AnimalWorker&lt;/code&gt; is a worker aiding an agent.&lt;/p&gt;

&lt;p&gt;The correct solution is composition.&lt;/p&gt;

&lt;p&gt;The agent may use a worker, but it should not inherit from one.&lt;/p&gt;


&lt;h2&gt;
  
  
  5. Preventing silent migration across layers
&lt;/h2&gt;

&lt;p&gt;In many systems, classes do not become problematic all at once.&lt;/p&gt;

&lt;p&gt;They migrate slowly.&lt;/p&gt;

&lt;p&gt;A class starts as domain logic.&lt;br&gt;
Then it gets logging.&lt;br&gt;
Then database calls.&lt;br&gt;
Then formatting.&lt;br&gt;
Then HTTP handling.&lt;br&gt;
Then retry logic.&lt;br&gt;
Then business decisions from another domain.&lt;/p&gt;

&lt;p&gt;Eventually, the class still has the same name, but no longer the same responsibility.&lt;/p&gt;

&lt;p&gt;Clprolf framework prevents this migration from being silent.&lt;/p&gt;

&lt;p&gt;If a class is declared as an &lt;code&gt;agent&lt;/code&gt;, technical work should remain secondary or be delegated to workers.&lt;/p&gt;

&lt;p&gt;If a class is declared as a &lt;code&gt;worker&lt;/code&gt;, it should not become the place where domain decisions are made.&lt;/p&gt;

&lt;p&gt;An agent may contain a reasonable amount of technical code when that improves simplicity or readability, or having secondary domains.&lt;/p&gt;

&lt;p&gt;A worker may call back an agent when acting as a bridge, for example in UI events, callbacks, or adapters.&lt;/p&gt;

&lt;p&gt;But the primary role must remain clear.&lt;/p&gt;


&lt;h2&gt;
  
  
  6. Why this matters in large systems
&lt;/h2&gt;

&lt;p&gt;In small systems, discipline is often enough.&lt;/p&gt;

&lt;p&gt;A few developers can remember the intended design.&lt;/p&gt;

&lt;p&gt;They know which classes are domain objects, which classes are technical, and which ones are temporary.&lt;/p&gt;

&lt;p&gt;But large systems live longer than individual decisions.&lt;/p&gt;

&lt;p&gt;Teams change.&lt;br&gt;
Features accumulate.&lt;br&gt;
Shortcuts become permanent.&lt;br&gt;
Names stop reflecting reality.&lt;/p&gt;

&lt;p&gt;In that context, implicit architecture is fragile.&lt;/p&gt;

&lt;p&gt;Clprolf helps by making important architectural distinctions explicit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;agent  = conceptual meaning
worker = technical execution
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gives developers a shared vocabulary.&lt;/p&gt;

&lt;p&gt;It also makes violations easier to detect, either manually during code review or automatically through tooling such as architecture tests.&lt;/p&gt;

&lt;p&gt;A class can still be badly designed.&lt;/p&gt;

&lt;p&gt;But it can no longer contradict its declared role silently.&lt;/p&gt;




&lt;h2&gt;
  
  
  7. Clprolf framework and architectural maintenance
&lt;/h2&gt;

&lt;p&gt;Clprolf is not only useful when writing new code.&lt;/p&gt;

&lt;p&gt;It is also useful during maintenance.&lt;/p&gt;

&lt;p&gt;When a class becomes hard to understand, Clprolf encourages a simple question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What is the primary role of this class?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If the answer is not clear, the class may temporarily remain an &lt;code&gt;ClDraft&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If the answer becomes clear, it can be refactored into an &lt;code&gt;agent&lt;/code&gt;, a &lt;code&gt;worker&lt;/code&gt;, or several smaller classes with clearer responsibilities.&lt;/p&gt;

&lt;p&gt;This makes refactoring more natural.&lt;/p&gt;

&lt;p&gt;You do not need to classify everything perfectly from the beginning.&lt;/p&gt;

&lt;p&gt;But over time, the codebase can move toward clearer roles.&lt;/p&gt;

&lt;p&gt;Clprolf therefore helps prevent architectural drift in two ways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;by making roles explicit when classes are created;&lt;/li&gt;
&lt;li&gt;by supporting refactoring when roles become clearer later.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  8. What Clprolf framework does not do
&lt;/h2&gt;

&lt;p&gt;Clprolf does not reduce what can be built.&lt;/p&gt;

&lt;p&gt;It does not remove object-oriented programming.&lt;/p&gt;

&lt;p&gt;It does not replace existing architectures such as MVC, Clean Architecture, or DDD.&lt;/p&gt;

&lt;p&gt;It does not prevent developers from making decisions.&lt;/p&gt;

&lt;p&gt;Instead, it makes those decisions visible.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Architectural drift is one of the main reasons object-oriented systems become difficult to maintain.&lt;/p&gt;

&lt;p&gt;The problem is not that developers do not care about design.&lt;/p&gt;

&lt;p&gt;The problem is that, in classical OOP, the role of a class is often only implicit.&lt;/p&gt;

&lt;p&gt;Clprolf makes that role explicit.&lt;/p&gt;

&lt;p&gt;An &lt;code&gt;agent&lt;/code&gt; carries meaning.&lt;br&gt;
A &lt;code&gt;worker&lt;/code&gt; performs technical execution.&lt;br&gt;
Inheritance must preserve conceptual coherence.&lt;br&gt;
Composition is used when domains diverge.&lt;/p&gt;

&lt;p&gt;The result is not heavier architecture.&lt;/p&gt;

&lt;p&gt;It is clearer architecture.&lt;/p&gt;

&lt;p&gt;Clprolf does not merely describe responsibility.&lt;/p&gt;

&lt;p&gt;It gives responsibility a visible place in the structure of the code.&lt;/p&gt;

&lt;p&gt;And in long-lived systems, that visibility can be decisive.&lt;/p&gt;

</description>
      <category>java</category>
      <category>architecture</category>
      <category>cleancode</category>
      <category>designpatterns</category>
    </item>
    <item>
      <title>Refactoring Your Classes with Clprolf framework</title>
      <dc:creator>Charles Koffler</dc:creator>
      <pubDate>Thu, 25 Dec 2025 14:51:46 +0000</pubDate>
      <link>https://dev.to/charles_koffler_bcabc582b/refactoring-your-classes-with-clprolf-and-indefobj-3j8k</link>
      <guid>https://dev.to/charles_koffler_bcabc582b/refactoring-your-classes-with-clprolf-and-indefobj-3j8k</guid>
      <description>&lt;p&gt;Most developers agree on the &lt;strong&gt;Single Responsibility Principle (SRP)&lt;/strong&gt;.&lt;br&gt;
The real difficulty is not &lt;em&gt;what&lt;/em&gt; to do — it’s &lt;strong&gt;when&lt;/strong&gt; to do it.&lt;/p&gt;

&lt;p&gt;In real projects, we usually:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;write code that works,&lt;/li&gt;
&lt;li&gt;understand it better over time,&lt;/li&gt;
&lt;li&gt;refactor when responsibilities become clearer.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Clprolf framework fits naturally into this workflow&lt;/strong&gt; by supporting postponed architectural decisions through refactoring.&lt;/p&gt;


&lt;h2&gt;
  
  
  1️⃣ Starting from a Classic OOP Class
&lt;/h2&gt;

&lt;p&gt;Let’s start with a very common example.&lt;br&gt;
Nothing exotic. Just a class that &lt;em&gt;works&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrderManager&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;processOrder&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Order&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getTotal&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;IllegalArgumentException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Invalid order"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;saveToDatabase&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;logOrder&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;formatConfirmation&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;sendEmail&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;saveToDatabase&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Order&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Saving order "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getId&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;logOrder&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Order&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Order processed: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getId&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;formatConfirmation&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Order&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Order #"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getId&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" confirmed"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;sendEmail&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Sending email: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This class:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;contains &lt;strong&gt;business rules&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;handles &lt;strong&gt;persistence&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;performs &lt;strong&gt;logging&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;formats messages,&lt;/li&gt;
&lt;li&gt;sends emails.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Everyone has written something like this.&lt;/p&gt;




&lt;h2&gt;
  
  
  2️⃣ Using Clprolf framework Without Thinking About Roles
&lt;/h2&gt;

&lt;p&gt;In Clprolf, you can start &lt;strong&gt;exactly the same way&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;No need to decide anything upfront.&lt;br&gt;
You simply acknowledge that the architectural role is &lt;strong&gt;not yet clear&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ClDraft&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrderManager&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;processOrder&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Order&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getTotal&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;IllegalArgumentException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Invalid order"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;saveToDatabase&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;logOrder&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;formatConfirmation&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;sendEmail&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;saveToDatabase&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Order&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;logOrder&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Order&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;formatConfirmation&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Order&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;sendEmail&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this stage:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;nothing is forced,&lt;/li&gt;
&lt;li&gt;no architectural commitment is made,&lt;/li&gt;
&lt;li&gt;the code can remain like this for a while.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;ClDraft&lt;/code&gt; behaves like classic OOP — &lt;strong&gt;but consciously&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  3️⃣ Applying SRP After Understanding the Code
&lt;/h2&gt;

&lt;p&gt;Later — exactly like in a classic SRP refactoring — you realize that this class mixes different responsibilities.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Concern&lt;/th&gt;
&lt;th&gt;Nature&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Business decision&lt;/td&gt;
&lt;td&gt;Business&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Persistence&lt;/td&gt;
&lt;td&gt;Technical&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Logging&lt;/td&gt;
&lt;td&gt;Technical&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Formatting / I/O&lt;/td&gt;
&lt;td&gt;Technical&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This is where &lt;strong&gt;Clprolf becomes useful&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  4️⃣ Refactoring into Explicit Responsibilities
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Before (ClDraft)

OrderManager
 ├─ business rule
 ├─ persistence
 ├─ logging
 └─ notification


After (SRP made explicit)

OrderProcessor (ClAgent)
 ├─ business decision

OrderRepository (ClWorker)
 └─ persistence

OrderNotifierWorker (ClWorker)
 ├─ logging
 └─ messaging
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🎯 Business Responsibility → &lt;code&gt;agent&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ClAgent&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrderProcessor&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;OrderRepository&lt;/span&gt; &lt;span class="n"&gt;repository&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;OrderNotifierWorker&lt;/span&gt; &lt;span class="n"&gt;worker&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;OrderProcessor&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;OrderRepository&lt;/span&gt; &lt;span class="n"&gt;repository&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
                          &lt;span class="nc"&gt;OrderNotifierWorker&lt;/span&gt; &lt;span class="n"&gt;worker&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;repository&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;repository&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;worker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;worker&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;process&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Order&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getTotal&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;IllegalArgumentException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Invalid order"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;repository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;save&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;worker&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;notify&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;strong&gt;agent&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;expresses &lt;strong&gt;business intent&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;coordinates actions,&lt;/li&gt;
&lt;li&gt;contains &lt;strong&gt;no technical details&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  ⚙️ Technical Responsibilities → &lt;code&gt;worker&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ClWorker&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrderRepository&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Order&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Saving order "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getId&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;@ClWorker&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrderNotifierWorker&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;notify&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Order&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;format&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;send&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Order&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Order processed: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getId&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Order&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Order #"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getId&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" confirmed"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Sending email: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Workers may group related technical concerns when they serve the same technical purpose:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I/O,&lt;/li&gt;
&lt;li&gt;formatting,&lt;/li&gt;
&lt;li&gt;logging,&lt;/li&gt;
&lt;li&gt;infrastructure.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is &lt;strong&gt;acceptable&lt;/strong&gt; because business meaning remains in the agent. And because most of the time, the worker supports an agent.&lt;/p&gt;




&lt;h2&gt;
  
  
  5️⃣ What Changed — and What Didn’t
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ❌ What did &lt;strong&gt;not&lt;/strong&gt; change
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;algorithms,&lt;/li&gt;
&lt;li&gt;behavior,&lt;/li&gt;
&lt;li&gt;performance,&lt;/li&gt;
&lt;li&gt;expressivity.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ✅ What &lt;strong&gt;did&lt;/strong&gt; change
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;responsibilities became explicit,&lt;/li&gt;
&lt;li&gt;architectural intent became visible,&lt;/li&gt;
&lt;li&gt;future evolution became easier.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is simply &lt;strong&gt;SRP applied structurally&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧩 Conclusion
&lt;/h2&gt;

&lt;p&gt;Clprolf framework does &lt;strong&gt;not&lt;/strong&gt; ask developers to think harder —&lt;br&gt;
and not earlier.&lt;/p&gt;

&lt;p&gt;You can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;write code first,&lt;/li&gt;
&lt;li&gt;understand it later,&lt;/li&gt;
&lt;li&gt;refactor responsibilities when needed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;ClDraft&lt;/code&gt; is &lt;strong&gt;not a goal&lt;/strong&gt; —&lt;br&gt;
it is a &lt;strong&gt;temporary state&lt;/strong&gt; that supports real-world development.&lt;/p&gt;

&lt;p&gt;Clprolf framework can work as a &lt;strong&gt;refactoring tool for architectural clarity&lt;/strong&gt;.&lt;/p&gt;




</description>
      <category>java</category>
      <category>oop</category>
      <category>productivity</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Clprolf Framework — Global Model</title>
      <dc:creator>Charles Koffler</dc:creator>
      <pubDate>Sat, 06 Dec 2025 15:55:51 +0000</pubDate>
      <link>https://dev.to/charles_koffler_bcabc582b/a-global-model-of-how-classes-relate-to-each-other-in-clprolf-2igk</link>
      <guid>https://dev.to/charles_koffler_bcabc582b/a-global-model-of-how-classes-relate-to-each-other-in-clprolf-2igk</guid>
      <description>&lt;p&gt;Clprolf framework introduces simple class roles to clarify the natural place of each class in a project.&lt;/p&gt;

&lt;p&gt;Many developers understand the basic distinction:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;an &lt;code&gt;agent&lt;/code&gt; carries meaning, intention, or domain behavior;&lt;/li&gt;
&lt;li&gt;a &lt;code&gt;worker&lt;/code&gt; is a system service and performs technical execution.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But when a project grows, another question appears:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;How do these classes relate to each other globally?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This document provides a conceptual overview of how the main Clprolf roles interact in practice.&lt;/p&gt;

&lt;p&gt;It explains:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;how agents and workers depend on each other;&lt;/li&gt;
&lt;li&gt;how domain-level classes stay separated from technical classes;&lt;/li&gt;
&lt;li&gt;how system-oriented objects such as streams, sockets, files, or threads can be understood;&lt;/li&gt;
&lt;li&gt;how workers act as bridges between conceptual objects and low-level execution.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is not a formal compiler rule-set.&lt;/p&gt;

&lt;p&gt;It is a &lt;strong&gt;mental model&lt;/strong&gt;: a guide that helps developers classify new classes more naturally and understand Clprolf architecture as a whole.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. The basic idea
&lt;/h2&gt;

&lt;p&gt;The core model is simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Agent  = meaning
Worker = execution
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An &lt;code&gt;agent&lt;/code&gt; represents something conceptually meaningful in the program.&lt;/p&gt;

&lt;p&gt;A &lt;code&gt;worker&lt;/code&gt; is a system service. It performs the technical work needed to support agents, the application, or the system.&lt;/p&gt;

&lt;p&gt;In many systems, we also encounter classes that are close to the operating system or runtime, but still have a conceptual identity.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Stream&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Socket&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Thread&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Channel&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;File&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Window&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Button&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These can be understood as &lt;strong&gt;system-oriented agents&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;They are still agents because they represent conceptual objects, but their internal behavior often depends on low-level workers.&lt;/p&gt;

&lt;p&gt;A system-oriented agent is not necessarily a new official class role.&lt;/p&gt;

&lt;p&gt;It is a conceptual category:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;an agent whose domain is connected to a system capability.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  2. Global conceptual diagram
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌────────────────────────────────────────────────────┐
│                       AGENT                        │
│       conceptual behavior, domain responsibility   │
│                                                    │
└─────────────────────────┬──────────────────────────┘
                          │
                          │ uses / delegates to
                          ▼
┌────────────────────────────────────────────────────┐
│                       WORKER                       │
│          system service for technical execution      │
│               serving an agent                     │
└─────────────────────────┬──────────────────────────┘
                          │
                          │ may use
                          ▼
┌────────────────────────────────────────────────────┐
│              (SYSTEM-ORIENTED) AGENT               │
│   conceptual object connected to system behavior   │
│   examples: stream, socket, thread, file, window   │
└─────────────────────────┬──────────────────────────┘
                          │
                          │ delegates low-level work to
                          ▼
┌────────────────────────────────────────────────────┐
│                    (LOW-LEVEL) WORKER              │
│     native call, rendering, I/O, OS/runtime work   │
└────────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This diagram should not be read as a strict one-way call graph.&lt;/p&gt;

&lt;p&gt;It shows the natural direction of responsibility:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;meaning → execution → system capability → low-level operation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  3. Agent
&lt;/h2&gt;

&lt;p&gt;An &lt;code&gt;agent&lt;/code&gt; represents a meaningful object or behavior.&lt;/p&gt;

&lt;p&gt;It carries intention, responsibility, and conceptual identity.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;OrderProcessor&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CheckoutService&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Snake&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;FoodExpert&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;WindowObserver&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Button&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;DirectoryExplorer&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Animal&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;An agent answers questions such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What does this object mean?&lt;/li&gt;
&lt;li&gt;What responsibility does it carry?&lt;/li&gt;
&lt;li&gt;What behavior belongs to its domain?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Agent guidelines
&lt;/h3&gt;

&lt;p&gt;An agent may:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;call other agents;&lt;/li&gt;
&lt;li&gt;delegate technical work to workers;&lt;/li&gt;
&lt;li&gt;hold domain state;&lt;/li&gt;
&lt;li&gt;express business, application, simulation, or UI meaning.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;An agent should avoid:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;directly performing heavy technical work;&lt;/li&gt;
&lt;li&gt;depending directly on low-level system mechanisms when a worker can handle them;&lt;/li&gt;
&lt;li&gt;becoming a mixed class where domain decisions and technical execution are indistinguishable.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If an agent needs system-level behavior, it usually delegates it to a worker.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Worker
&lt;/h2&gt;

&lt;p&gt;A &lt;code&gt;worker&lt;/code&gt; performs technical execution. It is a system service.&lt;/p&gt;

&lt;p&gt;It does not primarily represent a domain concept.&lt;br&gt;
It performs work for an agent, the application, or the system.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;OrderRepository&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;FileWriterWorker&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;DatabaseWorker&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;RendererWorker&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Launcher&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SocketWorker&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SwingRenderer&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;DirectoryExplorerWorker&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A worker answers questions such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What technical operation must be performed?&lt;/li&gt;
&lt;li&gt;What system, framework, I/O, or rendering mechanism must be called?&lt;/li&gt;
&lt;li&gt;What concrete execution is needed by an agent?&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Worker guidelines
&lt;/h3&gt;

&lt;p&gt;A worker may:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;call other workers;&lt;/li&gt;
&lt;li&gt;use system-oriented agents;&lt;/li&gt;
&lt;li&gt;perform I/O, rendering, persistence, networking, or launching;&lt;/li&gt;
&lt;li&gt;call back an agent when acting as a technical bridge, such as in UI events, callbacks, adapters, or asynchronous notifications.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A worker should avoid:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;containing domain decisions;&lt;/li&gt;
&lt;li&gt;becoming the conceptual brain of the application;&lt;/li&gt;
&lt;li&gt;hiding business rules inside technical code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A worker can bridge the domain world and the system world, but it should not absorb the domain.&lt;/p&gt;


&lt;h2&gt;
  
  
  5. System-oriented agent
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;system-oriented agent&lt;/strong&gt; is an agent whose conceptual domain is connected to a system capability.&lt;/p&gt;

&lt;p&gt;It is not simply a worker, because it represents an object with meaning.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a &lt;code&gt;Stream&lt;/code&gt; represents a flow of data;&lt;/li&gt;
&lt;li&gt;a &lt;code&gt;Socket&lt;/code&gt; represents a communication endpoint;&lt;/li&gt;
&lt;li&gt;a &lt;code&gt;Thread&lt;/code&gt; represents an execution path;&lt;/li&gt;
&lt;li&gt;a &lt;code&gt;File&lt;/code&gt; represents a filesystem object;&lt;/li&gt;
&lt;li&gt;a &lt;code&gt;Window&lt;/code&gt; represents a visible interaction space;&lt;/li&gt;
&lt;li&gt;a &lt;code&gt;Button&lt;/code&gt; represents a clickable UI object.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These objects are conceptually meaningful.&lt;/p&gt;

&lt;p&gt;However, their implementation often requires technical operations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;native calls,&lt;/li&gt;
&lt;li&gt;OS interaction,&lt;/li&gt;
&lt;li&gt;rendering,&lt;/li&gt;
&lt;li&gt;I/O,&lt;/li&gt;
&lt;li&gt;event dispatching,&lt;/li&gt;
&lt;li&gt;memory or runtime management.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That low-level work should be handled internally by workers.&lt;/p&gt;
&lt;h3&gt;
  
  
  System-oriented agent guidelines
&lt;/h3&gt;

&lt;p&gt;A system-oriented agent may:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;expose conceptual methods such as &lt;code&gt;open()&lt;/code&gt;, &lt;code&gt;read()&lt;/code&gt;, &lt;code&gt;write()&lt;/code&gt;, &lt;code&gt;click()&lt;/code&gt;, &lt;code&gt;show()&lt;/code&gt;, or &lt;code&gt;close()&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;delegate its technical realization to workers;&lt;/li&gt;
&lt;li&gt;interact with other system-oriented agents in the same coherent system domain.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A system-oriented agent should avoid:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;calling unrelated domain agents directly;&lt;/li&gt;
&lt;li&gt;mixing high-level business decisions with low-level system mechanics;&lt;/li&gt;
&lt;li&gt;exposing technical implementation details as its main identity.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The key idea is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A system-oriented agent represents a system capability as a meaningful object.&lt;br&gt;
A worker performs the low-level execution behind it.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  6. Summary table
&lt;/h2&gt;

&lt;p&gt;Here is a simplified model of direct usage.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;From / To&lt;/th&gt;
&lt;th&gt;Agent&lt;/th&gt;
&lt;th&gt;Worker&lt;/th&gt;
&lt;th&gt;System-oriented agent&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Agent&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Usually no&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Worker&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Controlled callback / bridge&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;System-oriented agent&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Usually no&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes, if same system domain&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This table is a guide, not a rigid rule-set.&lt;/p&gt;

&lt;p&gt;The important idea is not to forbid every possible dependency.&lt;/p&gt;

&lt;p&gt;The important idea is to preserve the direction of meaning:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;agents carry meaning
workers execute
system-oriented agents represent system capabilities
low-level workers perform the technical realization
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  7. Purpose of this model
&lt;/h2&gt;

&lt;p&gt;This model helps developers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;classify new classes correctly;&lt;/li&gt;
&lt;li&gt;avoid accidental mixing of concerns;&lt;/li&gt;
&lt;li&gt;navigate complex systems more safely;&lt;/li&gt;
&lt;li&gt;recognize patterns inside existing codebases;&lt;/li&gt;
&lt;li&gt;understand why some system classes still feel like agents;&lt;/li&gt;
&lt;li&gt;decide when a UI object, listener, socket, stream, or file should be modeled as an agent or as a worker.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It also explains why Clprolf is not just:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;business = agent
technical = worker
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The real model is slightly richer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;agent  = conceptual meaning
worker = technical execution
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Some conceptual objects are close to the system.&lt;/p&gt;

&lt;p&gt;That does not automatically make them workers.&lt;/p&gt;

&lt;p&gt;A button can be an agent.&lt;br&gt;
A listener can be an observer agent.&lt;br&gt;
A stream can be a system-oriented agent.&lt;br&gt;
Their rendering, event dispatching, or native operations can be workers.&lt;/p&gt;


&lt;h2&gt;
  
  
  8. Final synthesis
&lt;/h2&gt;

&lt;p&gt;Clprolf gives each class a natural place.&lt;/p&gt;

&lt;p&gt;At the highest level:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Agent  = meaning
Worker = execution
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then the model expands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Domain agent
    → carries business, application, simulation, or UI meaning

Worker
    → performs technical execution

System-oriented agent
    → represents a conceptual system capability

Low-level worker
    → performs native, rendering, I/O, or runtime operations
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This model keeps Clprolf simple while explaining real-world cases more accurately.&lt;/p&gt;

&lt;p&gt;It avoids a false choice between “everything technical is worker” and “everything conceptual is pure business.”&lt;/p&gt;

&lt;p&gt;Instead, it asks one practical question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What is the main responsibility of this class?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If the class represents something meaningful, it is probably an agent.&lt;/p&gt;

&lt;p&gt;If it mainly executes technical work, it is probably a worker.&lt;/p&gt;

&lt;p&gt;That is the global logic of Clprolf.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final line
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Agents carry meaning.&lt;br&gt;
Workers perform execution.&lt;br&gt;
System-oriented agents represent meaningful system capabilities.&lt;br&gt;
Together, they make architecture easier to read, reason about, and maintain.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>java</category>
      <category>designpatterns</category>
      <category>productivity</category>
      <category>programming</category>
    </item>
    <item>
      <title>Separating Class Responsibilities with Clprolf framework</title>
      <dc:creator>Charles Koffler</dc:creator>
      <pubDate>Thu, 04 Dec 2025 18:06:42 +0000</pubDate>
      <link>https://dev.to/charles_koffler_bcabc582b/separating-class-responsibilities-with-clprolf-7f</link>
      <guid>https://dev.to/charles_koffler_bcabc582b/separating-class-responsibilities-with-clprolf-7f</guid>
      <description>&lt;p&gt;Designing clean, well-structured classes is one of the central challenges of object-oriented programming.&lt;/p&gt;

&lt;p&gt;Clprolf framework addresses this challenge by introducing &lt;strong&gt;class roles&lt;/strong&gt;: a simple way to express the main role of a class and the kind of work it is expected to perform.&lt;/p&gt;

&lt;p&gt;Clprolf does not replace your existing architecture.&lt;/p&gt;

&lt;p&gt;Your repositories, services, controllers, entities, UI components, abstractions, and domain objects all stay where they are.&lt;/p&gt;

&lt;p&gt;Clprolf framework simply adds an explicit role to each important class, making the separation between conceptual logic and technical execution easier to read, maintain, and verify.&lt;/p&gt;




&lt;h2&gt;
  
  
  The “class roles”
&lt;/h2&gt;

&lt;p&gt;Clprolf framework uses class roles.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A class keeps its identity, but its class role tells us what kind of role it plays in the program.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In Clprolf, the two main class roles are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;agent&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;worker&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They help distinguish between classes that carry conceptual meaning and classes that perform technical execution.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Two class roles for two kinds of work
&lt;/h2&gt;

&lt;p&gt;Every significant class should declare its main class role.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;agent&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;An &lt;code&gt;agent&lt;/code&gt; is a class whose main responsibility is conceptual, domain-oriented, or meaningful in the application.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;business services,&lt;/li&gt;
&lt;li&gt;domain objects,&lt;/li&gt;
&lt;li&gt;controllers,&lt;/li&gt;
&lt;li&gt;observers/listeners with a conceptual role,&lt;/li&gt;
&lt;li&gt;UI objects that represent meaningful user interactions,&lt;/li&gt;
&lt;li&gt;simulations,&lt;/li&gt;
&lt;li&gt;application coordinators.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;An agent may contain a small amount of technical code, or secondary domains, if it's practical.&lt;/p&gt;

&lt;p&gt;However, heavy technical work should usually be delegated to workers.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;code&gt;worker&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;A &lt;code&gt;worker&lt;/code&gt; is a class whose main responsibility is technical execution.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;technical support classes for agent&lt;/li&gt;
&lt;li&gt;repositories,&lt;/li&gt;
&lt;li&gt;DAOs,&lt;/li&gt;
&lt;li&gt;file access classes,&lt;/li&gt;
&lt;li&gt;rendering workers,&lt;/li&gt;
&lt;li&gt;launchers,&lt;/li&gt;
&lt;li&gt;persistence classes,&lt;/li&gt;
&lt;li&gt;console or system I/O,&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A worker performs technical work for an agent, for the application, or for the system.&lt;/p&gt;

&lt;p&gt;It should avoid becoming the place where domain decisions are made.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Class roles work with your existing architecture
&lt;/h2&gt;

&lt;p&gt;Clprolf does not replace familiar architectural roles such as Service, Repository, Controller, Entity, View, or DAO.&lt;/p&gt;

&lt;p&gt;It adds a class role on top of them.&lt;/p&gt;

&lt;p&gt;A typical mapping could be:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Existing component&lt;/th&gt;
&lt;th&gt;Clprolf class role&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Service&lt;/td&gt;
&lt;td&gt;&lt;code&gt;agent&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Controller&lt;/td&gt;
&lt;td&gt;&lt;code&gt;agent&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Entity / domain object&lt;/td&gt;
&lt;td&gt;&lt;code&gt;agent&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Repository / DAO&lt;/td&gt;
&lt;td&gt;&lt;code&gt;worker&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Launcher&lt;/td&gt;
&lt;td&gt;&lt;code&gt;worker&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Renderer / low-level display code&lt;/td&gt;
&lt;td&gt;&lt;code&gt;worker&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This mapping is not meant to erase architectural nuance.&lt;/p&gt;

&lt;p&gt;Different teams may interpret certain components differently.&lt;/p&gt;

&lt;p&gt;For example, controllers may be treated as application agents because they coordinate meaningful behavior.&lt;br&gt;
But in some architectures, a controller may be treated as a purely technical endpoint.&lt;/p&gt;

&lt;p&gt;Clprolf allows that flexibility, as long as the choice remains clear and consistent.&lt;/p&gt;


&lt;h2&gt;
  
  
  3. Domain consistency through inheritance rules
&lt;/h2&gt;

&lt;p&gt;Because a class declares its main role, inheritance can be checked for coherence.&lt;/p&gt;

&lt;p&gt;The basic rule is simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A class should inherit only from a class belonging to the same coherent role or domain.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  Allowed
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ClAgent&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Animal&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ClAgent&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Dog&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Animal&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This is coherent: &lt;code&gt;Dog&lt;/code&gt; remains in the same conceptual family as &lt;code&gt;Animal&lt;/code&gt;.&lt;/p&gt;


&lt;h3&gt;
  
  
  Not allowed
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ClWorker&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ClientDAO&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ClAgent&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Dog&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;ClientDAO&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This is not coherent.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Dog&lt;/code&gt; represents a conceptual domain object.&lt;br&gt;
&lt;code&gt;ClientDAO&lt;/code&gt; represents technical class for database calls.&lt;/p&gt;

&lt;p&gt;The issue is not inheritance itself.&lt;br&gt;
The issue is incoherent inheritance across unrelated roles.&lt;/p&gt;

&lt;p&gt;Clprolf makes this kind of mismatch visible and, depending on the implementation, checkable through language rules, tooling, or architecture tests.&lt;/p&gt;


&lt;h2&gt;
  
  
  4. Why this is useful in practice
&lt;/h2&gt;

&lt;p&gt;With Clprolf class roles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;conceptual logic and technical execution stay easier to separate;&lt;/li&gt;
&lt;li&gt;class hierarchies are less likely to drift into incoherent states;&lt;/li&gt;
&lt;li&gt;technical classes are less likely to absorb domain decisions;&lt;/li&gt;
&lt;li&gt;agents are encouraged to delegate heavy technical work to workers;&lt;/li&gt;
&lt;li&gt;roles become easier to understand for developers joining the project;&lt;/li&gt;
&lt;li&gt;architectural discussions become more concrete.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of asking vaguely:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Is this class clean?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;we can ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Is this class coherent with its declared class role?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That question is much easier to discuss, review, and automate.&lt;/p&gt;


&lt;h2&gt;
  
  
  5. Class roles and SOLID
&lt;/h2&gt;

&lt;p&gt;Class roles are only one part of Clprolf, but they support a powerful idea:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Each object should express a unique and well-defined kind of work.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This aligns naturally with the &lt;strong&gt;Single Responsibility Principle&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A class belongs to one main role, expressed through its class role.&lt;br&gt;
Its methods should then remain coherent with that role.&lt;/p&gt;

&lt;p&gt;This does not mean a class must have only one method.&lt;/p&gt;

&lt;p&gt;It means that its methods should serve the same overarching responsibility.&lt;/p&gt;

&lt;p&gt;For example, an &lt;code&gt;agent&lt;/code&gt; may have several methods, as long as those methods serve the same conceptual role.&lt;/p&gt;

&lt;p&gt;A &lt;code&gt;worker&lt;/code&gt; may have several methods, as long as those methods remain focused on technical execution.&lt;/p&gt;

&lt;p&gt;Clprolf interfaces can also target these roles.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ClAgent&lt;/span&gt;
&lt;span class="nd"&gt;@ClFamily&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;PaymentService&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ClWorker&lt;/span&gt;
&lt;span class="nd"&gt;@Family&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;PaymentRepository&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This allows family and trait interfaces to match the intended role of the classes that implement them.&lt;/p&gt;

&lt;p&gt;As a result, developers can define both:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;what kind of object a class is;&lt;/li&gt;
&lt;li&gt;what kind of work it is expected to perform.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All while staying compatible with established object-oriented and SOLID principles.&lt;/p&gt;




&lt;h2&gt;
  
  
  6. How does this relate to DDD or Clean Architecture?
&lt;/h2&gt;

&lt;p&gt;Clprolf does not replace Domain-Driven Design or Clean Architecture.&lt;/p&gt;

&lt;p&gt;It works alongside them.&lt;/p&gt;

&lt;p&gt;DDD focuses on modeling the business domain, defining concepts, language, and boundaries.&lt;/p&gt;

&lt;p&gt;Clean Architecture focuses on separating domain logic from technical concerns through layers and dependency rules.&lt;/p&gt;

&lt;p&gt;Clprolf works at a more local level:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It makes the main role of each class explicit.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Clprolf is close to Clean Architecture in spirit, because it also tries to preserve clean boundaries between conceptual logic and technical execution.&lt;/p&gt;

&lt;p&gt;The difference is that Clprolf expresses those boundaries directly in the code through class roles.&lt;/p&gt;

&lt;p&gt;The framework allows to check with ArchUnit the application of the Clprolf annotations.&lt;/p&gt;

&lt;p&gt;So Clprolf does not require developers to rely only on discipline and convention.&lt;/p&gt;

&lt;p&gt;It gives teams a structure that can be read, discussed, and verified.&lt;/p&gt;




&lt;h2&gt;
  
  
  Summary comparison
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Approach&lt;/th&gt;
&lt;th&gt;Main focus&lt;/th&gt;
&lt;th&gt;Boundary enforcement&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;DDD&lt;/td&gt;
&lt;td&gt;Domain modeling, ubiquitous language, bounded contexts&lt;/td&gt;
&lt;td&gt;Mostly conventions and team discipline&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Clean Architecture&lt;/td&gt;
&lt;td&gt;Separation of domain and technical concerns&lt;/td&gt;
&lt;td&gt;Guidelines, layers, dependency rules&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Clprolf framework&lt;/td&gt;
&lt;td&gt;Class roles: explicit class roles such as &lt;code&gt;agent&lt;/code&gt; and &lt;code&gt;worker&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Annotations and architecture tests&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  7. Examples
&lt;/h2&gt;

&lt;p&gt;Below are simple examples using the Clprolf Java framework.&lt;/p&gt;

&lt;p&gt;They show how class roles integrate naturally into everyday Java classes.&lt;/p&gt;




&lt;h3&gt;
  
  
  Example 1 — A service using a repository
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ClAgent&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrderService&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;OrderRepository&lt;/span&gt; &lt;span class="n"&gt;repository&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;OrderRepository&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;validateAndStore&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;orderId&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Application/domain logic&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;orderId&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;orderId&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isBlank&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;IllegalArgumentException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Invalid order id"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// Technical operation delegated to a worker&lt;/span&gt;
        &lt;span class="n"&gt;repository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;save&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;orderId&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;OrderService&lt;/code&gt; carries application logic and delegates technical persistence to a worker.&lt;/p&gt;




&lt;h3&gt;
  
  
  Example 2 — A repository
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ClWorker&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrderRepository&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;orderId&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Technical persistence code&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Saving order "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;orderId&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;OrderRepository&lt;/code&gt; performs technical work.&lt;/p&gt;

&lt;p&gt;It does not decide whether the order is valid.&lt;br&gt;
It simply saves what it is asked to save.&lt;/p&gt;




&lt;h3&gt;
  
  
  Example 3 — Forbidden inheritance
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ClWorker&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;WrongRepository&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;OrderService&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Not coherent:&lt;/span&gt;
    &lt;span class="c1"&gt;// a technical worker should not inherit from an agent service.&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Clprolf prevents, or at least highlights, this kind of cross-role inheritance.&lt;/p&gt;

&lt;p&gt;A technical class should not extend a conceptual service.&lt;/p&gt;

&lt;p&gt;Composition should be used instead.&lt;/p&gt;




&lt;h3&gt;
  
  
  Example 4 — A simple domain agent
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ClAgent&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Animal&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;eat&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;food&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"The animal eats "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;food&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"The animal sleeps"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Animal&lt;/code&gt; is an agent because it represents a conceptual object.&lt;/p&gt;

&lt;p&gt;It can have several methods because they remain coherent with the same domain.&lt;/p&gt;




&lt;h3&gt;
  
  
  Example 5 — A checkout service
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ClAgent&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CheckoutService&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;OrderRepository&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;OrderRepository&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;PaymentRepository&lt;/span&gt; &lt;span class="n"&gt;payments&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;PaymentRepository&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;checkout&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;orderId&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;orderId&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;orderId&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isBlank&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;IllegalArgumentException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Invalid order id"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;orders&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;save&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;orderId&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;payments&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;process&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;orderId&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ClWorker&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PaymentRepository&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;process&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;orderId&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Technical payment operation&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Processing payment for order "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;orderId&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The checkout service coordinates the application action.&lt;/p&gt;

&lt;p&gt;The repositories perform technical operations.&lt;/p&gt;




&lt;h2&gt;
  
  
  8. What these examples demonstrate
&lt;/h2&gt;

&lt;p&gt;These examples show that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;you keep your usual components: services, repositories, controllers, entities, launchers;&lt;/li&gt;
&lt;li&gt;Clprolf framework adds a clear role through &lt;code&gt;@ClAgent&lt;/code&gt; or &lt;code&gt;@ClWorker&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;agents may use workers through composition;&lt;/li&gt;
&lt;li&gt;workers should not absorb domain decisions;&lt;/li&gt;
&lt;li&gt;inheritance stays coherent;&lt;/li&gt;
&lt;li&gt;class roles become easier to read and maintain.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Clprolf does not make architecture heavier.&lt;/p&gt;

&lt;p&gt;It makes architectural intent visible.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final line
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Class roles are one part of Clprolf framework: they give objects a clear type of work, support clean separation between conceptual and technical responsibilities, remain compatible with SOLID, and can be targeted by Clprolf interfaces.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>programming</category>
      <category>oop</category>
      <category>designpatterns</category>
      <category>architecture</category>
    </item>
    <item>
      <title>“One Reason to Change” — The SRP in Clprolf Framework</title>
      <dc:creator>Charles Koffler</dc:creator>
      <pubDate>Thu, 13 Nov 2025 15:26:48 +0000</pubDate>
      <link>https://dev.to/charles_koffler_bcabc582b/one-reason-to-change-the-forgotten-logic-behind-the-srp-and-how-clprolf-completes-it-1n5o</link>
      <guid>https://dev.to/charles_koffler_bcabc582b/one-reason-to-change-the-forgotten-logic-behind-the-srp-and-how-clprolf-completes-it-1n5o</guid>
      <description>&lt;h2&gt;
  
  
  1. Trying to precise SRP
&lt;/h2&gt;

&lt;p&gt;The &lt;em&gt;Single Responsibility Principle&lt;/em&gt; (SRP) is quoted everywhere.&lt;/p&gt;

&lt;p&gt;Its famous sentence —&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;“A class should have only one reason to change.”&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;— is powerful, but also ambiguous.&lt;/p&gt;

&lt;p&gt;What is a &lt;em&gt;reason&lt;/em&gt;?&lt;br&gt;
Whose responsibility are we talking about?&lt;br&gt;
And where does that responsibility come from?&lt;/p&gt;

&lt;p&gt;The SRP was never false.&lt;br&gt;
It simply stopped before naming the source of responsibility.&lt;/p&gt;

&lt;p&gt;That is where &lt;strong&gt;Clprolf&lt;/strong&gt; steps in: not to oppose the SRP, but to complete its logic.&lt;/p&gt;


&lt;h2&gt;
  
  
  2. What the SRP really implies
&lt;/h2&gt;

&lt;p&gt;If all methods of a class should change for the same reason, then they must all participate in the same coherent work.&lt;/p&gt;

&lt;p&gt;That leads to two important consequences:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Technical and conceptual responsibilities must not be mixed randomly.&lt;/strong&gt;&lt;br&gt;
A database driver change should not affect business rules.&lt;br&gt;
A business rule change should not force a refactoring of low-level technical code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Each class must have one main meaning.&lt;/strong&gt;&lt;br&gt;
This meaning unites its methods, gives the class its identity, and defines its natural scope.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In other words, respecting the SRP means respecting both:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;separation of concerns&lt;/strong&gt;&lt;br&gt;
and&lt;br&gt;
&lt;strong&gt;unity of meaning&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A class is not coherent because it has few methods.&lt;br&gt;
It is coherent because its methods serve the same main responsibility.&lt;/p&gt;


&lt;h2&gt;
  
  
  3. Responsibility belongs to the class, not to isolated methods
&lt;/h2&gt;

&lt;p&gt;Responsibility does not live in methods individually.&lt;/p&gt;

&lt;p&gt;Each method performs a specific action, but the class itself carries the overarching responsibility.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;Doctor&lt;/strong&gt; class has one main responsibility: caring for the health of patients.&lt;/p&gt;

&lt;p&gt;Its methods may be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;takeBloodPressure&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;prescribeTreatment&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;analyzeResults&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These methods do different things, but they all serve the same responsibility.&lt;/p&gt;

&lt;p&gt;They are not separate responsibilities.&lt;br&gt;
They are different expressions of one coherent duty.&lt;/p&gt;

&lt;p&gt;Methods &lt;strong&gt;express&lt;/strong&gt; the responsibility.&lt;br&gt;
They do not define it by themselves.&lt;/p&gt;

&lt;p&gt;Confusing method-level actions with class-level responsibility is what leads to fragmentation, over-engineering, and endless SRP debates.&lt;/p&gt;


&lt;h2&gt;
  
  
  4. "SRP does not mean “one method per class”
&lt;/h2&gt;

&lt;p&gt;A common misunderstanding says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“A class should do only one thing, so it should have only one method.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is not SRP.&lt;br&gt;
It is a reduction of SRP.&lt;/p&gt;

&lt;p&gt;An object is defined by a set of related operations belonging to the same conceptual domain.&lt;/p&gt;

&lt;p&gt;A class may have many methods, and often should have many methods, as long as they all serve the same main meaning.&lt;/p&gt;

&lt;p&gt;SRP is violated when a class mixes unrelated domains, not when it contains several methods belonging to the same one.&lt;/p&gt;

&lt;p&gt;This confusion comes from treating “responsibility” as an isolated action, instead of understanding it as:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;a conceptual duty flowing from what the class is meant to represent.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  5. The chain of meaning: Change → Responsibility → Nature
&lt;/h2&gt;

&lt;p&gt;A class does not change for arbitrary reasons.&lt;/p&gt;

&lt;p&gt;It changes because its responsibility evolves.&lt;/p&gt;

&lt;p&gt;And that responsibility exists because the class has a main conceptual nature: what the class is meant to represent in the program.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;The way a doctor takes blood pressure might change:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a new device,&lt;/li&gt;
&lt;li&gt;a new procedure,&lt;/li&gt;
&lt;li&gt;a new medical standard.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But the reason for the change remains the same:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;protecting and improving the patient’s health.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The technical details may evolve, but the responsibility remains coherent because it is rooted in the same conceptual nature.&lt;/p&gt;

&lt;p&gt;So when we say:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“A class should have only one reason to change,”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;we are really saying:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Change belongs to responsibility, and responsibility belongs to nature.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When this hierarchy is respected, evolution no longer breaks the class.&lt;br&gt;
It confirms its role.&lt;/p&gt;


&lt;h2&gt;
  
  
  6. Where Clprolf framework could bring clarity
&lt;/h2&gt;

&lt;p&gt;This is exactly where &lt;strong&gt;Clprolf&lt;/strong&gt; goes beyond discussion.&lt;/p&gt;

&lt;p&gt;Clprolf does not merely interpret the SRP.&lt;br&gt;
It makes its intention visible.&lt;/p&gt;

&lt;p&gt;In Clprolf:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;every class declares its main role;&lt;/li&gt;
&lt;li&gt;that role reveals the class’s conceptual nature;&lt;/li&gt;
&lt;li&gt;its responsibility flows from that domain;&lt;/li&gt;
&lt;li&gt;its methods are expected to remain coherent with that responsibility.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A class is no longer just a block of code.&lt;br&gt;
It declares what kind of object it is.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ClAgent&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Doctor&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Doctor is an agent: a conceptual object carrying domain meaning.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ClWorker&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrderDAO&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;OrderDAO is a worker: a technical performer serving execution.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Clprolf framework does not make bad design impossible.&lt;br&gt;
But it makes incoherence visible.&lt;/p&gt;

&lt;p&gt;The class has declared its role, so any contradiction becomes easier to see, discuss, test, or even detect automatically.&lt;/p&gt;


&lt;h2&gt;
  
  
  7. From moral advice to structural clarity
&lt;/h2&gt;

&lt;p&gt;SRP often remains a moral principle:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Try to keep your classes focused.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;With Clprolf framework, the principle becomes structural:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ClAgent&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrderProcessor&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ClWorker&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrderRepository&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code itself starts to say:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This class carries conceptual logic.&lt;br&gt;
This class performs technical work.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That does not remove judgment.&lt;br&gt;
But it gives judgment a concrete basis.&lt;/p&gt;

&lt;p&gt;Instead of asking vaguely:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Does this class respect SRP?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;we can ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Does this class remain coherent with its declared role?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is much easier to reason about.&lt;/p&gt;


&lt;h2&gt;
  
  
  8. Agents, workers, and practical flexibility
&lt;/h2&gt;

&lt;p&gt;Clprolf should not be understood as a rigid purity system.&lt;/p&gt;

&lt;p&gt;An &lt;strong&gt;agent&lt;/strong&gt; is a class whose main responsibility is conceptual, domain-oriented, or meaningful in the application.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;worker&lt;/strong&gt; is a class whose main responsibility is technical execution: launching, displaying, storing, rendering, sending, reading, writing, or interacting with the system.&lt;/p&gt;

&lt;p&gt;An agent may contain a small amount of technical code if it remains secondary and improves readability.&lt;/p&gt;

&lt;p&gt;But heavy technical work should usually be delegated to workers.&lt;/p&gt;

&lt;p&gt;Likewise, a worker should avoid making domain decisions.&lt;br&gt;
It may manipulate data, perform I/O, render output, or call technical APIs, but it should not become the brain of the application.&lt;/p&gt;

&lt;p&gt;The rule is not:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Agents must be perfectly pure.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The rule is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The main role must stay clear.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is what makes Clprolf practical.&lt;/p&gt;


&lt;h2&gt;
  
  
  9. Method-level SRP: the real issue
&lt;/h2&gt;

&lt;p&gt;SRP also has a meaningful application at the method level, but not in the simplistic way people often describe.&lt;/p&gt;

&lt;p&gt;The key rule is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;A business method should not be polluted with heavy technical code.&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;A technical method should not contain domain decisions.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When a method mixes domain logic with infrastructure logic, it immediately gains two independent reasons to change:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the domain rules may evolve;&lt;/li&gt;
&lt;li&gt;the technical mechanism may evolve.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is a real SRP violation.&lt;/p&gt;

&lt;p&gt;Example of a problematic method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;processOrder&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Order&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;total&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;IllegalArgumentException&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nc"&gt;Connection&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;DriverManager&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getConnection&lt;/span&gt;&lt;span class="o"&gt;(...);&lt;/span&gt;
    &lt;span class="nc"&gt;PreparedStatement&lt;/span&gt; &lt;span class="n"&gt;statement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;prepareStatement&lt;/span&gt;&lt;span class="o"&gt;(...);&lt;/span&gt;
    &lt;span class="n"&gt;statement&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;executeUpdate&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This method mixes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;order validation,&lt;/li&gt;
&lt;li&gt;database connection,&lt;/li&gt;
&lt;li&gt;SQL execution.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The method has more than one reason to change.&lt;/p&gt;

&lt;p&gt;In Clprolf framework, the preferred structure would be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ClAgent&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrderProcessor&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;OrderRepository&lt;/span&gt; &lt;span class="n"&gt;repository&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;process&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Order&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;total&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;IllegalArgumentException&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;repository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;save&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ClWorker&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrderRepository&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Order&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// technical persistence code&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the roles are clear:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the agent decides;&lt;/li&gt;
&lt;li&gt;the worker executes.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  10. What does not violate SRP
&lt;/h2&gt;

&lt;p&gt;Many things often called “SRP violations” are not necessarily violations.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a method that is long;&lt;/li&gt;
&lt;li&gt;a method with several internal steps;&lt;/li&gt;
&lt;li&gt;a method that contains an inline algorithm;&lt;/li&gt;
&lt;li&gt;a class with several related methods;&lt;/li&gt;
&lt;li&gt;a class that performs several actions within the same coherent domain.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are not automatically SRP problems.&lt;/p&gt;

&lt;p&gt;Algorithmic steps do not create multiple responsibilities by themselves.&lt;/p&gt;

&lt;p&gt;A method can have several steps and still express one intention.&lt;/p&gt;

&lt;p&gt;A class can have several methods and still serve one responsibility.&lt;/p&gt;

&lt;p&gt;SRP is about &lt;strong&gt;cross-domain evolution&lt;/strong&gt;, not micro-method minimalism.&lt;/p&gt;

&lt;p&gt;The question is not:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Is there more than one line?”&lt;br&gt;
“Is there more than one method?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The question is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Are multiple unrelated reasons to change being mixed together?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  11. Clprolf framework and inheritance coherence
&lt;/h2&gt;

&lt;p&gt;SRP is also related to inheritance.&lt;/p&gt;

&lt;p&gt;Inheritance is not just code reuse.&lt;br&gt;
It expresses conceptual continuity.&lt;/p&gt;

&lt;p&gt;If a class inherits from another class, it should remain in the same coherent domain.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ClAgent&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Animal&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ClAgent&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Dog&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Animal&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is coherent: Dog remains in the same conceptual family as Animal.&lt;/p&gt;

&lt;p&gt;But this is not coherent:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ClWorker&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DatabaseConnection&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ClAgent&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Dog&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;DatabaseConnection&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This mixes unrelated meanings.&lt;/p&gt;

&lt;p&gt;The issue is not inheritance itself.&lt;br&gt;
The issue is incoherent inheritance.&lt;/p&gt;

&lt;p&gt;Clprolf makes this visible by giving each class a declared role.&lt;/p&gt;

&lt;p&gt;If the inheritance crosses incompatible domains, the contradiction becomes obvious.&lt;/p&gt;

&lt;p&gt;And if the developer really needs to force the relation, Clprolf can allow explicit forcing annotations — but the exception remains visible.&lt;/p&gt;




&lt;h2&gt;
  
  
  12. From SRP to Clprolf
&lt;/h2&gt;

&lt;p&gt;The SRP says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A class should have only one reason to change.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Clprolf framework asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Where does that reason come from?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And the answer is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It comes from the class’s responsibility.&lt;br&gt;
And that responsibility comes from its main nature, revealed by its declared role.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So Clprolf completes the SRP like this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A class should have only one reason to change&lt;br&gt;
because it has one main responsibility,&lt;br&gt;
rooted in one main conceptual nature.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This does not replace the SRP.&lt;/p&gt;

&lt;p&gt;It explains it.&lt;/p&gt;

&lt;p&gt;It gives it structure.&lt;/p&gt;

&lt;p&gt;It turns a slogan into something readable in code.&lt;/p&gt;




&lt;h2&gt;
  
  
  13. Summary table
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Concept&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Domain&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;What the class conceptually represents&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Doctor&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Responsibility&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;What the class is responsible for as a whole&lt;/td&gt;
&lt;td&gt;Caring for patients&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Methods&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Concrete actions expressing the responsibility&lt;/td&gt;
&lt;td&gt;&lt;code&gt;takeBloodPressure()&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Agent&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Class with a conceptual/domain role&lt;/td&gt;
&lt;td&gt;&lt;code&gt;OrderProcessor&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Worker&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Class with a technical execution role&lt;/td&gt;
&lt;td&gt;&lt;code&gt;OrderRepository&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;When nature, responsibility, methods, and role stay aligned, change becomes more predictable.&lt;/p&gt;

&lt;p&gt;The class can evolve without losing its identity.&lt;/p&gt;




&lt;h2&gt;
  
  
  14. Final note — Change as a sign of duty
&lt;/h2&gt;

&lt;p&gt;Change is not always a sign of instability.&lt;/p&gt;

&lt;p&gt;Sometimes, change is the proof that a class is still faithful to its duty.&lt;/p&gt;

&lt;p&gt;A class evolves because the responsibility it carries evolves.&lt;/p&gt;

&lt;p&gt;If the class has a clear nature, that evolution remains coherent.&lt;/p&gt;

&lt;p&gt;If the class mixes unrelated responsibilities, every change becomes dangerous.&lt;/p&gt;

&lt;p&gt;That is what the SRP was trying to say.&lt;/p&gt;

&lt;p&gt;Clprolf framework helps to make it visible.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The SRP told us:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“A class should have only one reason to change.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Clprolf tries to complete the sentence:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;A class should have only one reason to change because its responsibility flows from one main nature, made visible by its declared role.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In the end, what the SRP truly asks for is simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;no cross-domain mixing;&lt;/li&gt;
&lt;li&gt;no incoherent inheritance;&lt;/li&gt;
&lt;li&gt;no silent contradiction between what a class is and what it does;&lt;/li&gt;
&lt;li&gt;one clear meaning given to each class.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is the clarity Clprolf brings.&lt;/p&gt;

</description>
      <category>designpatterns</category>
      <category>java</category>
      <category>development</category>
    </item>
    <item>
      <title>🗂️ Clprolf Framework Directory Explorer</title>
      <dc:creator>Charles Koffler</dc:creator>
      <pubDate>Sun, 19 Oct 2025 21:24:37 +0000</pubDate>
      <link>https://dev.to/charles_koffler_bcabc582b/clprolf-directory-explorer-when-breadth-first-becomes-intuitive-5a0f</link>
      <guid>https://dev.to/charles_koffler_bcabc582b/clprolf-directory-explorer-when-breadth-first-becomes-intuitive-5a0f</guid>
      <description>&lt;p&gt;Everyone knows that exploring directories can quickly turn into a messy technical exercise:&lt;br&gt;
loops, recursion, stacks, file filters… and code that loses all readability.&lt;/p&gt;

&lt;p&gt;With &lt;strong&gt;Clprolf framework&lt;/strong&gt;, clarity is built-in.&lt;br&gt;
Let’s see how a simple &lt;em&gt;directory explorer&lt;/em&gt; can become a beautifully structured program.&lt;/p&gt;


&lt;h3&gt;
  
  
  💡 1. The Concept
&lt;/h3&gt;

&lt;p&gt;We want to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;explore all subdirectories of a given folder,&lt;/li&gt;
&lt;li&gt;in &lt;strong&gt;breadth-first&lt;/strong&gt; order (level by level),&lt;/li&gt;
&lt;li&gt;assign each directory a hierarchical ID,&lt;/li&gt;
&lt;li&gt;and display the results cleanly.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of mixing logic, display, and data handling,&lt;br&gt;
Clprolf invites us to split them into &lt;strong&gt;roles&lt;/strong&gt;.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Component&lt;/th&gt;
&lt;th&gt;Declension&lt;/th&gt;
&lt;th&gt;Responsibility&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Launcher&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;@ClWorker&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Starts the exploration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;DirectoryExplorerImpl&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;@ClAgent&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Performs the exploration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;DirectoryExplorerWorkerImpl&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;@ClWorker&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Displays results&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Directory&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;@ClAgent&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Represents one directory node&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;DirectoryExplorer&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;@ClAgent @ClFamily&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The family of the agent&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;DirectoryExplorerWorker&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;@ClWorker @ClFamily&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The family of the worker for the agent&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;


&lt;h3&gt;
  
  
  ⚙️ 2. The Launcher
&lt;/h3&gt;

&lt;p&gt;The entry point is as simple as it looks.&lt;br&gt;
It prepares the environment and delegates the job to the proper agent.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ClWorker&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Launcher&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;Path&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Paths&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getProperty&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"user.home"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toRealPath&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;LinkOption&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;NOFOLLOW_LINKS&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;ignored&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{}&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(!&lt;/span&gt;&lt;span class="nc"&gt;Files&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isDirectory&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;err&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Not a directory: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;exit&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="nc"&gt;DirectoryExplorer&lt;/span&gt; &lt;span class="n"&gt;explorer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;DirectoryExplorerImpl&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;explorer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;breadthFirstFolders&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It’s clear who does what:&lt;br&gt;
this worker doesn’t explore — it simply &lt;em&gt;launches the agent&lt;/em&gt;.&lt;/p&gt;


&lt;h3&gt;
  
  
  🧭 3. The Agent — &lt;code&gt;DirectoryExplorerImpl&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Here lies the real exploration logic.&lt;br&gt;
The agent collaborates with a worker, manipulates a model, and manages a queue.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ClAgent&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DirectoryExplorerImpl&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;DirectoryExplorer&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;DirectoryExplorerWorker&lt;/span&gt; &lt;span class="n"&gt;worker&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;DirectoryExplorerImpl&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;worker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;DirectoryExplorerWorkerImpl&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;breadthFirstFolders&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Path&lt;/span&gt; &lt;span class="n"&gt;directoryPath&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;directoryPath&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;directoryPath&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;normalize&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;toAbsolutePath&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

        &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Directory&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;foldersList&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;
        &lt;span class="nc"&gt;Queue&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Directory&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;directoryToExplore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;LinkedList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;

        &lt;span class="n"&gt;directoryToExplore&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Directory&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;directoryPath&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;)));&lt;/span&gt;

        &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="o"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;directoryToExplore&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isEmpty&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;Directory&lt;/span&gt; &lt;span class="n"&gt;current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;directoryToExplore&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;poll&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
            &lt;span class="n"&gt;foldersList&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;current&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

            &lt;span class="nc"&gt;File&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;files&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;current&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getPath&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;toFile&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;listFiles&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;files&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
                &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;File&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;files&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isDirectory&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                        &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;newId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;current&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getHierarchicalId&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
                        &lt;span class="n"&gt;newId&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                        &lt;span class="n"&gt;directoryToExplore&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Directory&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toPath&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;normalize&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;toAbsolutePath&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;newId&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
                        &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="o"&gt;++;&lt;/span&gt;
                    &lt;span class="o"&gt;}&lt;/span&gt;
                &lt;span class="o"&gt;}&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;worker&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;displayResult&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;foldersList&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every part is crystal clear:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The queue defines a &lt;strong&gt;breadth-first traversal&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Each directory receives its own &lt;strong&gt;hierarchical ID&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;worker&lt;/strong&gt; takes care of presentation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No recursion, no confusion.&lt;/p&gt;




&lt;h3&gt;
  
  
  👷 4. The Worker
&lt;/h3&gt;

&lt;p&gt;Responsible for showing the result, not for computing it.&lt;br&gt;
Again, we separate &lt;em&gt;doing&lt;/em&gt; from &lt;em&gt;showing&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ClWorker&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DirectoryExplorerWorkerImpl&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;DirectoryExplorerWorker&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;displayResult&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Directory&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;foldersList&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Directory&lt;/span&gt; &lt;span class="n"&gt;dir&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;foldersList&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;display&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;formatId&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dir&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getHierarchicalId&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" : "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;dir&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getPath&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
            &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;display&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;formatId&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"("&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;join&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;", "&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;String:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;valueOf&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;toArray&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]::&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;")"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Simple, explicit, human-readable.&lt;/p&gt;




&lt;h3&gt;
  
  
  📦 5. The Model
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ClAgent&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Directory&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;Path&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;hierarchicalId&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Directory&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Path&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;hierarchicalId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Path&lt;/span&gt; &lt;span class="nf"&gt;getPath&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;getHierarchicalId&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;hierarchicalId&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  🤝 6. The interfaces
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ClAgent&lt;/span&gt;
&lt;span class="nd"&gt;@ClFamily&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;DirectoryExplorer&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;breadthFirstFolders&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Path&lt;/span&gt; &lt;span class="n"&gt;directoryPath&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;@ClWorker&lt;/span&gt;
&lt;span class="nd"&gt;@ClFamily&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;DirectoryExplorerWorker&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;displayResult&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Directory&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;foldersList&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  🪶 7. Why it matters
&lt;/h3&gt;

&lt;p&gt;Breadth-first exploration is only the example.&lt;br&gt;
What matters here is &lt;strong&gt;how naturally the architecture expresses itself&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The launcher launches.&lt;/li&gt;
&lt;li&gt;The agent explores.&lt;/li&gt;
&lt;li&gt;The worker displays.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  ✨ Final Thoughts
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;In classical Java, you might have written a single class doing everything.&lt;/p&gt;

&lt;p&gt;In Clprolf, each role finds its natural place.&lt;br&gt;
The result is simple, explicit, and readable — even for someone who never wrote Java before.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Clprolf brings &lt;strong&gt;clarity back into architecture&lt;/strong&gt;.&lt;/p&gt;




</description>
      <category>programming</category>
      <category>architecture</category>
      <category>java</category>
    </item>
  </channel>
</rss>
