java的設計模式大體上分爲三大類(個人理解):
*創建型模式(4種):工廠模式,單例模式,建造者模式,原型模式
*結構型模式(7種):適配器模式,裝飾器模式,代理模式,外觀模式,橋接模式,組合模式,享元模式
*行爲型模式(11種):策略模式、模板方法模式、觀察者模式、迭代子模式、責任鏈模式、命令模式、備忘錄模式、狀態模式、訪問者模式、中介者模式、解釋器模式
設計模式遵循的6個原則:
1、開閉原則
對擴展開放,對修改關閉
2、里氏代換原則
只有當衍生類可以替換掉基類,軟件單位的功能不受到影響時,基類才能真正被複用,而衍生類也能夠在基類的基礎上增加新的行爲
3、依賴倒轉原則
這個是開閉原則的基礎,對接口編程,依賴於抽象而不依賴於具體。
4、接口隔離原則
使用多個隔離的藉口來降低耦合度。
5、迪米特法則(最少知道原則)
一個實體應當儘量少的與其他實體之間發生相互作用,使得系統功能模塊相對獨立。
6、合成複用原則
原則是儘量使用合成/聚合的方式,而不是使用繼承。繼承實際上破壞了類的封裝性,超類的方法可能會被子類修改。
一、工廠模式(Factory)
實例1:追MM少不了請吃飯了,麥當勞的雞翅和肯德基的雞翅都是MM愛吃的東西,雖然口味有所不同,但不管你帶MM去麥當勞或肯德基,只管向服務員說“來四個雞翅”就行了。麥當勞和肯德基就是生產雞翅的Factory 。
public class Factory{
public static Sample creator(int which){
//getClass 產生Sample 一般可使用動態類裝載裝入類。
if (which== 1)
return new SampleA();
else if (which== 2)
return new SampleB();
}
}
1
2
3
4
5
6
7
8
9
實例2:請MM去麥當勞吃漢堡,不同的MM有不同的口味,要每個都記住是一件煩人的事情,我一般採用Factory Method模式,帶着MM到服務員那兒,說“要一個漢堡”,具體要什麼樣的漢堡呢,讓MM直接跟服務員說就行了。
public abstract class Factory{
public abstract Sample creator();
}
public class AFactory extends Factory{
public Sample creator(){
.........
return new SampleA ();
}
}
public class BFactory extends Factory{
public Sample creator(){
.........
return new SampleB ();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
二、建造模式(Builder)
實例:MM最愛聽的就是“我愛你”這句話了,見到不同地方的MM,要能夠用她們的方言跟她說這句話哦,我有一個多種語言翻譯機,上面每種語言都有一個按鍵,見到MM我只要按對應的鍵,它就能夠用相應的語言說出“我愛你”這句話了,國外的MM也可以輕鬆搞掂,這就是我的“我愛你”builder。
public interface Builder {
//創建部件A 比如創建汽車車輪
void buildPartA();
//創建部件B 比如創建汽車方向盤
void buildPartB();
//創建部件C 比如創建汽車發動機
void buildPartC();
//返回最後組裝成品結果 (返回最後裝配好的汽車)
//成品的組裝過程不在這裏進行,而是轉移到下面的Director類別中進行。
//從而實現瞭解耦過程和部件
Product getResult();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Director {
private Builder builder;
public Director( Builder builder ) {
this.builder = builder;
}
// 將部件partA partB partC最後組成複雜物件
//這裏是將車輪 方向盤和發動機組裝成汽車的過程
public void construct() {
builder.buildPartA();
builder.buildPartB();
builder.buildPartC();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
三、原始模型模式(Prototype)
實例:跟MM用QQ聊天,一定要說些深情的話語了,我搜集了好多肉麻的情話,需要時只要copy出來放到QQ裏面就行了,這就是我的情話prototype了。
public abstract class AbstractSpoon implements Cloneable {
String spoonName;
public void setSpoonName(String spoonName) {
this.spoonName = spoonName;
}
public String getSpoonName() {
return this.spoonName;
}
public Object clone() {
Object object = null;
try {
object = super.clone();
} catch (CloneNotSupportedException exception) {
System.err.println("AbstractSpoon is not Cloneable");
}
return object;
}
}
public class SoupSpoon extends AbstractSpoon {
public SoupSpoon(){
setSpoonName("Soup Spoon");
}
}
public class SaladSpoon extends AbstractSpoon {
public SoupSpoon(){
setSpoonName("Salad Spoon");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
四、單例模式(Singleton)
1、一個類只有一個實例
2、提供一個全局訪問點
3、禁止拷貝
public class Singleton {
private static Singleton instance = null;
public static synchronized Singleton getInstance() {
if (instance==null)
instance=new Singleton();
return instance;
}
}
1
2
3
4
5
6
7
8
9
五、適配器(Adapter)
實例:在朋友聚會上碰到了一個美女Sarah,從香港來的,可我不會說粵語,她不會說普通話,只好求助於我的朋友kent了,他作爲我和Sarah之間的Adapter,讓我和Sarah可以相互交談了。
public interface IRoundPeg{
public void insertIntoHole(String msg);
}
public interface ISquarePeg{
public void insert(String str);
}
public class PegAdapter implements IRoundPeg,ISquarePeg{
private RoundPeg roundPeg;
private SquarePeg squarePeg;
// 構造方法1
public PegAdapter(RoundPeg peg){
this.roundPeg=peg;
}
// 構造方法 2
public PegAdapter(SquarePeg peg)(
this.squarePeg=peg;
}
public void insert(String str){
roundPeg.insertIntoHole(str);
}
public void insertIntoHole(String str){
SquarePeg.insert(str);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
六、橋樑模式(Bridge)
實例:早上碰到MM,要說早上好,晚上碰到MM,要說晚上好;碰到MM穿了件新衣服,要說你的衣服好漂亮哦,碰到MM新做的髮型,要說你的頭髮好漂亮哦。不要問我“早上碰到MM新做了個髮型怎麼說”這種問題,自己用BRIDGE組合一下不就行了 。
public abstract class Coffee {
CoffeeImp coffeeImp;
public void setCoffeeImp() {
this.CoffeeImp = CoffeeImpSingleton.getTheCoffeImp();
}
public SodaImp getCoffeeImp() {
return this.CoffeeImp;
}
public abstract void pourCoffee();
}
public abstract class CoffeeImp {
public abstract void pourCoffeeImp();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//bridge
public class CoffeeImpSingleton {
private static CoffeeImp coffeeImp;
public CoffeeImpSingleton(CoffeeImp coffeeImpIn){
this.coffeeImp = coffeeImpIn;
}
public static CoffeeImp getTheCoffeeImp() {
return coffeeImp;
}
}
1
2
3
4
5
6
7
8
9
10
七、合成模式(Composite)
實例:Mary今天過生日。“我過生日,你要送我一件禮物。”“嗯,好吧,去商店,你自己挑。”“這件T恤挺漂亮,買,這條裙子好看,買,這個包也不錯,買。”“喂,買了三件了呀,我只答應送一件禮物的哦。”“什麼呀,T恤加裙子加包包,正好配成一套呀,小姐,麻煩你包起來。”“……”,MM都會用Composite模式了,你會了沒有?
public abstract class Equipment {
private String name;
public abstract double netPrice();
public abstract double discountPrice();
//增加部件方法
public boolean add(Equipment equipment) {
return false;
}
//刪除部件方法
public boolean remove(Equipment equipment) {
return false;
}
1
2
3
4
5
6
7
8
9
10
11
12
//注意這裏,這裏就提供一種用於訪問組合體類別的部件方法。
public Iterator iter() {
return null;
}
public Equipment(final String name) {
this.name=name;
}
}
1
2
3
4
5
6
7
8
八、裝飾模式(Decorator)
實例:Mary過完輪到Sarly過生日,還是不要叫她自己挑了,不然這個月伙食費肯定玩完,拿出我去年在華山頂上照的照片,在背面寫上“最好的的禮物,就是愛你的Fita”,再到街上禮品店買了個像框(賣禮品的MM也很漂亮哦),再找隔壁搞美術設計的Mike設計了一個漂亮的盒子裝起來……,我們都是Decorator,最終都在修飾我這個人呀,怎麼樣,看懂了嗎?
public interface Work {
public void insert();
}
public class SquarePeg implements Work{
public void insert(){
System.out.println("方形樁插入");
}
}
public class Decorator implements Work{
private Work work; //額外增加的功能被打包在這個List中
private ArrayList others = new ArrayList();
//在構造器中使用組合new方式,引入Work物件;
public Decorator(Work work) {
this.work=work;
others.add("挖坑");
others.add("釘木板");
}
public void insert(){
newMethod();
}
//在新方法中,我們在insert之前增加其他方法,這裏次序先後是用戶靈活指定的
public void newMethod(){
otherMethod();
work.insert();
}
public void otherMethod(){
ListIterator listIterator = others.listIterator();
while (listIterator.hasNext()){
System.out.println(((String)(listIterator.next())) + " 正在進行");
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
九、門面模式(Facade)
實例:我有一個專業的Nikon相機,我就喜歡自己手動調光圈、快門,這樣照出來的照片才專業,但MM可不懂這些,教了半天也不會。幸好相機有Facade設計模式,把相機調整到自動檔,只要對準目標按快門就行了,一切由相機自動調整,這樣MM也可以用這個相機給我拍張照片了。
public class DBCompare {
String sql = "SELECT * FROM <table> WHERE <column name> = ?";
try {
Mysql msql=new mysql(sql);
prep.setString( 1, "<column value>" );
rset = prep.executeQuery();
if( rset.next() ) {
System.out.println( rset.getString( "<column name" ));
}
} catch( SException e ) {
e.printStackTrace();
} finally {
mysql.close();
mysql=null;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
十、享元模式(Flyweight)
實例:每天跟MM發短信,手指都累死了,最近買了個新手機,可以把一些常用的句子存在手機裏,要用的時候,直接拿出來,在前面加上MM的名字就可以發送了,再不用一個字一個字敲了。共享的句子就是Flyweight,MM的名字就是提取出來的外部特徵,根據上下文情況使用。
public class CD {
private String title;
private int year;
private Artist artist;
public String getTitle() {
return title;
}
public int getYear() {
return year;
}
public Artist getArtist() {
return artist;
}
public void setTitle(String t){
title = t;
}
public void setYear(int y){
year = y;
}
public void setArtist(Artist a){
artist = a;
}
}
public class Artist {
//內部狀態
private String name;
// note that Artist is immutable.
String getName(){
return name;
}
Artist(String n){
name = n;
}
}
public class ArtistFactory {
Hashtable pool = new Hashtable();
Artist getArtist(String key){
Artist result;
result = (Artist)pool.get(key);
////産生新的Artist
if(result == null) {
result = new Artist(key);
pool.put(key,result);
}
return result;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
十一、代理模式(Proxy)
實例:跟MM在網上聊天,一開頭總是“hi,你好”,“你從哪兒來呀?”“你多大了?”“身高多少呀?”這些話,真煩人,寫個程序做爲我的Proxy吧,凡是接收到這些話都設置好了自動的回答,接收到其他的話時再通知我回答。
public class ForumPermissions implements Cacheable;
public class ForumProxy implements Forum;
public class DbForum implements Forum, Cacheable
1
2
3
4
5
十二、職責鏈(Chain of Responsibility)
實例:晚上去上英語課,爲了好開溜坐到了最後一排,哇,前面坐了好幾個漂亮的MM哎,找張紙條,寫上“Hi,可以做我的女朋友嗎?如果不願意請向前傳”,紙條就一個接一個的傳上去了,糟糕,傳到第一排的MM把紙條傳給老師了,聽說是個老處女呀,快跑!
public interface Handler{
public void handleRequest(Request request);
}
public class Request{
private String type;
public Request(String type){this.type=type;}
public String getType(){return type;}
public void execute(){
//request真正具體行爲代碼
}
}
public class ConcreteHandler implements Handler{
private Handler successor;
public ConcreteHandler(Handler successor){
this.successor=successor;
}
public void handleRequest(Request request){
if (request instanceof HelpRequest){
//這裏是處理Help的具體代碼
}else if (request instanceof PrintRequst){
request.execute();
}else
//傳遞到下一個
successor.handle(request);
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
十三、命令模式(Command)
實例:俺有一個MM家裏管得特別嚴,沒法見面,只好藉助於她弟弟在我們倆之間傳送信息,她對我有什麼指示,就寫一張紙條讓她弟弟帶給我。這不,她弟弟又傳送過來一個COMMAND,爲了感謝他,我請他吃了碗雜醬麪,哪知道他說:“我同時給我姐姐三個男朋友送COMMAND,就數你最小氣,才請我吃麪。”
public interface Command {
public abstract void execute ( );
}
public class producer{
public static List produceRequests() {
List queue = new ArrayList();
queue.add( new DomesticEngineer() );
queue.add( new Politician() );
queue.add( new Programmer() );
return queue;
}
}
public class TestCommand {
public static void main(String[] args) {
List queue = Producer.produceRequests();
for (Iterator it = queue.iterator(); it.hasNext(); )
//取出List中東東,其他特徵都不能確定,只能保證一個特徵是100%正確,
// 他們至少是介面Command的"兒子"。所以強制轉換類別型爲介面Command
((Command)it.next()).execute();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
十四、解釋器模式(Interpreter)
實例:俺有一個《泡MM真經》,上面有各種泡MM的攻略,比如說去吃西餐的步驟、去看電影的方法等等,跟MM約會時,只要做一個Interpreter,照着上面的腳本執行就可以了。
十五、迭代子模式(Iterator)
實例:
我愛上了Mary,不顧一切的向她求婚。
Mary:“想要我跟你結婚,得答應我的條件”
我:“什麼條件我都答應,你說吧”
Mary:“我看上了那個一克拉的鑽石”
我:“我買,我買,還有嗎?”
Mary:“我看上了湖邊的那棟別墅”
我:“我買,我買,還有嗎?”
Mary:“我看上那輛法拉利跑車”
我腦袋嗡的一聲,坐在椅子上,一咬牙:“我買,我買,還有嗎?”
//用來遍曆Collection中物件
public class TestCommand {
public static void main(String[] args) {
List queue = Producer.produceRequests();
for (Iterator it = queue.iterator(); it.hasNext(); )
//取出List中東東,其他特徵都不能確定,只能保證一個特徵是100%正確,
// 他們至少是介面Command的"兒子"。所以強制轉換類別型爲介面Command
((Command)it.next()).execute();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
十六、調停者模式(Mediator)
實例:四個MM打麻將,相互之間誰應該給誰多少錢算不清楚了,幸虧當時我在旁邊,按照各自的籌碼數算錢,賺了錢的從我這裏拿,賠了錢的也付給我,一切就OK啦,俺得到了四個MM的電話。
public interface Mediator { }
public class ConcreteMediator implements Mediator { //假設當前有兩個成員.
private ConcreteColleague1 colleague1 = new ConcreteColleague1();
private ConcreteColleague2 colleague2 = new ConcreteColleague2();
... }
public class Colleague {
private Mediator mediator;
public Mediator getMediator() {
return mediator;
}
public void setMediator( Mediator mediator ) {
this.mediator = mediator;
}
}
public class ConcreteColleague1 { }
public class ConcreteColleague2 { }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
十七、備忘錄模式(Memento)
實例:同時跟幾個MM聊天時,一定要記清楚剛纔跟MM說了些什麼話,不然MM發現了會不高興的哦,幸虧我有個備忘錄,剛纔與哪個MM說了什麼話我都拷貝一份放到備忘錄裏面保存,這樣可以隨時察看以前的記錄啦。
public class Originator {
private int number;
private File file = null;
public Originator(){} // 創建一個Memento
public Memento getMemento(){
return new Memento(this);
} // 恢復到原始值
public void setMemento(Memento m){
number = m.number;
file = m.file;
}
}
private class Memento implements java.io.Serializable{
private int number;
private File file = null;
public Memento( Originator o){
number = o.number;
file = o.file;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
十八、觀察者模式(Obserber)
實例:想知道咱們公司最新MM情報嗎?加入公司的MM情報郵件組就行了,tom負責蒐集情報,他發現的新情報不用一個一個通知我們,直接發佈給郵件組,我們作爲訂閱者(觀察者)就可以及時收到情報啦 。
public class product extends Observable{
private String name;
private float price;
public String getName(){ return name;}
public void setName(){
this.name=name;
//設置變化點
setChanged();
notifyObservers(name);
}
}
public class NameObserver implements Observer{ private String name=null;
public void update(Observable obj,Object arg){
if (arg instanceof String){
name=(String)arg;
//産品名稱改變值在name中
System.out.println("NameObserver :name changet to "+name);
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
十九、狀態模式(State)
實例:跟MM交往時,一定要注意她的狀態哦,在不同的狀態時她的行爲會有不同,比如你約她今天晚上去看電影,對你沒興趣的MM就會說“有事情啦”,對你不討厭但還沒喜歡上的MM就會說“好啊,不過可以帶上我同事麼?”,已經喜歡上你的MM就會說“幾點鐘?看完電影再去泡吧怎麼樣?”,當然你看電影過程中表現良好的話,也可以把MM的狀態從不討厭不喜歡變成喜歡哦。
public class BlueState extends State{
public void handlepush(Context c){
//根據push方法"如果是blue狀態的切換到green" ;
c.setState(new GreenState());
}
public void handlepull(Context c){
//根據pull方法"如果是blue狀態的切換到red" ;
c.setState(new RedState());
}
public abstract void getcolor(){ return (Color.blue)}
}
public class Context{
private Sate state=null; //我們將原來的 Color state 改成了新建的State state;
//setState是用來改變state的狀態 使用setState實現狀態的切換
pulic void setState(State state){
this.state=state;
}
public void push(){
//狀態的切換的細節部分,在本例中是顔色的變化,已經封裝在子類別的handlepush中實現,這裏無需關心
state.handlepush(this);
//因爲sample要使用state中的一個切換結果,使用getColor()
Sample sample=new Sample(state.getColor());
sample.operate();
}
public void pull(){
state.handlepull(this);
Sample2 sample2=new Sample2(state.getColor());
sample2.operate();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
二十、策略模式(Strategy)
實例:跟不同類型的MM約會,要用不同的策略,有的請電影比較好,有的則去吃小吃效果不錯,有的去海邊浪漫最合適,單目的都是爲了得到MM的芳心,我的追MM錦囊中有好多Strategy哦。
public abstract class RepTempRule{
protected String oldString="";
public void setOldString(String oldString){
this.oldString=oldString;
}
protected String newString="";
public String getNewString(){
return newString;
}
public abstract void replace() throws Exception;
}
public class test{ ......
public void testReplace(){ //使用第一套方案進行替換。
RepTempRule rule=new RepTempRuleOne();
rule.setOldString(record);
rule.replace(); }.....
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
二十一、模板方法模式(Template Method)
實例:追MM聖經規定了追MM在不同時期有不同的步驟(Template method),但每個步驟針對不同的情況,都有不一樣的做法,這就要看你隨機應變啦(具體實現);
public abstract class Benchmark
{
/**
* 下面操作是我們希望在子類別中完成
*/
public abstract void benchmark(); /**
* 重復執行benchmark次數
*/
public final long repeat (int count) {
if (count <= 0)
return 0;
else {
long startTime = System.currentTimeMillis();
for (int i = 0; i < count; i++)
benchmark();
long stopTime = System.currentTimeMillis();
return stopTime - startTime;
}
}
}
public class MethodBenchmark extends Benchmark
{
/**
* 真正定義benchmark內容
*/
public void benchmark() {
for (int i = 0; i < Integer.MAX_VALUE; i++){
System.out.printtln("i="+i);
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
二十二、訪問者模式(Visitor)
實例:情人節到了,要給每個MM送一束鮮花和一張卡片,可是每個MM送的花都要針對她個人的特點,每張卡片也要根據個人的特點來挑,我一個人哪搞得清楚,還是找花店老闆和禮品店老闆做一下Visitor,讓花店老闆根據MM的特點選一束花,讓禮品店老闆也根據每個人特點選一張卡,這樣就輕鬆多了。
public interface Visitable
{
public void accept(Visitor visitor);
}
public class ConcreteVisitor implements Visitor
{
//在本方法中,我們實現了對Collection的元素的成功訪問
public void visitCollection(Collection collection) {
Iterator iterator = collection.iterator()
while (iterator.hasNext()) {
Object o = iterator.next();
if (o instanceof Visitable)
((Visitable)o).accept(this);
} public void visitString(String string) {
System.out.println("'"+string+"'");
}
public void visitFloat(Float float) {
System.out.println(float.toString()+"f");
}
---------------------
作者:Armymans
來源:CSDN
原文:https://blog.csdn.net/qq_43652509/article/details/84755072
版權聲明:本文爲博主原創文章,轉載請附上博文鏈接!