標籤:
課程:Java程式設計 班級:1352 姓名:黃偉業 學號:20135315
成績: 指導教師:婁嘉鵬 實驗日期:2015.5.7
實驗密級: 預習程度: 實驗時間:15:50--20:50
儀器組次: 必修/選修: 選修 實驗序號:2
實驗目的:
1.掌握單元測試和TDD
2. 理解並掌握物件導向三要素:封裝、繼承、多態
3. 初步掌握UML建模
4. 熟悉S.O.L.I.D原則
5. 瞭解設計模式
實驗儀器:
名稱 |
型號 |
數量 |
PC |
Lenovo |
1 |
實驗樓環境 |
/ |
1 |
Eclipse |
/ |
1 |
一、實驗內容及步驟
一、 單元測試和TDD
代碼1:
public class MyUtil{
public static String percentage2fivegrade(int grade){
if ((grade < 0))
return "錯誤";
else if (grade < 60)
return "不及格";
else if (grade < 70)
return "及格";
else if (grade < 80)
return "中等";
else if (grade < 90)
return "良好";
else if (grade <= 100)
return "優秀";
else
return "錯誤";
}
}
代碼2:
import org.junit.Test;
import junit.framework.TestCase;
public class MyUtilTest extends TestCase {
@Test
public void testNormal() {
assertEquals("不及格", MyUtil.percentage2fivegrade(55));
assertEquals("及格", MyUtil.percentage2fivegrade(65));
assertEquals("中等", MyUtil.percentage2fivegrade(75));
assertEquals("良好", MyUtil.percentage2fivegrade(85));
assertEquals("優秀", MyUtil.percentage2fivegrade(95));
}
}
二、 物件導向三要素
代碼1:
public class AnimalTest {
public static void main(String[]args){
Dog d=new Dog();
d.setColor("Yellow");
getInfo(d);
Cat c=new Cat();
c.setColor("Black");
getInfo(c);
}
public static void getInfo(Dog d){
System.out.println(d.toString());
}
public static void getInfo(Cat c){
System.out.println(c.toString());
}
}
代碼2:
package dog;
public class DogTest {
public static void main(String[] args){
Dog g=new Dog();
g.setColor("Yellow");
getInfo();
}
public static void getInfo(Dog d){
System.out.println(d.toString());
}
}
代碼3:
public abstract class Animal {
private String color;
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public abstract String shout();
}
public class Dog extends Animal{
public String shout(){
return "汪汪";
}
public String toString(){
return "The Dog‘s color is " + this.getColor() +", and it shouts "+ this.shout() + "!";
}
}
public class Cat extends Animal{
public String shout(){
return "喵喵";
}
public String toString(){
return "The Cat‘s color is " + this.getColor() +", and it shouts "+ this.shout() + "!";
}
}
三、設計模式實樣本
S.O.L.I.D原則
物件導向三要素是“封裝、繼承、多態”,任何物件導向程式設計語言都會在文法上支援這三要素。如何藉助抽象思維用好三要素特別是多態還是非常困難的,S.O.L.I.D類設計原則是一個很好的指導:
SRP(Single Responsibility Principle,單一職責原則)
OCP(Open-Closed Principle,開放-封閉原則)
LSP(Liskov Substitusion Principle,Liskov替換原則)
ISP(Interface Segregation Principle,介面分離原則)
DIP(Dependency Inversion Principle,依賴倒置原則)
OCP是OOD中最重要的一個原則,OCP的內容是:
software entities (class, modules, function, etc.) should open for extension,but closed for modification.
軟體實體(類,模組,函數等)應該對擴充開放,對修改封閉。
基於OCP,利用物件導向中的多態性(Polymorphic),更靈活地處理變更擁抱變化,OCP可以用抽象和繼承、面向介面編程手段實現
SRP的內容是:
- There should never be more than one reason for a class to change
- 決不要有一個以上的理由修改一個類
LSP的內容是:
- Subtypes must be substitutable for their base types
- Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it
- 子類必須可以被其基類所代
- 使用指向基類的指標或引用的函數,必須能夠在不知道具體衍生類別物件類型的情況下使用它
ISP的內容是:
- Clients should not be forced to depend upon interfaces that they do not use
- 客戶不應該依賴他們並未使用的介面
DIP的內容是:
- High level modules should not depend upon low level modules. Both should depend upon abstractions
- Abstractions should not depend upon details. Details should depend upon abstractions
- 高層模組不應該依賴於低層模組。二者都應該依賴於抽象
- 抽象不應該依賴於細節。細節應該依賴於抽象
注意以下5點:
代碼:
abstract class Data {
abstract public void DisplayValue();
}
class Integer extends Data {
int value;
Integer() {
value=100;
}
public void DisplayValue(){
System.out.println (value);
}
}
//20135215
abstract class Factory {
abstract public Data CreateDataObject();
}
class IntFactory extends Factory {
public Data CreateDataObject(){
return new Integer();
}
}
//20135215
class Document {
Data pd;
Document(Factory pf){
pd = pf.CreateDataObject();
}
public void DisplayData(){
pd.DisplayValue();
}
}
public class MyDoc {
static Document d;
public static void main(String[] args) {
d = new Document(new IntFactory());
d.DisplayData();
}
}
(四)實驗練習使用TDD的方式設計關實現複數類Complex。
代碼1:
package complex;
public class ComplexTest{
public static void main(String[] args) {
Complex c=new Complex();
Complex c1=new Complex(6,12);
Complex c2=new Complex(11,32);
c1.Output();
c2.Output();
System.out.println("這兩複數和為:");
System.out.println(c.add(c1, c2).r+"+"+c.add(c1, c2).i+"i");
System.out.println("這兩複數差為:");
System.out.println(c.reduce(c1, c2).r+"+"+c.reduce(c1, c2).i+"i");
}
}
代碼2:
package complex;
public class Complex{
double r,i;
Complex()
{
this.r=0;//實數
this.i=0;//複數
}
Complex(double re,double im)
{
this.r=re;
this.i=im;
}
Complex reduce(Complex p1,Complex p2)
{
Complex p =new Complex(p1.r-p2.r,p1.i-p2.i);
return p;
}
Complex add(Complex p1, Complex p2) {
Complex p =new Complex(p1.r+p2.r,p1.i+p2.i);
return p;
}
void Output()
{
System.out.println("複數的值為:");
if(this.i!=0)
System.out.println(this.r+"+"+this.i+"i");
else
System.out.println(this.r);
}
}
實驗的好處:
先寫出虛擬碼,可以使在編寫產品代碼時更加流暢,編寫測試代碼可以盡量減少產品代碼中的bug。因此單元測試可以有效地提高編程效率,減少所寫程式中的bug。
實驗中遇到的問題:
複數類的定義不瞭解。
二、實驗感想
1、這次實驗耗費了很長時間,最後都要做不下去了。我深深體會到網路的重要性和學習新方法、使用新工具的能力的重要性。
2、UML圖有點抽象,在虛擬機器上實現的時候操作不熟練,剛開始一直沒明白怎麼把那個框調出來(因為實驗樓虛擬機器一直出問題,自己沒有靜下心來看操作步驟上“單擊工具列上的類表徵圖,再在class diagram(類圖)中單擊一下”),之後是那條箭頭畫不上去,百度教程,應該是先點擊工具列上的箭頭表徵圖(實現關係)然後點擊起始的類,出現一條虛線,再點擊指向的類。終於把能圖畫出來了。
3、TDD的方式例題的測試代碼看得懂,但是自己編寫的時候就不知道哪些語句怎麼用,只好用自己寫的測試代碼,可能這樣不算嚴格TDD方式,但是我覺得這樣的思想對我自己設計某些獨立功能是有很大協助的。
4、做練習代碼的時候,一看到實現複數類不知道具體是要做什麼,就上網搜了一下“Complex”,發現有輸出、加法、減法的功能,然後我就按著這樣的思路編寫了虛擬碼。開始的時候沒有把功能抽取出來,囉嗦的寫了很多,然後抽取了print功能,將每一項功能單獨出來,代碼一下就變少了。
然後我寫完上述報告後,看到老師給的複數類還有乘法的功能,我就把代碼翻出來,再實現了一下乘法的功能:
JAVA課程實驗報告 實驗二 JAVA物件導向程式設計