<?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; [ClAgent] (UI Component)
            ├── RelayCommand.cs     --&amp;gt; [ClAgent] (Intention Driver)
            └── IClNotifyPropertyChanged.cs --&amp;gt; [ClTrait] (Structural Behavior)

&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;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;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="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="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 

            &lt;span class="c1"&gt;// Validate that Clprolf parents are strictly other Traits&lt;/span&gt;
            &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;allParentsAreTraitsOrNonClprolf&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="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="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="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;allParentsAreTraitsOrNonClprolf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                &lt;span class="s"&gt;"Verifying semantic inheritance rules."&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;
  
  
  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="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="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 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) Class Types
&lt;/h1&gt;

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




&lt;h2&gt;
  
  
  II.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;.&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;
  
  
  II.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;
  
  
  II.3) &lt;code&gt;ClDraft&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;An object without a defined role.&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;
  
  
  II.4) 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;h2&gt;
  
  
  II.5) An "opinionated" framework for the agent/worker choice
&lt;/h2&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;, 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 Connection class:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;an &lt;code&gt;agent&lt;/code&gt; to represent the connection,&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 Connection class as a &lt;code&gt;ClAgent&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         │            │       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;h3&gt;
  
  
  II.5.2) The optional &lt;code&gt;ClSystem&lt;/code&gt; role
&lt;/h3&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;/p&gt;


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

&lt;blockquote&gt;
&lt;p&gt;A class only inherits from another class within the same domain.&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;
  
  
  IV) 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;
  
  
  V) 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;
  
  
  V.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;
  
  
  V.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;
  
  
  V.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;
  
  
  V.4) &lt;code&gt;ClFree&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;A generic interface without a specific role.&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;
  
  
  V.5) Using Interfaces
&lt;/h2&gt;

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

&lt;p&gt;They are intended to be implemented by one or more future Clprolf classes.&lt;br&gt;
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.&lt;br&gt;
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;
This family interface can itself inherit from multiple &lt;code&gt;Family&lt;/code&gt; or &lt;code&gt;Trait&lt;/code&gt; interfaces.&lt;br&gt;
Thus, the interfaces that would have been implemented directly by the class are grouped together at the level of its main &lt;code&gt;Family&lt;/code&gt;.&lt;br&gt;
Clprolf therefore preserves the richness of multiple interface inheritance, while maintaining a simple and cohesive structure for concrete classes.&lt;/p&gt;
&lt;h2&gt;
  
  
  Note: In non-strict mode, it is possible for a class to implement multiple &lt;code&gt;ClFamily&lt;/code&gt; interfaces, to stay closer to standard Java and C# practices.
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;Trait&lt;/code&gt; interfaces express a common functionality across multiple &lt;code&gt;Family&lt;/code&gt; interfaces.&lt;/p&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.&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;/p&gt;

&lt;p&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;p&gt;Forcing interface inheritance remains possible 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).&lt;/p&gt;

&lt;p&gt;Note: In non-strict mode, direct implementation of a &lt;code&gt;Trait&lt;/code&gt; by a class is allowed.&lt;/p&gt;




&lt;h2&gt;
  
  
  V.6) 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;
  
  
  VI) 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               │
│   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 enforces the Single Responsibility Principle (SRP). Indeed, each class possesses its own conceptual or business domain, which is strictly preserved during inheritance.&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 facilitates 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, the Liskov Substitution Principle is naturally upheld. &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 advises 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.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;D&lt;/strong&gt; — Dependency Inversion / 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.&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;Agent
Worker
Draft
&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;Family
Trait
Free
&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;A structured approach to object-oriented programming.&lt;/strong&gt;&lt;br&gt;
Roles and responsibilities become explicit.&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;p&gt;Its goal is not to replace classical OOP, but to make certain important distinctions explicit:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;business or domain responsibilities versus technical/support responsibilities,&lt;/li&gt;
&lt;li&gt;coherent inheritance versus composition,&lt;/li&gt;
&lt;li&gt;the primary responsibility of a class.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It helps adhere to the well-known SOLID principles.&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.&lt;/p&gt;

&lt;p&gt;A class may start with a well-defined purpose, but gradually accumulate additional concerns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;business rules,&lt;/li&gt;
&lt;li&gt;technical implementation details,&lt;/li&gt;
&lt;li&gt;infrastructure logic,&lt;/li&gt;
&lt;li&gt;unrelated responsibilities.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As systems grow, architectural intent becomes harder to understand and maintain.&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.&lt;/p&gt;

