package template; /** * Abstract Class with Template Method. * The overall migration algorithm is fixed here; subclasses fill in * the source-specific steps (connect, read, transform). */ public abstract class DataMigration { // THE TEMPLATE METHOD — defines the fixed algorithm skeleton public final void migrate() { System.out.println("\n[" + getSourceName() + "] Starting migration..."); connect(); validate(); int rowCount = readData(); int transformed = transformData(rowCount); writeData(transformed); if (sendNotification()) { notifyStakeholders(); } disconnect(); System.out.println("[" + getSourceName() + "] Migration complete.\n"); } // Abstract steps — must be implemented by each subclass protected abstract String getSourceName(); protected abstract void connect(); protected abstract int readData(); protected abstract int transformData(int rawCount); // Concrete steps — common to all migrations protected void validate() { System.out.println(" Validating schema compatibility..."); } protected void writeData(int count) { System.out.println(" Writing " + count + " rows to target..."); } protected void disconnect() { System.out.println(" Closing source connection."); } // Hook — subclasses may override to change behaviour protected boolean sendNotification() { return true; } protected void notifyStakeholders() { System.out.println(" Sending completion email to team."); } }