設計模式(五)——模板方法模式

liangxingwei發表於2017-12-14

本文原創掘金:L_Sivan

模板方法模式

  • 定義: 定義一個操作中演算法的框架,而將一些步驟延遲到子類中。模板方法模式使得子類可以不改變一個演算法的結構即可重定義該演算法的某些特定步驟。
  • 作用: 通過使用模板方法模式,可以將一些複雜流程的實現步驟封裝在一系列基本方法中,在抽象父類中提供一個稱之為模板方法的方法來定義這些基本方法的執行次序,而通過其子類來覆蓋某些步驟,從而使得相同的演算法框架可以有不同的執行結果。
  • 是一個行為類模式

上例子:

// 抽象模板
public abstract class AbstractCarCreater {
	protected void assemblyCar(){
		System.out.println("先把車的總體框架搭好");
	}
	protected abstract void coloring();
	protected abstract void assemblyLogo( );
	public void createrCar(  ){
		assemblyCar();
		this.coloring();
		this.assemblyLogo();
	}
}
// 賓士模板
public class BenzCarCreater extends AbstractCarCreater{
	@Override
	protected void coloring( ) {
		System.out.println("奢華的賓士得上亮黑色");
	}
	@Override
	protected void assemblyLogo() {
		System.out.println("上了一個極致奢華的賓士Logo");
	}
}
// 寶馬模板
public class BmwCarCreater extends AbstractCarCreater{
	@Override
	protected void coloring() {
		System.out.println("寶馬要上酷炫的銀白色");
	}
	@Override
	protected void assemblyLogo() {
		System.out.println("上了一個顯眼的BMW的Logo");
	}
}
// 場景類
public class Client {
	public static void main(String[] args) {
		BenzCarCreater benzCarCreater = new BenzCarCreater();
		benzCarCreater.createrCar();
		System.out.println("-------------------------------------");
		BmwCarCreater bmwCarCreater = new BmwCarCreater();
		bmwCarCreater.createrCar();
	}
}
複製程式碼

上面的程式碼,在抽象模板中,我們已經定好了一個演算法的框架,組裝一輛完整的車的演算法,然後演算法中的方法是抽象的,交由子類來實現,每多一個字類,就有多一個不同的執行結果,這就是模版方法。

擴充套件

這個擴充套件,其實並不是什麼知識點或者思想層面的擴充套件,而是,寫了這幾篇設計模式,在大學團隊專案中用到的模式啊!!!!興奮到爆炸。

做過Java s2sh開發的人其實應該也用到,可能不知道是這種模式而已,下面來簡單地上點程式碼:

// 定義對資料庫的增刪改查操作
public interface BaseDao<T> {
	public Serializable add(T t);
	public void update(T t);
	public void delete(T t);
	public int delete(Serializable id); 
	public T findDataById(Serializable id);
	public List<T> findAllData();
	public List<T> findDataByPage(int pageNum, int pageCount);
	public List<T> findDataByCondition(String conditionName, String conditionValue,String conditionOperation);
}
// 將資料庫的增刪改查操作實現
public abstract class HibernateDao<T> implements BaseDao<T>{
	@Autowired
	private SessionFactory sessionFactory; 
	public SessionFactory getSessionFactory() {
		return sessionFactory;
	}
	public void setSessionFactory(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
	}
	@Override
	public Serializable add(T t) {
		return sessionFactory.getCurrentSession().save(t);
	}
	@Override
	public void update(T t) {
		sessionFactory.getCurrentSession().update(t);
	}
	@Override
	public int delete(Serializable id) {
		String hql = "delete from "+this.getEntityClass().getSimpleName()+" en where en.id = ?";
		return sessionFactory.getCurrentSession().createQuery(hql).setParameter(0, id).executeUpdate();
	}
	@Override
	public void delete(T t) {
		sessionFactory.getCurrentSession().delete(t);
	}
	@Override
	public T findDataById(Serializable id) {
		return (T) sessionFactory.getCurrentSession().get(getEntityClass(), id);
	}
	@Override
	public List<T> findDataByCondition(String conditionName, String conditionValue, String conditionOperation) {
		String hql = "select en from "+getEntityClass().getSimpleName()+" en where en."+conditionName+" "+conditionOperation+"?";
		return sessionFactory.getCurrentSession().createQuery(hql).setParameter(0, conditionValue).list();
	}
	@Override
	public List<T> findDataByPage(int pageNum, int pageCount) {
		String hql = "from "+getEntityClass().getSimpleName();
		return sessionFactory.getCurrentSession().createQuery(hql).setFirstResult((pageNum-1)*pageCount).setMaxResults(pageCount).list();
	}
	@Override
	public List<T> findAllData() {
		String hql = "from "+getEntityClass().getSimpleName();
		return sessionFactory.getCurrentSession().createQuery(hql).list();
	}
    // 終極方法
	protected abstract Class<T> getEntityClass();
}
// 真正的dao
@Repository
public class BookDao extends HibernateDao<Book>{
	@Override
	protected Class<Book> getEntityClass() {
		return Book.class;
	}
}
複製程式碼

上面的程式碼就用到了模版方法模式,BaseDao中,使用了泛型約束Bean的型別,確保實現該介面的Dao都是操作某一個Bean的,然後,它的每個增刪改查的方法其實都是相同操作的“演算法”,是的,就是演算法,唯一的不同點在哪?就是Bean的名字。所以用了一個HibernateDao來繼承BaseDao,然後定義了一個終極方法protected abstract Class getEntityClass();,通過這個方法來獲取傳入的類的class屬性,從而獲得Bean的名字,從而得到不同的演算法結果,這個就是一個活生生的模版方法模式,棒棒噠。

水平有誤,難免有錯,還請拍磚

相關文章