&lt;p&gt;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;p&gt;To support this idea, Clprolf introduces explicit class roles and structural guidelines.&lt;/p&gt;




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

&lt;h3&gt;
  
  
  &lt;code&gt;agent&lt;/code&gt;
&lt;/h3&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 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.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note: entities and DTOs are typically classified as agents, since they represent domain data.&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 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="nc"&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;worker&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Represents a technical class.&lt;/p&gt;

&lt;p&gt;A technical class is primarily intended to support agent classes rather than be organized around a class domain.&lt;br&gt;
Workers provide technical support and infrastructure services. They may coordinate or use low-level agent classes 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;br&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;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;/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;@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;// database access&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;draft&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;An object without a defined role.&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;
  
  
  🧠 Inheritance
&lt;/h2&gt;

&lt;p&gt;Clprolf encourages inheritance only 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="nd"&gt;@Agent&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;@Agent&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;When domains do not match, composition is generally preferred.&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;AppLauncher&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;AppLauncher&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;In this case, composition would usually provide a clearer design.&lt;/p&gt;




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

&lt;p&gt;Clprolf extends the same philosophy to interfaces.&lt;/p&gt;

&lt;p&gt;Three interface categories are available:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;family&lt;/code&gt; — an abstract family of related implementations,&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;trait&lt;/code&gt; — a shared capability across multiple families,&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;free&lt;/code&gt; — a flexible interface.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Family and trait interfaces also declare a target role:&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;This allows abstractions to remain consistent with the roles of their implementations.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚖️ What Clprolf Provides
&lt;/h2&gt;

&lt;p&gt;By making roles explicit, Clprolf helps developers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;understand class responsibilities more quickly,&lt;/li&gt;
&lt;li&gt;maintain clearer architectural boundaries,&lt;/li&gt;
&lt;li&gt;build more coherent inheritance hierarchies,&lt;/li&gt;
&lt;li&gt;reduce architectural drift over time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The framework acts primarily as a structural guide rather than a rigid architectural framework.&lt;/p&gt;




&lt;h2&gt;
  
  
  🎯 When to Use Clprolf
&lt;/h2&gt;

&lt;p&gt;Clprolf is well suited for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;teams that want a lightweight structural guide for object-oriented design without adopting a heavy architectural framework,&lt;/li&gt;
&lt;li&gt;educational contexts focused on architectural clarity,&lt;/li&gt;
&lt;li&gt;complex systems,&lt;/li&gt;
&lt;li&gt;simulation and MAS-like applications,&lt;/li&gt;
&lt;li&gt;long-lived codebases where explicit responsibilities and coherent inheritance are important.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ⚖️ Philosophy
&lt;/h2&gt;

&lt;p&gt;Clprolf intentionally introduces light structural constraints.&lt;/p&gt;

&lt;p&gt;These constraints are not designed to restrict creativity, but to make architectural decisions explicit.&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;h2&gt;
  
  
  Foundational Principles of Clprolf
&lt;/h2&gt;

&lt;p&gt;Clprolf is based on two core principles:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A class is either organized around a well-defined class domain or exists to provide technical support to other classes.&lt;/li&gt;
&lt;li&gt;Inheritance must preserve the class domain; otherwise, composition should be used.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These principles define how Clprolf structures classes and relationships.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Is a Class Domain?
&lt;/h2&gt;

&lt;p&gt;A class domain is the central subject around which a class is organized.&lt;/p&gt;

&lt;p&gt;It defines what the class fundamentally represents and what it is responsible for.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Animal&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;Connection&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Parser&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;JsonSerializer&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Scheduler&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Controller&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PdfGenerator&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;RandomGenerator&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PaymentService&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;InventoryService&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each of these classes represents a coherent subject.&lt;/p&gt;

&lt;p&gt;A class domain does not need to be business-related.&lt;/p&gt;

&lt;p&gt;It may represent:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a business concept,&lt;/li&gt;
&lt;li&gt;a system concept,&lt;/li&gt;
&lt;li&gt;a technical concept,&lt;/li&gt;
&lt;li&gt;a scientific concept,&lt;/li&gt;
&lt;li&gt;a simulation entity,&lt;/li&gt;
&lt;li&gt;a service,&lt;/li&gt;
&lt;li&gt;or any other coherent subject.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Domain-Oriented Classes
&lt;/h2&gt;

&lt;p&gt;A domain-oriented class represents something.&lt;/p&gt;

