工廠模式:
定義了一個創建對象的接口,但由子類決定要實例化的類是哪一個。工廠方法讓類將實例化推遲到子類。只需要創建相關或依賴對象的家族,而不需要明確指定具體類。這樣,客戶程序中關於超類的代碼和子類對象創建代碼解耦了。
設計原則:
針對接口編程,而不是針對實現編程(變量不可以持有具體類的引用)。
關於Pizza的工廠模式的uml圖:
用例:
需求:
假設我們現在有多種佈局樣式的 Fragment ,準備用 ViewPager 來裝載, 並實現滾動切換的效果,其中會根據數據的不同採用不同的 Fragment 。
思路:
1. 創建一個 BaseFragment ,然後讓所有佈局樣式的 Fragment 都繼承這個 BaseFragm ,在要添加對象的地方直接 BaseFragment f = new Fragment1() 。 這樣做功能上是可行的,但是這違背了一個設計原則,那就是儘量遵循 "針對接口編程,而不是去針對實現編程" 。
2. 採用工廠模式進行設計。這樣做的好處是如果什麼時候又添加了新的fragment,就可以在不改動現有的代碼的情況下,可以往裏面添加新的 fragment。
具體實現:
1. 創建一個工廠接口:
public abstract class BaseFragmentsInterface { FragmentInterfaces fragmentInterfaces;//fragment的引用 public Fragment getFragment(int i){ fragmentInterfaces = createFragment(i); //獲取具體的fragment的實例 return fragmentInterfaces.newInstance(i); } //抽象方法,由子類來決定具體的實現,超類並不知情 protected abstract FragmentInterfaces createFragment(int i);
2. 創建具體的fragment:
public class CreateFragment1 extends BaseFragmentsInterface { //根據數據的類型的不同,創建指定的fragm @Override protected FragmentInterfaces createFragment(int i) { if(i == 0){ return new Fragment1(); }else if(i == 1){ return new Fragment1(); }else if(i == 2){ return new Fragment1(); }else if(i == 3){ return new Fragment1(); } return null; }3. 創建一個接口,讓所有的fragment都實現這個接口:
public interface FragmentInterfaces { abstract Fragment newInstance(int s); }4. 創建具體的fragment:
public class Fragment1 extends BaseFragments implements FragmentInterfaces{ private String hello = "hello android"; private String defaultHello = "default value"; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { Bundle args = getArguments(); hello = args != null ? args.getString("hello") : defaultHello; View view = inflater.inflate(R.layout.layout_fragment1, container, false); TextView viewhello = (TextView) view.findViewById(R.id.tv); viewhello.setText(hello); return view; } //根據數據的類型不同,在fragment裏面顯示不同的文字說明 @Override public Fragment1 newInstance(int s) { Fragment1 newFragment = new Fragment1(); Bundle bundle = new Bundle(); if(s == 0){ bundle.putString("hello", "this is 0 fragment!"); }else if(s == 1){ bundle.putString("hello", "this is 1 fragment!"); }else if(s == 2){ bundle.putString("hello", "this is 2 fragment!"); }else if(s == 3){ bundle.putString("hello", "this is 3 fragment!"); } newFragment.setArguments(bundle); //bundle還可以在每個標籤裏傳送數據 return newFragment; }5. 添加 fragment 到 viewpager:
//這裏假設list的角標不同添加不同的fragment for (int i = 0; i < listNumber.size(); i++) { if(i >= 0 && i < 4){ BaseFragmentsInterface baseFragmentsInterface = new CreateFragment1(); fragmentList.add(baseFragmentsInterface.getFragment(i)); }else if(i >= 4 && i < 8){ BaseFragmentsInterface baseFragmentsInterface = new CreateFragment2(); fragmentList.add(baseFragmentsInterface.getFragment(i)); }else if(i >= 8 && i < 12){ BaseFragmentsInterface baseFragmentsInterface = new CreateFragment3(); fragmentList.add(baseFragmentsInterface.getFragment(i)); } }
private void initAdapter(){ viewPager.setAdapter(new MyViewPagerAdapter(getSupportFragmentManager() , fragmentList)); viewPager.setCurrentItem(0); viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
/** * 作者: on 2016/11/8 17:43 * 說明: FragmentPagerAdapter: 默認將Fragment緩存到內存 * FragmentStatePagerAdapter:切換之後就會移除其他的fragment,不會緩存到內存 */ public class MyViewPagerAdapter extends FragmentStatePagerAdapter { private List<Fragment> list; public MyViewPagerAdapter(FragmentManager fm , List<Fragment> list) { super(fm); this.list = list; } @Override public Fragment getItem(int position) { if(list.size() > 0){ return list.get(position); } return null; } @Override public int getCount() { return list.size(); }
6. 創建fragment 的uml: