Design patterns are a classic way to solve recurring software design problems.
In this article, we’ll revisit the Adapter pattern, but written in Clprolf — a language that makes object-oriented roles and contracts explicit.
Even if you don’t know Clprolf yet, don’t worry:
- the use case is familiar,
 - the solution is the same pattern you already know,
 - and you’ll see how Clprolf makes both sides clearer.
 
🤔 The Problem
Imagine you have an existing class that implements an old interface, but your application now expects the modern version of that interface.
- You cannot change the old class (it’s legacy code, or external).
 - You need a way to reuse it, but expose it through the newer contract.
 
That’s where the Adapter comes in.
✅ The Clprolf Solution
In Clprolf, the rule is simple:
- A concrete agent can contract only one 
version_inh. - So you cannot make the same class both an “old” and a “modern” implementation.
 - Instead, you create a new agent — the Adapter — which contracts the modern version, and internally uses the old one via 
with_compat. 
📝 Example: Enumeration → Iterator
Old Java APIs used Enumeration, but modern code expects Iterator. We want to reuse existing Enumeration implementations without rewriting them.
Clprolf Code
// 1. Old contract (an abstraction)
public version_inh abstraction Enumeration<E> {
    boolean hasMoreElements();
    E nextElement();
}
// 2. Modern contract (an agent)
public version_inh agent Iterator<E> {
    boolean hasNext();
    E next();
}
// 3. Adapter agent: contracts the modern version
public agent EnumToIterAdapter<E> contracts Iterator<E> {
    private with_compat Enumeration<E> enumeration;
    public EnumToIterAdapter(with_compat Enumeration<E> enumeration) {
        this.enumeration = enumeration;
    }
    public boolean hasNext() {
        return enumeration.hasMoreElements();
    }
    public E next() {
        return enumeration.nextElement();
    }
}
🔎 Why this is clear in Clprolf
- 
version_inhmakes it explicit: these are role contracts meant to be implemented by agents. - 
contractsshows clearly: the Adapter is a modernIterator. - 
with_compathighlights the dependency on the oldEnumeration. - No hidden tricks: we see immediately that the Adapter is a new agent created for translation.
 
And here’s an important detail:
- 
Enumerationis an abstraction (a very minimal contract, part of theagentdeclension in Clprolf). - 
Iteratoris a full agent, representing the modern iteration model. - So the Adapter not only bridges old to new, but also shows a shift in philosophy: from abstraction to agent.
 
🎯 Key takeaway
In Clprolf, the Adapter is never a “magical disguise.”
It’s simply:
A new agent that contracts the modern interface, and delegates to an old implementation through
with_compat.
This removes confusion and makes the intent crystal clear.
👀 Bonus: Using the Adapter in a Demo
For completeness, here’s how a client would actually use the Adapter.
Even if the old API gives you an Enumeration, the Adapter lets you treat it as a modern Iterator:
public worker_agent AdapterDemo {
    public static void main(String[] args) {
        Vector<String> legacyVector = new Vector<>();
        legacyVector.add("one");
        legacyVector.add("two");
        with_compat Enumeration<String> enumeration = legacyVector.elements();
        with_compat Iterator<String> iterator = new EnumToIterAdapter<>(enumeration);
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
    }
}
✨ What do you think? Have you used the Adapter pattern in real projects (e.g., bridging old APIs with modern ones)?
    
Top comments (0)