軟件架構與設計模式課后習題答案(2-4章)_第1頁
軟件架構與設計模式課后習題答案(2-4章)_第2頁
軟件架構與設計模式課后習題答案(2-4章)_第3頁
軟件架構與設計模式課后習題答案(2-4章)_第4頁
軟件架構與設計模式課后習題答案(2-4章)_第5頁
已閱讀5頁,還剩64頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

第2章習題與參考答案

1.某基于Java的C/S系統的“登錄功能”通過如下登錄類(Login)實現,請指出設計存

在的問題,并基于單一職責原則進行重構。

Login

+init():void

+display():void

+validate0:void

+getConnection():Connection

+findUser(StringuserName.:boolean

StringuserPassword)

+main(Stringargs[J):void

答案:功能太過于集成,嚴重違反類的單一原則。就一個類而言,應該僅有一個引起

它變化的原因。

2.某圖形界面系統提供了各種不同形狀的按鈕,客戶端代碼可針對這些按鈕進行編程,用

戶可能會改變需求要求使用不同的按鈕,原始設計方案如圖所示,請指出設計存在的問題,

并基于開閉原則對該系統進行重構。

答案:客戶端的一個方法直接調用加法類,當需要變更,如想添加一個減法類時就得改變

加法類中代碼(用switch語句實現),這就違背了“開閉原則”,應該進行重構。

3.某系統需要實現對重要數據(如用戶密碼)的加密處理,在數據操作類(DataOperator)

中需要調用加密類中定義的加密算法,系統提供了兩個不同的加密類,CipherA和CipherB,

它們實現不同的加密方法,在DataOperator中可以選擇其中的一個實現加密操作。請指出

設計存在的問題,并基于里氏代換原則進行重構。

答案:因為如果需要更換一個加密算法類或者增加并使用一個新的加密算法類,如將

CipherA改為CipherB,則需要修改客戶類Client和數據操作類DataOperator的源代碼,

違背了開閉原則。現使用里氏代換原則對其進行重構,使得系統可以靈活擴展,符合開閉

原則。子類型必須能夠替換掉它們的父類型。

□<className>CipherB</dassName>

configjanl

4.某系統提供一個數據轉換模塊,可以將來自不同數據源的數據轉換成多種格式,如可以

轉換來自數據庫的數據(DatabaseSource)、也可以轉換來自文本文件的數據(TextSource),

轉換后的格式可以是XML文件(XMLTransformer)>也可以是XLS文件(XLSTransformer),

原始設計方案如圖所示,請指出設計存在的問題,并基于依賴倒轉原則進行重構。

XMLTransformer

MainClass

+main(Stringargs[]):void

XLSTransformer

答案:因為該系統可能需要增加新的數據源或者新的文件格式,每增加一個新類型的數據

源或者新類型的文件格式,客戶類MainClass都需要修改源代碼,以便使用新的類,這樣

就違背了開閉原則。因此使用依賴倒轉原則對其進行重構。

<sourceName>Data&aseSource</sonceName>

<transformerName>XMLTransfocmer<transformerName>

5.一個擁有多個客戶類的系統,在系統中定義了一個巨大的接口(胖接口)

Abstractservice來服務所有的客戶類。如圖所示,請指出設計存在的問題,并基于接口

分離原則進行重構。

CoocreteService

?operatorA()void

?op?fator8()void

?operatocC()vcxd

答案:類應該完全依賴相應的專門的接口,這樣一個功能集中的接口違背了接口隔離原則,

一旦針對某個客戶的方法發生改變,就需要進行重新編譯和發布,因此其他客戶都會受到

影響。

因為這樣做既滿足了接口隔離原則,又滿足了單一原則,何樂而不為呢,但是也帶來了很

多的不便,類增多了。

6.某教學管理系統部分數據庫訪問類設計如圖所示,請指出設計存在的問題,并基于合成

復用原則進行重構。

答案:因為如果需要更換數據庫連接方式,則需要修改DBUtil類源代碼。例如如原來采用

JDBC連接數據庫,現在采用數據庫連接池連接;如果StudentDAO采用JDBC連接,但是

TeacherDAO采用連接池連接,則需要增加一個新的DBUtil類,并修改StudentDAO或

TeacherDAO的源代碼,使之繼承新的數據庫連接類,這樣導致違背開閉原則,系統擴展性

較差,應盡量使用對象組合而不是用繼承來達到復用的目的。

7.某系統界面類(如Forml、Form2等類)與數據訪問類(如DA01、DA02等類)設計如圖,類

之間的調用關系較為復雜。請指出設計存在的問題,并基于迪米特法則進行重構。

答案:由于界面控件之間的交互關系復雜,導致在該窗口中增加新的界面控件時,需要修

改與之交互的其他控件的源代碼,系統擴展性較差,也不便于增加和刪除新控件。違反了

一個軟件實體應當盡可能少的與其他實體發生相互作用的原則,即違反迪米特法則。

這樣就可以降低類的耦合性,是類中功能更加單一,相當于外觀模式。

第3章習題與參考答案

1.有一系列的自動車產品Bus(公交車),Truck(卡車);它們需要由不同的工廠生

產,但具有相同的生產流程。為了以后擴展其他流水線,比如摩托車,我們需要一種柔軟

的方案來實現自動車生產的過程。請基于Java分別用工廠方法、抽象工廠方法兩種設計模

式加以實現。

參考答案:

1)工廠方法:

