學(xué)一樣?xùn)|西,自己另外舉個(gè)例子實(shí)現(xiàn)一遍,才能知道里面的原理.記錄一下學(xué)習(xí)的幾種基本的設(shè)計(jì)模式
文件結(jié)構(gòu)
幾種設(shè)計(jì)模式的文件結(jié)構(gòu)如下圖所示
目錄結(jié)構(gòu)圖
源代碼下載
源碼下載
代理模式
說(shuō)明
這里我舉了一個(gè)網(wǎng)頁(yè)渲染時(shí)使用代理延遲加載圖片的例子,用線程的睡眠模擬延遲加載,hibernate的延遲加載就是用了代理模式實(shí)現(xiàn)
代理模式的主要應(yīng)用:
- 遠(yuǎn)程代理,例如webservice
- 虛擬代理,html渲染
- 安全代理,控制真實(shí)對(duì)象的訪問(wèn)權(quán)限
spring的AOP就是用的代理模式的思想設(shè)計(jì)實(shí)現(xiàn)的
類(lèi)圖
UML類(lèi)圖
代碼
package codeDesign.proxy;
/**
* Created by kangbiao on 2015/11/22.
* 網(wǎng)頁(yè)繪制接口,代理和被代理類(lèi)均實(shí)現(xiàn)該接口
*/
public interface Draw {
/**
* 繪制圖片啸澡,需要花很多時(shí)間碟狞,使用代理來(lái)繪制
* @param url
*/
void drawPicture(String url);
}
package codeDesign.proxy;
/**
* Created by kangbiao on 2015/11/22.
* 繪制html網(wǎng)頁(yè)的類(lèi)(該類(lèi)會(huì)消耗很多時(shí)間)
*/
public class HtmlDraw implements Draw{
/**
* 該方法不耗時(shí),不需要代理
* @param text
*/
public void drawText(String text) {
System.out.println("正在繪制文字:" + text);
}
/**
* 會(huì)消耗一定的時(shí)間携茂,需要代理
* @param url
*/
@Override
public void drawPicture(String url) {
System.out.println("圖片區(qū)域正在從遠(yuǎn)程加載圖片");
try {
Thread.sleep(5000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("正在繪制圖片:"+url);
}
}
package codeDesign.proxy;
/**
* Created by kangbiao on 2015/11/22.
* 圖片繪制代理類(lèi)
*/
public class ProxyDraw implements Draw {
HtmlDraw htmlDraw;
public ProxyDraw(){
this.htmlDraw=new HtmlDraw();
}
@Override
public void drawPicture(String url) {
System.out.println("代理先輸出一張占位圖片");
new Thread(new Runnable() {
@Override
public void run() {
htmlDraw.drawPicture("1.jpg");
System.out.println("代理去掉占位圖片");
}
}).start();
}
}
package codeDesign.proxy;
/**
* Created by kangbiao on 2015/11/22.
* 代理模式測(cè)試類(lèi)
*/
public class ProxyTest {
/**
* 該過(guò)程演示了網(wǎng)頁(yè)的繪制過(guò)程拳锚,使用代理模式異步繪制網(wǎng)頁(yè)上面的圖片
* @param args
*/
public static void main(String[] args){
HtmlDraw htmlDraw=new HtmlDraw();
htmlDraw.drawText("文字1");
ProxyDraw proxyDraw=new ProxyDraw();
proxyDraw.drawPicture("1.jpg");
htmlDraw.drawText("文字2");
}
}
工廠模式
說(shuō)明
最基礎(chǔ)的設(shè)計(jì)模式
類(lèi)圖
工廠模式UML類(lèi)圖
代碼
package codeDesign.factory;
/**
* Created by kangbiao on 2015/11/21.
*
*/
public class Tea {
private String sugar;
public void mixSugarTea(){
System.out.print("只有"+sugar);
}
public String getSugar()
{
return sugar;
}
public void setSugar(String sugar)
{
this.sugar = sugar;
}
}
package codeDesign.factory;
/**
* Created by kangbiao on 2015/11/21.
* 藍(lán)茶
*/
public class BlueTea extends Tea{
public void mixSugarTea(){
System.out.print(super.getSugar()+"藍(lán)茶");
}
}
package codeDesign.factory;
/**
* Created by kangbiao on 2015/11/21.
* 紅茶
*/
public class BlackTea extends Tea{
public void mixSugarTea(){
System.out.print(super.getSugar()+"紅茶");
}
}
package codeDesign.factory;
/**
* Created by kangbiao on 2015/11/21.
* 茶的工廠類(lèi)
*/
public class TeaFactory {
public static Tea getTea(String teaType){
Tea tea;
switch (teaType){
case "black":
tea=new BlackTea();
break;
case "blue":
tea=new BlueTea();
break;
default:
tea=new Tea();
break;
}
return tea;
}
}
package codeDesign.factory;
/**
* Created by kangbiao on 2015/11/21.
* 工廠模式測(cè)試
*/
public class FactoryTest {
public static void main(String[] args){
Tea tea = TeaFactory.getTea("black");
tea.setSugar("紅糖");
tea.mixSugarTea();
}
}
裝飾器模式
說(shuō)明
- 如果只有一個(gè)Concrete Component類(lèi)而沒(méi)有抽象的Component接口時(shí)叹洲,可以讓Decorator繼承Concrete Component糜芳。
- 如果只有一個(gè)Concrete Decorator類(lèi)時(shí),可以將Decorator和Concrete Decorator合并妖枚。
- java的io流包就是使用的裝飾器模式
類(lèi)圖
裝飾器模式UML類(lèi)圖
代碼
package codeDesign.decorator;
/**
* Created by kangbiao on 2015/11/21.
* 汽車(chē)類(lèi)
*/
public class Car {
public void showFunc(){
System.out.print("組裝完畢");
}
}
package codeDesign.decorator;
/**
* Created by kangbiao on 2015/11/21.
* 汽車(chē)的功能類(lèi)
*/
public class Function extends Car{
protected Car car;
public void addFuncs(Car car){
this.car=car;
}
public void showFunc(){
if (car!=null){
car.showFunc();
}
}
}
package codeDesign.decorator;
/**
* Created by kangbiao on 2015/11/21.
* 制動(dòng)功能
*/
public class BrakingFunction extends Function{
public void showFunc(){
System.out.print("制動(dòng)");
super.showFunc();
}
}
package codeDesign.decorator;
/**
* Created by kangbiao on 2015/11/21.
* ABS防抱死功能
*/
public class ABSFunction extends Function{
public void showFunc(){
System.out.print("ABS");
super.showFunc();
}
}
package codeDesign.decorator;
/**
* Created by kangbiao on 2015/11/21.
* 裝飾模式測(cè)試
*/
public class DecoratorTest {
public static void main(String[] args){
Car car=new Car();
ABSFunction abs=new ABSFunction();
BrakingFunction braking=new BrakingFunction();
abs.addFuncs(car);
braking.addFuncs(abs);
braking.showFunc();
}
}
策略模式
說(shuō)明
這里我結(jié)合了工廠模式,使得加密算法的選擇邏輯不用暴露給客戶端
Strategy中定義了公共算法的實(shí)現(xiàn)接口,然后通過(guò)多態(tài)在Context動(dòng)態(tài)的創(chuàng)建不同的實(shí)現(xiàn)類(lèi)的實(shí)例從而達(dá)到算法策略選擇邏輯
簡(jiǎn)化單元測(cè)試,因?yàn)槊恳粋€(gè)具體的實(shí)現(xiàn)都在一個(gè)類(lèi)里面,可以分開(kāi)測(cè)試
減少了算法調(diào)用類(lèi)和算法實(shí)現(xiàn)類(lèi)之間的耦合
類(lèi)圖
策略模式UML類(lèi)圖
代碼
package codeDesign.strategy;
/**
* Created by kangbiao on 2015/11/21.
* 加密算法接口
*/
public interface EncryptStrategy {
/**
* 加密算法實(shí)現(xiàn)接口
* @param rawString
* @return
*/
String doEncrypt(String rawString);
}
package codeDesign.strategy;
/**
* Created by kangbiao on 2015/11/21.
* md5加密策略實(shí)現(xiàn)類(lèi)
*/
public class MD5Strategy implements EncryptStrategy{
@Override
public String doEncrypt(String rawString) {
return "MD5("+rawString+")";
}
}
package codeDesign.strategy;
/**
* Created by kangbiao on 2015/11/21.
* SHA1加密實(shí)現(xiàn)類(lèi)
*/
public class SHA1Strategy implements EncryptStrategy {
@Override
public String doEncrypt(String rawString) {
return "SHA1("+rawString+")";
}
}
package codeDesign.strategy;
/**
* Created by kangbiao on 2015/11/21.
* 加密上下文維護(hù)類(lèi)廷臼,客戶端調(diào)用類(lèi)
*/
public class EncryptContext {
private EncryptStrategy encryptStrategy;
public final static byte MD5=0;
public final static byte SHA1=1;
/**
* 這里實(shí)現(xiàn)用工廠模式實(shí)現(xiàn)自動(dòng)裝載不同的類(lèi)
* @param method
*/
public EncryptContext(Byte method){
switch (method){
case MD5:
this.encryptStrategy=new MD5Strategy();
break;
case SHA1:
this.encryptStrategy=new SHA1Strategy();
break;
default:
break;
}
}
public String doEncrypt(String rawString){
return encryptStrategy.doEncrypt(rawString);
}
}
package codeDesign.strategy;
/**
* Created by kangbiao on 2015/11/21.
* 策略模式測(cè)試類(lèi)
*/
public class EncryptTest {
public static void main(String[] args){
EncryptContext encryptContext=new EncryptContext(EncryptContext.MD5);
String result=encryptContext.doEncrypt("123456");
System.out.print(result);
}
}