目錄
前言
開閉原則定義
開閉原則做用
開閉原則案例
1. 描述
2. uml 圖
3. 具體代碼
前言
在軟件開發中,爲了提升軟件系統的可維護性和可複用性,增長軟件的可擴展性和靈活性,程序員要儘可能根據 7 條原則來開發程序,從而提升軟件開發效率、節約軟件開發成本和維護成本。咱們將在下面的幾節中依次來介紹這 7 條原則,本節首先介紹開閉原則。
開閉原則定義
開閉原則規定「軟件中的對象(類,模塊,函數等等)應該對於擴展是開放的,可是對於修改是封閉的」,這意味着一個實體是容許在不改變它的源代碼的前提下變動它的行爲。該特性在產品化的環境中是特別有價值的,在這種環境中,改變源代碼須要代碼審查,單元測試以及諸如此類的用以確保產品使用質量的過程。遵循這種原則的代碼在擴展時並不發生改變,所以無需上述的過程。
咱們一般在程序設計中利用接口、抽象類、繼承和實現等方式來體現開閉原則。
開閉原則做用
開閉原則是面向對象程序設計的終極目標,它使軟件實體擁有必定的適應性和靈活性的同時具有穩定性和延續性。具體來講,其做用以下
對軟件測試的影響
軟件遵照開閉原則的話,軟件測試時只須要對擴展的代碼進行測試就能夠了,由於原有的測試代碼仍然可以正常運行。
能夠提升代碼的可複用性
粒度越小,被複用的可能性就越大;在面向對象的程序設計中,根據原子和抽象編程能夠提升代碼的可複用性。
能夠提升軟件的可擴展性和可維護性
遵照開閉原則的軟件,其穩定性高和延續性強,從而易於擴展和維護。
開閉原則案例
1. 描述
咱們設計圖書接口、電子書接口、以及SSM電子書類和美食書籍類。電子書接口經過繼承圖書接口,對其進行了擴展,增長了getSize()方法,即獲取電子書內存大大小。SSM電子書類經過實現電子書接口進一步擴展,增長了SSMComtent方法。美食書籍類經過實現圖書接口,一樣實現了擴展的方法。
之後若是咱們有了更多的武俠類、遊戲類……等書籍,不須要對原來的圖書接口進行修改,只須要繼承完成擴展便可。
2. uml 圖
3. 具體代碼
圖書接口
import java.util.Date;
/**
* 圖書接口
* 價格、書名、出版日期
*/
public interface IBook {
double getPrince();
String getName();
Date publishDate();
}
電子書接口,擴展了一個方法獲取電子書所佔大小的方法。
/**
* 電子書接口
*/
public interface IComputerBook extends IBook{
/**
* 獲取電子書大小 16kb
* */
String getSize();
}
實現圖書接口實現擴展。
import java.util.Date;
public class FoodBook implements IBook{
private String name;
private double price;
private Date publishDate;
public FoodBook(String name, double price, Date publishDate) {
this.name = name;
this.price = price;
this.publishDate = publishDate;
}
@Override
public double getPrince() {
return price;
}
@Override
public String getName() {
return name;
}
@Override
public Date publishDate() {
return publishDate;
}
public void foodContent() {
System.out.println("美食書籍: " + name + "-內容豐富哦!僅須要" + price +"元");
}
}
實現電子書接口實現擴展。
import java.util.Date;
public class SSMBook implements IComputerBook {
private String name;
private double price;
private Date publishDate;
private String size;
private String author;
public SSMBook(String name, double price, Date publishDate, String size, String author) {
this.name = name;
this.price = price;
this.publishDate = publishDate;
this.size = size;
this.author = author;
}
@Override
public String getSize() {
return size;
}
@Override
public double getPrince() {
return price;
}
@Override
public String getName() {
return name;
}
@Override
public Date publishDate() {
return publishDate;
}
public void SSMComtent() {
System.out.println("SSM架構實戰書籍:" + name + "-做者:" + author);
}
}
測試類
import java.util.Date;
public class Main {
public static void main(String[] args) {
FoodBook foodBook = new FoodBook("廚房祕籍", 30.00, new Date());
showBookConten(foodBook);
SSMBook ssmBook = new SSMBook("ssm架構", 57.20, new Date(), "20MB", "anben");
showBookConten(ssmBook);
}
private static void showBookConten(IBook iBook) {
if (iBook instanceof IComputerBook) {
SSMBook ssmBook = (SSMBook) iBook;
ssmBook.SSMComtent();
} else {
FoodBook foodBook = (FoodBook) iBook;
foodBook.foodContent();
}
}
}
測試結果
美食書籍: 廚房祕籍-內容豐富哦!僅須要30.0元
SSM架構實戰書籍:ssm架構-做者:anben
MainActivity:
複製代碼
1 //定義底部文字
2 private final int[] TAB_TITLES = new int[]{
3 R.string.menu_msg, R.string.menu_history, R.string.menu_mine
4 };
5 //定義底部圖標
6 private final int[] TAB_IMGS = new int[]{
7 R.drawable.tab_main_msg, R.drawable.tab_main_history, R.drawable.tab_main_mine
8 };
9 //黃油刀 找到控件
10 @BindView(R.id.view_pager)
11 ViewPager viewPager;
12 @BindView(R.id.tab_layout)
13 TabLayout tabLayout;
14
15 //定義適配器
16 private PagerAdapter pagerAdapter;
17
18
19
20
21 //初始化頁卡
22 private void initPager() {
23 pagerAdapter = new MainFragmentAdapter(getSupportFragmentManager());
24 viewPager.setAdapter(pagerAdapter);
25 viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
26 tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
27 @Override
28 public void onTabSelected(TabLayout.Tab tab) {
29 viewPager.setCurrentItem(tab.getPosition(), false);
30 }
31
32 @Override
33 public void onTabUnselected(TabLayout.Tab tab) {
34
35 }
36
37 @Override
38 public void onTabReselected(TabLayout.Tab tab) {
39
40 }
41 });
42 }
43
44
45 //設置頁卡顯示效果
46 private void setTabs(TabLayout tabLayout, LayoutInflater inflater, int[] tabTitles, int[] tabImgs) {
47 for (int i = 0; i < tabImgs.length; i++) {
48 TabLayout.Tab tab = tabLayout.newTab();
49 View view = inflater.inflate(R.layout.item_main_menu, null);
50 //使用自定義視圖,便於修改
51 tab.setCustomView(view);
52 TextView tvTitle = (TextView) view.findViewById(R.id.txt_tab);
53 tvTitle.setText(tabTitles[i]);
54 ImageView imgTab = (ImageView) view.findViewById(R.id.img_tab);
55 imgTab.setImageResource(tabImgs[i]);
56 tabLayout.addTab(tab);
57 }
58 }
複製代碼
MainActivity.xml:
複製代碼
1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
2 xmlns:app="http://schemas.android.com/apk/res-auto"
3 xmlns:tools="http://schemas.android.com/tools"
4 android:layout_width="match_parent"
5 android:layout_height="match_parent"
6 android:orientation="vertical"
7 tools:context=".MainActivity">
8 <RelativeLayout
9 android:layout_width="match_parent"
10 android:layout_height="wrap_content"
11 >
12 <com.example.myapplication.mytoobar.CustomToolbar
13 android:id="@+id/bar1"
14 android:layout_width=www.xcdeyiju.com"match_parent"
15 android:layout_height="wrap_content"/>
16 <View
17 android:layout_width="match_parent"
18 android:layout_height="0.5dp"
19 android:background="@color/line_gray"
20 android:layout_alignBottom="@+id/bar1"></View>
21 </RelativeLayout>
22 <android.support.v4.view.ViewPager
23 android:id="@+id/view_pager"
24 android:layout_width="match_parent"
25 android:layout_height="0dip"
26 android:layout_weight="1" />
27
28 <View
29 android:layout_width="match_parent"
30 android:layout_height=www.yuchenghd.com"0.5dip"
31 android:background="@color/line_gray" />
32
33 <android.support.design.widget.TabLayout
34 android:id="@+id/tab_layout"
35 android:layout_width="match_parent"
36 android:layout_height="100dp"
37 app:tabIndicatorHeight="0dip" />
38
39 </LinearLayout>
複製代碼
Adapter:
複製代碼
1 @Override
2 public Fragment getItem(int i) {
3 Fragment fragment = null;
4 switch (www.yuchengyuLedL.com) {
5 case 0:
6 fragment = new MsgFragment();
7 break;
8 case 1:
9 fragment = new HistoryFragment();
10 break;
11 case 2:
12 fragment = new MineFragment();
13 break;
14 default:
15 break;
16 }
17 return fragment;
18
19 }
20
21 @Override
22 public int getCount() {
23 return 3;
24 }
複製代碼
四:自定義標題欄的實現
關鍵代碼:
toolbar.xml:
複製代碼
1 <ImageView
2 android:layout_width="www.xingtuyLgw.com wrap_www.yifayuled.cn content"
3 android:layout_height="wrap_content"
4
5
6 android:src="@mipmap/ic_launcher"
7 android:layout_gravity="left"
8 />
9 <TextView
10 android:id="@+id/tv_title"
11 android:layout_width="wrap_content"
12 android:layout_height="wrap_content"
13 android:text=www.whonyLpt.com"SubwayGo"
14 android:textColor="#000000"
15 android:layout_gravity="center"
16 android:singleLine="true"
17 android:visibility="visible"
18 android:textSize="30dp"
19 android:fontFamily="cursive"
20 />
21 <TextView
22 android:layout_width="wrap_content"
23 android:layout_height="wrap_content"
24 android:textSize="20dp"
25 android:textColor="@color/colorPrimaryDark"
26 android:text="設置"
27 android:gravity="center"
28 android:layout_gravity="right"
29 android:visibility=www.xingtuyuLept.com"visible"
30 />
複製代碼
複製代碼
1 public class CustomToolbar extends Toolbar {
2
3 public CustomToolbar(Context context)www.chaoyuepint.com{
4 this(context,null);
5 }
6 public CustomToolbar(Context www.baiyidLu.com context, AttributeSet attrs) {
7 this(context, attrs,0);
8 }
9 public CustomToolbar(Context context,www.baitengpt.com AttributeSet attrs,int defStyleAttr){
10 super(context,attrs,defStyleAttr);
11 inflate(context, R.layout.toolbar,this);
12 }
13 }
複製代碼
五:總結一下,以上代碼都是關鍵代碼,至於點擊事件的設置,頁面數據的傳遞等等比較基礎,就不附上了。下一篇會對線路的最優路徑進行選擇。java