classCarFactory{

publicCarcreateCar(StringcarType){

if(carType.equals("BUS"))

ReturnnewCarBus();

if(carType.equals("TRUCK"))

ReturnnewCarTruck();

)

)

publicclassClient{

publicstaticvoidmain(String[]args){

CarFactoryfactory=newCarFactory();

〃生產公交車

Carbus=factory.createCar(^BUS^);

System,out?printin(〃生產了:“+bus.getTypeO);

〃生產卡車

Cartruck=factory.createCar(UTRUCK,,);

System,out.printin(〃生產了:〃+truck.getTypeO);

)

)

2)抽象工廠方法:

abstractclassCarFactory{

〃定義生產自動車生產的接口規范

publicCarcreateCar();

)

classBusFactoryextendsCarFactory{

publicCarcreateCar(){

〃生產公交車

returnnewCarBus();

)

)

classTruckFactoryextendsCarFactory{

publicCarcreateCar(){

〃生產卡車

returnnewTruckBus();

)

)

publicclassCar{

publicStringgetType(){

return〃Car";

)

)

publicclassCarBusextendsCar{

publicStringgetType(){

return〃Bus";

)

)

publicclassCarTruckextendsCar(

publicStringgetType(){

return"Truck”;

)

}

publicclassClient{

publicstaticvoidmain(String[]args){

CarFactoryfactory=newBusFactoryO;

〃生產公交車

Carbus=factory.createCar();

System,out.printin(〃生產了:〃+bus.getType());

factory=newTruckFactory();

〃生產卡車

Cartruck=factory.createCar();

System,out.printIn("生產了:"+truck.getType());

)

}

2.請基于Java設計一個單例模式的程序,驗證單例模式的實例有且僅有一個。

參考答案:

publicclassSingleton{

privatestaticSingletons;

publicstaticSingletongetlnstance(){

if(s==null)

s=newSingleton();

returns;

)

}

//測試類

classsingletonTest{

publicstaticvoidmain(String[]args){

Singletonsi=Singleton,getlnstance();

Singletons2=Singleton,getlnstance();

if(sl=s2)

System,out.printin(/zslisthesameinstancewiths2〃);

else

System,out.println(z,slisnotthesameinstancewiths2〃);

)

)

singletonTest運行結果是:

siisthesameinstancewiths2

3.某圖形編輯器的原型模式設計方案如下圖,首先創建一個抽象類Shape和擴展

了Shape類的實體類,其次是定義類ShapeCache,該類把shape對象存儲在一個

Hashtable中,并在請求的時候返回它們的克隆。請基于Java著手實現。

參考答案:

步驟1、創建一個實現了Clonable接口的抽象類。

Shape,java

publicabstractclassShapeimplementsCloneable{

privateStringid;

protectedStringtype;

abstractvoiddraw();

publicStringgetTypeO(

returntype;

)

publicStringgetldO{

returnid;

}

publicvoidsetId(Stringid){

this,id=id;

)

publicObjectclone(){

Objectclone=null;

try(

clone=super,clone();

}catch(CloneNotSupportedExceptione){

e.printStackTrace();

)

returnclone;

)

)

步驟2、創建擴展了上面抽象類的實體類。

Rectangle,java

publicclassRectangleextendsShape{

publicRectangle(){

type="Rectangle”;

)

?Override

publicvoiddraw(){

System.out.printin(^InsideRectangle::draw()method.");

)

)

Square,java

publicclassSquareextendsShape(

publicSquare(){

type="Square”;

?Override

publicvoiddraw(){

System,out.printin(''InsideSquare::draw()method.z,);

)

)

Circle,java

publicclassCircleextendsShape{

publicCircle(){

type="Circle”;

)

?Override

publicvoiddraw(){

System.out.printIn("'InsideCircle::draw()method.,z);

)

)

步驟3、創建一個原型管理器類,從數據庫獲取實體類,并把它們存儲在一個Hashtable中。

ShapeCache.java

importjava.util.Ilashtable;

publicclassShapeCache{

privatestaticHashtable<String,Shape>shapeMap

二newHashtable<String,Shape>();

publicstaticShapegetShape(StringshapeId){

ShapecachedShape=shapeMap.get(shapeld);

return(Shape)cachedShape.clone();

}

//對每種形狀都運行數據庫查詢,并創建該形狀

//shapeMap.put(shapeKey,shape);

//例如,我們要添加三種形狀

publicstaticvoidloadCache(){

Circlecircle=newCircle();

circle.setld(〃l〃);

shapeMap.put(circle,getld(),circle);

Squaresquare=newSquare();

square.setld(〃2〃);

shapeMap.put(square,getld(),square);

Rectanglerectangle=newRectangle();

rectangle.setld(〃3〃);

shapeMap.put(rectangle,getld(),rectangle);

)

}

步驟4、PrototypePatternDemo使用ShapeCache類來獲取存儲在Ilashtable中的形狀

的克隆。

PrototypePatternDemo.java

publicclassPrototypePatternDemo{

publicstaticvoidmain(String[]args){

ShapeCache.loadCache();

ShapeclonedShape二(Shape)ShapeCache.getShape(〃l〃);

System,out.printIn(z,Shape:〃+clonedShape.getTypeO);

ShapeclonedShape2=(Shape)ShapeCache.getShape(/,2,/);

System,out.println(^Shape:〃+clonedShape2.getTypeO);

ShapeclonedShape3=(Shape)ShapeCache.getShape(〃3〃);

System,out.printin(/zShape:"+clonedShape3.getTypeO);

}

)

步驟5、驗證輸出。

Shape:Circle

Shape:Square

Shape:Rectangle

4.以組裝電腦為例,請基于Java利用創建者模式實現電腦產品的組裝實現。

參考答案:

1)在這里,我們先定義商品Commodity(Product)類:

publicclassCommodity{

Stringcommodity=〃〃;

publicCommodity(PartpartA,PartpartB,PartpartC){〃由各個部分組成

this,commodity=partA.part+〃\n”;

this,commodity=product+partB.part+,z\n,z;

this,commodity=product+partC.part;

System,out.printing我的機器配置為:\n"+commodity);

)

)

2)接下來我們再定義電腦的組成部分(Part)類:

publicclassPart{

Stringpart="〃;

publicPart(Stringpart){

this,part=part;

}

3)我們把電腦Computer(Builder)定義成一個接口類:

publicinterfaceComputer{

〃組裝部件A比如CPU

voidbuiIdPartAO;

〃組裝部件B比如主板

voidbuildPartBO;

〃組裝部件C比如硬盤

voidbuildPartCO;

〃返回最后組裝成品結果(返回最后組裝好的電腦)

〃成品的組裝過程不在這里進行,而是由組裝師(Assembler)類完成的。

〃從而實現了過程和部件的分離

ProductgetProduct();

}

4)定義電腦的組裝師Assembler(Director)類:

publicclassAssembler{

privateComputercomputer;

publicAssembler(Computercomputer){〃主要任務是裝電腦

this,computer=computer;

)

//將部件partApartBpartC最后組成復雜對象

〃這里是將主板、CPU和硬盤組裝成PC的過程

publicvoidconstruct(){

computer,buiIdPartAO;

computer.buildPartBO;

computer.buildPartCO;

)

}

5)我的電腦是對電腦接口的具體實現,因此再定義MyComputer實現類(ConcreteBuilder):