&lt;p&gt;Its identity comes from the domain it models rather than from the technical services it performs.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Animal
File
Connection
Parser
JsonSerializer
Scheduler
Controller
PdfGenerator
RandomGenerator
PaymentService
InventoryService
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These classes remain meaningful even when considered independently.&lt;/p&gt;

&lt;p&gt;In Clprolf, such classes are typically represented as &lt;code&gt;agent&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Technical Support Classes
&lt;/h2&gt;

&lt;p&gt;Some classes do not primarily represent a domain.&lt;/p&gt;

&lt;p&gt;Instead, they exist to support one or more agents by providing technical capabilities.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;launching agents,&lt;/li&gt;
&lt;li&gt;executing technical procedures,&lt;/li&gt;
&lt;li&gt;displaying information,&lt;/li&gt;
&lt;li&gt;interacting with the operating system,&lt;/li&gt;
&lt;li&gt;accessing platform-specific features,&lt;/li&gt;
&lt;li&gt;providing infrastructure services.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AnimalWorker
ApplicationLauncher
AgentLauncher
ProcessLauncher
SystemExecutor
NativeProcessRunner
OperatingSystemWorker
ControllerWorker
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These classes are primarily defined by the support they provide.&lt;/p&gt;

&lt;p&gt;Their purpose is to help agents perform technical operations.&lt;/p&gt;

&lt;p&gt;In Clprolf, such classes are typically represented as &lt;code&gt;worker&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Agents and Workers
&lt;/h2&gt;

&lt;p&gt;A useful way to understand the distinction is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;agent  → represents a domain
worker → supports a domain
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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;public agent Animal {

    private AnimalWorker worker;

    public void display() {
        worker.display(this);
    }

}
&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;public worker AnimalWorker {

    public void display(Animal animal) {

        // rendering logic
        // platform-specific code
        // UI interaction

    }

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

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;Animal&lt;/code&gt; agent represents the domain.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;AnimalWorker&lt;/code&gt; exists to provide technical support to that domain.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public agent PaymentService {
}
&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;public worker PaymentServiceLauncher {
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The service itself represents a domain.&lt;/p&gt;

&lt;p&gt;The launcher exists only to support its execution.&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 language.&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;agent&lt;/code&gt;),&lt;/li&gt;
&lt;li&gt;technical support classes (&lt;code&gt;worker&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>Getting Started with Clprolf: Structuring Responsibilities in OOP</title>
      <dc:creator>Charles Koffler</dc:creator>
      <pubDate>Fri, 06 Feb 2026 17:35:37 +0000</pubDate>
      <link>https://dev.to/charles_koffler_bcabc582b/getting-started-with-clprolf-structuring-responsibilities-in-oop-5doe</link>
      <guid>https://dev.to/charles_koffler_bcabc582b/getting-started-with-clprolf-structuring-responsibilities-in-oop-5doe</guid>
      <description>&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Clprolf (CLear PROgramming Language and Framework) builds upon classical Object-Oriented Programming.&lt;/p&gt;

&lt;p&gt;To fully benefit from this guide, 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;basic design principles.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Making Responsibilities Explicit
&lt;/h2&gt;

&lt;p&gt;Clprolf is a Java and C# framework designed to make architectural roles explicit.&lt;/p&gt;

&lt;p&gt;In many object-oriented systems, separation of responsibilities relies primarily on conventions and developer discipline.&lt;/p&gt;

&lt;p&gt;As projects evolve, responsibilities may gradually become mixed, making the original architecture harder to understand and maintain.&lt;/p&gt;

&lt;p&gt;Clprolf addresses this by making architectural intent part of the programming model itself.&lt;/p&gt;

&lt;p&gt;Every class explicitly declares its nature.&lt;/p&gt;




&lt;h2&gt;
  
  
  Foundational Principles of Clprolf
&lt;/h2&gt;

&lt;p&gt;Clprolf is based on two core principles:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A class is either technical or organized around a well-defined class domain.&lt;/li&gt;
&lt;li&gt;Inheritance must preserve the class domain; otherwise, composition should be used.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These principles define how Clprolf structures classes and relationships.&lt;/p&gt;




&lt;h3&gt;
  
  
  What Is a Class Domain?
&lt;/h3&gt;

&lt;p&gt;A class domain is the central subject around which a class is organized.&lt;/p&gt;

&lt;p&gt;It represents what the class fundamentally models and what it is primarily responsible for.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;a &lt;code&gt;File&lt;/code&gt; class belongs to a file-management domain,&lt;/li&gt;
&lt;li&gt;a &lt;code&gt;Connection&lt;/code&gt; class belongs to a connection-management domain,&lt;/li&gt;
&lt;li&gt;a &lt;code&gt;RandomGenerator&lt;/code&gt; class belongs to a random-generation domain,&lt;/li&gt;
&lt;li&gt;an &lt;code&gt;OrderProcessor&lt;/code&gt; class belongs to an order-processing domain.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Low-level technical abstractions such as File, Connection, Logger or Parser still possess their own class domain and are therefore typically modeled as agents.&lt;/p&gt;

&lt;p&gt;A technical class is different.&lt;/p&gt;

&lt;p&gt;A technical class is primarily intended to support agent classes rather than be organized around a class domain.&lt;br&gt;
Workers provide technical support and infrastructure services. They may coordinate or use low-level agent classes 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;br&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;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;/ul&gt;


&lt;h2&gt;
  
  
  1️⃣ Declaring a class role
&lt;/h2&gt;

&lt;p&gt;In classical OOP, a class is typically declared as:&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="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In Clprolf, the architectural nature is made 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;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;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;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;Each class declares its role from the beginning.&lt;/p&gt;

&lt;p&gt;The core class roles are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;agent&lt;/code&gt; → domain-oriented responsibility&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;worker&lt;/code&gt; → support/technical responsibility&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;draft&lt;/code&gt; → temporary undefined responsibility&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  2️⃣ Starting Flexible with &lt;code&gt;draft&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Architectural clarity is not always immediate.&lt;/p&gt;

&lt;p&gt;During prototyping or exploration, a class may begin as:&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;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="n"&gt;validate&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;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;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;&lt;code&gt;draft&lt;/code&gt; represents a temporary state.&lt;/p&gt;

&lt;p&gt;The responsibility can be clarified later through refactoring.&lt;/p&gt;




&lt;h2&gt;
  
  
  3️⃣ Making Responsibilities Explicit
&lt;/h2&gt;

&lt;p&gt;After analyzing the class, we identify several distinct responsibilities:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Responsibility&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;Order processing&lt;/td&gt;
&lt;td&gt;Domain&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;Notification delivery&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;The class can then be reorganized:&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;private&lt;/span&gt; &lt;span class="nc"&gt;OrderNotifier&lt;/span&gt; &lt;span class="n"&gt;notifier&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="n"&gt;validate&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;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;notifier&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;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;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;OrderNotifier&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 behavior remains unchanged.&lt;/p&gt;

&lt;p&gt;The architecture becomes explicit.&lt;/p&gt;




&lt;h2&gt;
  
  
  4️⃣ Structural Rules Are Enforced
&lt;/h2&gt;

&lt;p&gt;Clprolf does not merely recommend architectural discipline.&lt;/p&gt;

&lt;p&gt;It can enforce structural coherence.&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 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;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 attempts to inherit from a class of a different nature.&lt;/p&gt;

&lt;p&gt;This is considered as a violation by the ArchUnit checker.&lt;/p&gt;

&lt;p&gt;The equivalent Java code would compile:&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;AnimalImpl&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;Clprolf rejects it as architecturally inconsistent.&lt;/p&gt;




&lt;h2&gt;
  
  
  5️⃣ Structured Interfaces
&lt;/h2&gt;

&lt;p&gt;Clprolf also introduces structured interface categories.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;family&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Represents an abstract family of related implementations.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@ClAgent
@ClFamily
public interface Animal {

    void eat(int quantity);

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;trait&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Represents a capability shared across multiple families.&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;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;
  
  
  &lt;code&gt;free&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Represents a flexible interface without a predefined structural 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="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;p&gt;Unlike traditional interfaces, Clprolf interfaces participate in the structural model of the system.&lt;/p&gt;




&lt;h2&gt;
  
  
  6️⃣ What Clprolf Changes
&lt;/h2&gt;

&lt;p&gt;Clprolf does not change:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;algorithms,&lt;/li&gt;
&lt;li&gt;execution flow,&lt;/li&gt;
&lt;li&gt;runtime behavior.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead, it changes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;role visibility,&lt;/li&gt;
&lt;li&gt;architectural clarity,&lt;/li&gt;
&lt;li&gt;inheritance consistency,&lt;/li&gt;
&lt;li&gt;structural guarantees.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  7️⃣ Philosophy in One Sentence
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Clprolf encodes architectural responsibility at the language level instead of leaving it entirely to convention.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>java</category>
      <category>architecture</category>
      <category>refactoring</category>
      <category>programming</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>A Global Model of How Classes Relate to Each Other in Clprolf framework</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>
  </channel>
</rss>
