Inline Class
Before you begin: Classes, constructors, and fields.
Inline Class moves a class’s remaining fields and behavior into a class that uses it, then removes the redundant type. It is the reverse of Extract Class. 1
Original version: a class that only carries text
In this small application, a parcel has a label. An internal label class stores one string, performs no validation or formatting, and is not used anywhere else.
internal sealed class DeliveryLabel
{
public string Text { get; }
public DeliveryLabel(string text) { Text = text; }
}
public sealed class Parcel
{
private readonly DeliveryLabel label;
public Parcel(string text) { label = new DeliveryLabel(text); }
public string Label() { return label.Text; }
}class _DeliveryLabel:
def __init__(self, text):
self.text = text
class Parcel:
def __init__(self, text):
self._label = _DeliveryLabel(text)
def label(self):
return self._label.textThe extra object contributes neither a rule nor a meaningful operation. It is just one more place to visit while understanding a parcel.
Refactored version: store the text directly
public sealed class Parcel
{
private readonly string label;
public Parcel(string text) { label = text; }
public string Label() { return label; }
}The public constructor and Label method are unchanged. The internal object is gone.
class Parcel:
def __init__(self, text):
self._label = text
def label(self):
return self._labelParcel("Dock 4").label() still returns Dock 4; the parcel no longer forwards through another object.
A small class may still matter
A one-field type can prevent mixing a customer identifier with an order identifier, validate a currency, or enforce a security boundary. Those are real responsibilities. Size alone is not a reason to inline it.
Check other consumers, serialization, identity comparisons, and extension points before deleting a type. The example assumes the label wrapper is internal and unshared. If external code constructs or recognizes it, removing it changes an API and needs a migration plan.
Extraction and inlining are not rival philosophies. As requirements evolve, a class can acquire a useful role or lose one. Keep the separate type when its meaning and behavior justify it; remove it when it only adds navigation.