publicclassMyComputerimplementsComputer{

PartpartA,partB,partC;

publicvoidbuiIdPartAO{

partA=newPart(“P42.4CPU");

)

publicvoidbuildPartBO{

partB=newPart(,zInter主板〃);

)

publicvoidbuildPartCO{

partC=newPart(〃80G硬盤〃);

publicProductgetProduct0{

//返回最后組裝成品結果

CommoditymyComputer=newCommodity(partA,partB,partC);

returnmyComputer;

)

)

6)編寫測試類:

publicclassMyComputerTest{

publicstaticvoidmain(Stringargs[]){

MyComputermyComputer二newMyComputer();〃組裝我的電腦

Assemblerassembler=newAssembler(myComputer);〃派某一位組裝師

assembler,construct();〃組裝師進行組裝過程

Commoditycommodity二myComputer.getProduct();〃賣給我的電腦(商品)

)

}

5.四只小花貓參加唱歌比賽,比賽要求五只參賽,他們只有四只,他們把小花狗忽悠

進來了,可小花狗不會sing,請基于Java利用適配器模式幫幫它們。

參考答案:

1)Cat.java

publicinterfaceCat{

publicvoidsing();

)

2)SmallFlowerCat.java

publicclassSmallFlowerCatimplementsCat(

privateStringname;

publicSmalIFlowerCat(Stringname){

this,name=name;

)

?Override

publicvoidsing(){

System,out.println(name+z/一唯?");

)

)

3)Dog.java

publicclassDog(

publicvoidbake(){

System,out.printin(“汪汪~〃);

)

)

4)CatAdapter.java

publicclassCatAdapterimplementsCat{

privateDogmDog;

publicCatAdapter(Dogdog){

mDog=dog;

)

?Override

publicvoidsing(){

mDog.bake();

}

)

5)Test,java

importjava.util.ArrayList;

