Template Method Design Pattern

Merhaba, son iki yazıda da creational dessign patternlardan bahsetmiştim. Bu sefer behavioral bir design pattern olan template method patterninden bahsediyorum.

Template method patterninni eğer senaryonuzda bir algoritmanın birden çok implementation u varsa kullanabilirsiniz. İsminden de anlaşılacağı üzeride template pattern bu algoritmadaki bazı adımların şablon olarak kalmasını sağlar.

Bir örnekte açıklamaya çalışayım.

Örneğe geçmeden önce şunu belirtmeliyim ki bu örneği hazırlarken sadece template kısmını anlattığım için o kısma odaklanmaya çalıştım elbette kod bir bütün olarak incelenip düzeltilebilir.

package template;

public abstract class MessageSendingAlgorithm {
	
	
	protected String text;
	
	protected DataBase db ;
	
	
	public MessageSendingAlgorithm(DataBase db ) {
		this.db = db;
	}
	
	
	public void runAlgorithm(int id,String message) { // Template method
		
		String user = getUserData(id);
		addMessageText(message);
		sendMessage(user);
	}
	
	public String getUserData(int id) {   // Step 1
		 return db.users.get(id).name;
	}
	
	public  void addMessageText(String message) {  // Step 2
		text = message;
	}
	
	public abstract void sendMessage(String user);  // Step 3
}

package template;

public class SmsSending extends MessageSendingAlgorithm{
	
	public SmsSending(DataBase db) {
		super(db);
	}

	@Override
	public void sendMessage(String user) {
		System.out.println("other things...");
		System.out.println("Message is sending via sms to "+user);
		System.out.println("Message: "+super.text);
	}

}

package template;

public class EmailSending extends MessageSendingAlgorithm {

	public EmailSending(DataBase db) {
		super(db);
	}

	@Override
	public void sendMessage(String user) {
		System.out.println("other things..");
		System.out.println("Message is sending via e-mail to "+user);
		System.out.println("Message: "+super.text);
	}

}

package template;

public class User {
	
	protected String name;
	protected int id;
	
	
	public User(String name) {
		this.name = name;
	}

}

package template;

import java.util.ArrayList;

public class DataBase {
	
	protected ArrayList<User> users  = new ArrayList<User>();
	
	
	protected  void addUSer(String name) {
		
		users.add(new User(name));
		
	}
	
	protected void removeUser(int id) {
		users.remove(id);
	}

}

package template;

public class Test {

	public static void main(String[] args) {

			DataBase db = new DataBase();
			
			db.addUSer("Ahmet");
			db.addUSer("Ayşe");
			
			MessageSendingAlgorithm algorithm = new EmailSending(db);
			algorithm.runAlgorithm(1, "You may get advantage on our product! We made  discount!! Keep reading...");
			
			System.out.println();
			algorithm = new SmsSending(db);
			algorithm.runAlgorithm(0, "Dear costomer, We realized that you have not payed last bill. Please take into account that you may pay just in time");
			
	}

}

Örnektede görüldüğü gibi üst sınıfta kalıplaşmış olan algoritmanın adımlarının içi dolu yaptım ama değişkenlik gösterebilecek olan kısmı abstract olarak belirledim.

Kısa bir not olarak söylemekte fayda var. Ortak olan kısımdaki metotları isterseniz final yapabilirsiniz bu sayede subclasstan override etme imkanını ortadan kaldırmış olursunuz ama dikkat edin bunu yapmak o metodu bir şekilde limitler.