publicclassTest{

publicstaticvoidmain(Stringargs[]){

ArrayList<Cat>catArrayList=newArrayList<Cat>();

Dogdog=newDog();

for(inti=0;i<4;i++){

SmallFlowerCatcat=newSmallFlowerCat("小花貓"+(i+l)+”號");

catArrayList.add(cat);

)

CatdogToCat=newCatAdapter(dog);

catArrayList.add(dogToCat);

for(Catc:catArrayList){

c.sing();

}

}

)

測試結果:

小花貓1號一嘀~

小花貓2號一哨~

小花貓3號一哨~

小花貓4號一哺~

汪汪~

6.利用組合模式實現一個樹形菜單的創建。通過Javaswing的JTree組件,節點實

現類為DefaultMutableTreeNode,用于創建根節點、子節點和孫節點對象,再通過

DefaultTreeModel類利用根節點創建樹模型對象,然后通過treeModel.insertNodelnto

方法將節點對象插入樹模型中。創建樹形菜單結構與創建菜單欄類似,都是按層次與模型

創建的。

參考答案:

importjava.awt.*;

importjavax.swing.*;

importjavax.swing,tree.*;

importjavax.swing,event.*;

publicclassTreeextendsJFrameimplementsTreeSelectionListener

(

privateJLabellabel;

publicTreeO

(

super(〃樹形菜單〃);setSize(400,400);

Containercontainer=getContentPane();

〃創建根節點和子節點

DefaultMutableTreeNoderoot=newDefaultMutableTreeNode(〃文本編輯器〃);

Defau1tMutab1eTreeNodenodel=newDefaultMutableTreeNode(〃文件“);

DefaultMutableTreeNodenode2=newDefaultMutableTreeNode("編輯〃);

〃利用根節點創建TreeModel

Defau1tTreeMode1treeModel=newDefaultTreeModel(root);

〃插入子節點nodel,node2

treeModel.insertNodelnto(nodel,root,root.getChildCount());

treeModel.insertNodelnto(node2,root,root.getChildCount());

〃創建節點nodel的子節點并插入

DefaultMutableTreeNodeleafnode=newDefaultMutableTreeNode(〃打開”);

treeModel.insertNodelnto(leafnode,nodel,nodel.getChildCount());

leafnode=newDefaultMutableTreeNode(〃保存”);

treeModel.insertNodelnto(leafnode,nodel,nodel.getChildCount());

leafnode=newDefaultMutableTreeNode(“另存為〃);

treeModel.insertNodelnto(leafnode,nodel,nodel.getChildCount());

leafnode=newDefaultMutableTreeNode(〃關閉〃);

treeModel.insertNodelnto(leafnode,nodel,nodel.getChildCount());

〃創建節點node2的子節點并插入

leafnode=newDefaultMutableTreeNode(〃剪切〃);

treeModel.insertNodelnto(leafnode,node2,node2.getChildCount());

leafnode=newDefaultMutableTreeNode("復制〃);

treeModel.insertNodelnto(leafnode,node2,node2.getChildCount());

leafnode二newDefaultMutableTreeNode(〃粘貼〃);

treeModel.insertNodelnto(leafnode,node2,node2.getChildCount());

〃創建樹對象

JTreetree=newJTree(treeModel);

〃設置Tree的選擇為一次只能選擇一個節點

tree.getSelectionModel().setSelectionMode(

TreeSelectionModel.SINGLE_TREE_SELECTION);

〃注冊監聽器

tree.addTreeSelectionListener(this);

tree.setRowIleight(20);

〃創建節點繪制對象

DefaultTreeCe1IRenderercellRenderer=

(DefaultTreeCellRenderer)tree.getCelIRenderer();

〃設置字體

cellRenderer.setFont(newFont("Serif”,Font.PLAIN,14));

cellRenderer.setBackgroundNonSelectionColor(Color,white);

cellRenderer.setBackgroundSe1ectionCo1or(Co1or.yellow);

cellRenderer.setBorderSe1ectionCo1or(Co1or.red);

〃設置選或不選時,文字的變化顏色

cellRenderer.setTextNonSelectionColor(Color,black);

cellRenderer.setTextSelectionColor(Color,blue);

〃把樹對象添加到內容面板

container,add(newJScrollPane(tree));

〃創建標簽

label=newJLabel("你當前選擇的節點為:〃,JLabeLCENTER);

label.setFont(newFont("Serif”,Font.PLAIN,14));

container,add(label,BorderLayout.SOUTH);

setVisible(true);//設置可見

setDefaultCloseOperation(JFrame.EX1T_ON_CLOSE);〃設置窗口關閉動作

)

〃處理TreeSelectionEvent事件

publicvoidvalueChanged(TreeSelectionEventevent)

(

JTreetree=(JTree)event.getSourceO;

〃獲取目前選取的節點

Defau1tMutab1eTreeNodeselectionNode=

(DefaultMutableTreeNode)tree.getLastSelectedPathComponent();

StringnodeName=selectionNode.toStringO;

label.setText(〃你當前選取的節點為:〃+nodeName);

}

publicstaticvoidmain(Stringargs[])

{

Treed=newTreeO;

}

7.請基于Java使用裝飾模式模擬項目經理接到一個項目,項目最終要完成編碼的工

作。項目經理接到項目后,先做些前期的工作(比如需求分析、設計),然后將編碼工作委

派給程序員,程序員干完后,項目經理做項目的收尾工作。

參考答案:

publicinterfaceProject{

voiddoCodingO;

}

publicclassEmployeimplementsProject{

publicvoiddoCodingO{

System.out.printin("代碼工人在編寫代碼,加班編啊編啊,終于編完了!”);

)

}

publicclassManagerimplementsProject{

privateProjectproject;〃實際上存放的是代碼工人對象

publicManager(Projectproject){

this,project=project;

)

publicvoiddoCoding(){

〃項目經理開始新的工作

startNewWork();

)

/**

*模板:定義項目經理自己的事情

*/

publicvoidstartNewWork0{

〃項目經理在做早期工作

doEarlyWork();

〃項目經理很牛,做完需求和設計后,直接將編碼委派給代碼工人干

project.doCodingO;

〃項目經理在做收尾工作

doEndWork();

)

/**

*項目經理自己的事情:做早期工作

*/

publicvoiddoEarlyWork(){

)

/**

*項目經理做收尾工作

*/

publicvoiddoEndWork(){

}

)

publicclassManagerAextendsManager(

publicManagerA(Projectproject){

super(project);

)

/**

*項目經理自己的事情:做早期工作

*/

publicvoiddoEarlyWork(){

System.out.printin(〃項目經理A在做需求分析〃);

System,out.printin(〃項目經理A在做架構設計“);

System.out.printin(〃項目經理A在做詳細設計〃);

)

)

publicclassManagerBextendsManager{

publicManagerB(Projectproject){

super(project);

)

/**

*項目經理自己的事情:做早期工作

*/

publicvoiddoEarlyWork(){

System.out.println(〃項目經理B在做需求分析“);

System.out.printin("項目經理B在做詳細設計〃);

}

/**

*項目經理做收尾工作

*/

publicvoiddoEndWork(){

System.out.printIn(〃項目經理B在做收尾工作〃);

}

)

publicclassClient{

publicstaticvoidmain(Stringargs[]){

Projectemploye=newEmploye0;//代碼工人

ProjectmanagerA=newManagerA(employe);〃項目經理

ProjectmanagerB=newManagerB(employe);〃項目經理

〃以經理的名義將編碼完成,功勞都是經理的,實際編碼的是工人

managerA.doCodingO;

managerB.doCoding();

)

)

運行結果:

項目經理A在做需求分析

項目經理A在做架構設計

項目經理A在做詳細設計

代碼工人在編寫代碼,加班編啊編啊,終于編完了!

項目經理B在做需求分析

項目經理B在做詳細設計

代碼工人在編寫代碼,加班編啊編啊,終于編完了!

項目經理B在做收尾工作

8.請基于Java通過外觀模式實現在文件柜中尋找文件的管理。文件放在文件柜的第

二個抽屜里,但是它的鑰匙必須從第一個抽屜里獲得。

packagefacade;

classDrawerOne{

publicvoidopen(){

System.out.printin("第一個抽屜被打開了“);

getKey();

)

publicvoidgetKey(){

System.out.printin("得到第二個抽屜的鑰匙”);

)

)

classDrawerTwo{

publicvoidopen(){

System.out.printin("第二個抽屜被打開了");

getFileO;

)

publicvoidgetFileO{

System.out.printin("得到這個重要文件”);

)

)

classDrawerFacade{

DrawerOnedarwerOne=newDrawerOne();

DrawerTwodarwerTwo=newDrawerTwo();

publicvoidopen(){

darwerOne.open();

darwerTwo.open();

)

)

publicclassDrawerClient{

publicstaticvoidmain(String[]args){

I)rawerFacadedrawer=newDrawerFacade();

drawer,open();

)

)

9.一個咖啡店有幾種口味的咖啡(拿鐵、摩卡、卡布奇諾等等),如果這家店接到訂

單要幾十杯咖啡,那么顯然咖啡的口味就可以設置成共享的,而不必為每一杯單獨生成。

請基于Java使用享元模式實現咖啡供應管理。

參考答難:

publicabstractclassOrder{

//執行賣出動作,抽象享元接口

publicabstractvoidsell();

)

publicclassFlavorOrderextendsOrder{

〃具體享元類

publicStringflavor;

//獲取咖啡口味

publicF1avorOrder(Stringflavor){

this,flavor=flavor;

}

?Override

publicvoidsell(){

System,out.printin("賣出一份"+flavor+〃的咖啡。〃);

)

)

importjava.util.IlashMap;

importjava.util.Map;

publicclassFlavorFactory(

privateMap<String,Order>flavorPool=newHashMap<String,Order>();

//靜態工廠,負責生成訂單對象,享元工廠

privatestaticFlavorFactoryflavorFactory=newFlavorFactory();

privateFlavorFactory(){

publicstaticFlavorFactorygetlnstance0{

returnflavorFactory;

)

publicOrdergetOrder(Stringflavor){

Orderorder=null;

if(flavorPool.containsKey(flavor)){〃如果此映射包含指定鍵的映射

關系,則返回true

order=flavorPool.get(flavor);

}else{

order=newFlavorOrder(flavor);

flavorPool.put(flavor,order);

)

returnorder;

)

publicintgetTotalFlavorsMade(){

returnflavorPool.size();

}

}

importjava.util.*;

publicclassClient{

//客戶下的訂單

privatestaticList<Order>orders=newArrayList<Order>();

//訂單對象生成工廠

privatestaticFlavorFactoryflavorFactory;

//增加訂單

privatestaticvoidtakeOrders(Stringflavor){

orders,add(flavorFactory.getOrder(flavor));

)

publicstaticvoidmain(String[]args){

//訂單生成工廠

flavorFactory=FlavorFactory.getlnstance();

//增加訂單

takeOrders("摩卡”);

takeOrders("卡布奇諾");

takeOrders(〃香草星冰樂〃);

takeOrders(“香草星冰樂〃);

takeOrders("拿鐵”);

takeOrders("卡布奇諾");

takeOrders("拿鐵”);

takeOrders("卡布奇諾");

takeOrders("摩卡");

takeOrders("香草星冰樂“);

takeOrders("卡布奇諾”);

takeOrders("摩卡”);

takeOrders("香草星冰樂”);

takeOrders("拿鐵”);

takeOrders("拿鐵”);

//賣咖啡

for(Orderorder:orders){

order,sell();

//打印生成的訂單java對象數量

System,out.printin("\n客戶一共買了+orders.sizeO+"杯咖啡!”);

//打印生成的訂單java對象數量

System,out.printin("共生成了"+flavorFactory.getTotalFlavorsMade()

+“個FlavorOrderjava對象!”);

}

賣出一份摩卡的咖啡。

賣出一份卡布奇諾的咖啡。

賣出一份香草星冰樂的咖啡。

賣出一份香草星冰樂的咖啡。

賣出一份拿鐵的咖啡。

賣出一份卡布奇諾的咖啡。

賣出一份拿鐵的咖啡。

賣出一份卡布奇諾的咖啡。

賣出一份摩卡的咖啡。

賣出一份香草星冰樂的咖啡。

賣出一份卡布奇諾的咖啡。

賣出一份摩卡的咖啡。

賣出一份香草星冰樂的咖啡。

賣出一份拿鐵的咖啡。

賣出一份拿鐵的咖啡。

客戶一共買了15杯咖啡!

共生成了4個FlavorOrderjava對象!

10.一個紅酒廠商是不會直接把紅酒零售客戶的,都是通過代理來完成他的銷售業務

的,而客戶也不用為了喝紅酒而到處找工廠,他只要找到廠商在當地的代理就行了。具體

紅酒工廠在那里,客戶不用關心,代理會幫他處理。請基于Java代理模式實現這個需求。

參考答案:

紅酒代理商和紅酒廠商都有銷售紅酒的職能,可以為他們定義一個共同的抽象主題角色。

/**

*抽象主題角色,定義了真實角色和代理角色的公共接口。

*/

publicinterfaceSellInterface{

publicObjectsell();

)

/**

*真實主題角色,這里指紅酒工廠角色,它實現了SelHnterface接口

*/

publicclassRedWineFactoryimplementsSelllnterface{

publicObjectsell(){

System.out.printin(〃真實主題角色RedWineFactory被調用了〃);

returnnewObject();

)

)

/**

*代理主題角色,這里指紅酒代理商,它除了也要實現了selllnterface接口外,還持有紅

*廠商RedWineFactory對象的引用,從而使它能在調用真實主題前后做一些必要處理。

*/

publicclassRedWineProxyimplementsSellInterface(

〃持有一個RedWineFactory對象的引用

privateRedWineFactoryredWineFactory;

〃銷售總量

privatestaticintsell_count=0;

publicObjectsell(){

if(checkUser()){〃在通過代理主題角色,我們可以在真實主題角色被調用前做

一些諸如權限判斷的事情

Objectobj=redWineFactory.sell();

count++;〃同樣,在調用后我們也可以執行一些額外的動作.

returnobj;

}else(

thrownewRuntimeExceptionO;

)

}

protectedbooleancheckUser(){

//dosomething

returntrue;

)

)

〃測試類主程序

publicclassClient{

publicstaticvoidmain(Stringagr[])

(

SellInterfacesell=newRedWineProxy();

sell.sell();

)

}

11.對于筆記本的CPU評測,當安裝IntelCPU的時候評測分數比較高,而安裝AMDCPU

的時候則評測分數相對低一些,這個是一維影響,而配合上電腦品牌,就是二維影響。請

基于Java實現橋接模式的不同品牌筆記本性能評測。

參考答案:

interfaceCpuAbility{

StringabilityCpuO;

)

classAmdCpuimplementsCpuAbility(

publicStringabilityCpu0{

return〃性能一般〃;

)

}

classIntelCpuimplementsCpuAbility{

publicStringabilityCpu(){

return〃性能較好〃;

)

)

abstractclassAbstractcomputer{

CpuAbilityCpuAbility;

publicAbstractcomputer(CpuAbi1ityCpuAbility){

this.cpuAbi1ity=cpuAbi1ity;

)

publicabstractvoidcheckPcAbility();

}

classLenevoComputerextendsAbstractcomputer(

publicLenevoComputer(CpuAbi1ityCpuAbility){

super(cpuAbi1ity);

?Override

publicvoidcheckPcAbility(){

System,out.printlnC^華碩筆記本CPU性能

〃+super.cpuAbility.abilityCpuO);

}

)

classIswComputerextendsAbstractcomputer(

publicIswComputer(CpuAbilitycpuAbility){

super(cpuAbility);

)

?Override

publicvoidcheckPcAbility(){

System,out.printIn(Z/1BM筆記本CPU性能

/z+super.cpuAbility.abilityCpu());

)

)

〃執行代碼并輸出

publicclassClient{

publicstaticvoidmain(Stringagr[])

(

CpuAbilityability=newIntelCpuO;

Abstractcomputercomputer=newLenevoComputer(ability);

computer.checkPcAbility();

ability=newAdmCpu();//華碩筆記本CPU性能較好

computer=newIswComputer(ability);

computer.checkPcAbi1ity();//IBM筆記本CPU性能一般

)

)

12.文檔編輯是我們日常不可或缺的一項工作,包括顯示文檔、編輯文檔(撤銷、重

做),請基于Java利用命令模式實現文檔編輯任務。

參考答案:

classDocument{//Receiver:請求接收者,負責執行各命令

publicvoiddisplay(){〃顯示命令

System,out.printin("顯示文檔內容“);

)

publicvoidundo(){〃撤消命令

System.out.printin(〃撤銷文檔內容〃);

)

publicvoidredo(){

System,out.printin("重做文檔內容〃);

}

)

interfaceDocumentCommand{"Command:抽象的接口,對多種命令進行抽象

publicvoidexecute();

}

classDisplayCommandimplementsDocumentCommand{〃具體命令,要聚集一個命令接

收對象,并在執行方法中將命令執行轉發給接收者

privateDocumentdocument;

publicDisplayCommand(Documentdoc){

document=doc;

)

?Override

publicvoidexecute(){

document,display();

)

)

classUndoCommandimplementsDocumentCommand{〃具體命令

privateDocumentdocument;

publicUndoCommand(Documentdoc){

document=doc;

}

Override

publicvoidexecute(){

document,undo();

)

)

classRedoCommandimplementsDocumentCommand{〃具體命令

privateDocumentdocument;

publicRedoCommand(Documentdoc){

document=doc;

)

?Override

publicvoidexecute(){

document,redo();

)

}

classDocumentInvoker{//Invoker:命令請求者

privateDisplayCommanddcmd;

privateUndoCommanducmd;

privateRedoCommand_rcmd;

publicDocumentInvoker(DisplayCommanddcmd,UndoCommanducmd,RedoCommand

rcmd){

this._dcmd=dcmd;

this._ucmd=ucmd;

this._rcmd=rcmd;

)

publicvoiddisplay(){〃調用命令對象執行請求,即把命令執行轉發給命令對象

_dcmd.execute();

}

publicvoidundo(){

_ucmd.execute();

)

publicvoidredo(){

_rcmd.execute();

)

/*要對請求進行排隊、調度時可用下面的方式實現

privatejava.util.ArrayList<Command>comList=new

java.util.ArrayList<Command>();

publicvoidaddCommand(Commandcom){

comList.add(com);

)

publicvoidschedulePerformO{

for(Commandco:comList){

co.execute();

}

}

*/

)

publicclassCommandTest{

publicstaticvoidmain(String[]args){

Documentdoc=newDocument();〃客戶端要把接收者對象傳給具體命令對象

DisplayCommanddisplay二newDisplayCommand(doc);

UndoCommandundo=newUndoCommand(doc);

RedoCommandredo=newRedoCommand(doc);

Documentinvokerinvoker=newDocumentinvoker(display,undo,redo);

invoker,display();

invoker,undo();

invoker,redo();

13.軟件項目要求在規定的時間內完成,軟件開發是有工序(Procedure)要求的,例

如首先先由分析設計人員對系統進行分析設計,然后再由程序員進行編碼,最后再由測試

人員對整個

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論