單例模式闸天、簡單工廠模式、工廠方法模式斜做、抽象工廠模式苞氮、建造者模式、原型模式
一瓤逼、單例模式
作用:保證一個(gè)類只有一個(gè)實(shí)例笼吟,并且提供一個(gè)訪問該實(shí)例的全局訪問點(diǎn)。
五種寫法:餓漢模式抛姑、懶漢模式赞厕、雙重檢測鎖、靜態(tài)內(nèi)部類實(shí)現(xiàn)延遲加載定硝、枚舉類實(shí)現(xiàn)單例(不細(xì)講了,具體參考我的另一篇文章http://www.reibang.com/p/e86833bee429)
二毫目、簡單工廠模式
2.1蔬啡、作用:用來生產(chǎn)同一等級(jí)結(jié)構(gòu)中的任意產(chǎn)品诲侮。(對于增加新的產(chǎn)品,需要修改已有代碼)
2.2箱蟆、缺點(diǎn):對于增加新產(chǎn)品無能為力沟绪!不修改代碼的話,是無法擴(kuò)展的空猜,不完全滿足開閉原則(如下面的例子绽慈,如果再增加華為電腦,則必須修改工廠類的代碼)
2.3辈毯、UML圖:
2.4坝疼、示例:
//電腦接口
public interface Computer {
public void play();
}
//聯(lián)想電腦類
class LenovoComputer implements Computer{
public void play() {
System.out.println("我是聯(lián)想電腦");
}
}
//蘋果電腦類
class MacComputer implements Computer{
public void play() {
System.out.println("我是蘋果電腦");
}
}
--------------------------------------------------------------------------------
//簡單工廠類,類方法一般為靜態(tài)的谆沃,所以也稱為靜態(tài)工廠
public class SimpleFactory {
public static Computer createComputer(String type){
if(type.equalsIgnoreCase("mac")){
return new MacComputer();
}else{
return new LenovoComputer();
}
}
public static Computer createLenovoComputer(){
return new LenovoComputer();
}
public static Computer createMacComputer(){
return new MacComputer();
}
}
--------------------------------------------------------------------------------
//客戶端
public class Client {
public static void main(String[] args) {
SimpleFactory simpleFactory = new SimpleFactory();
Computer c1 = simpleFactory.createComputer("mac");
Computer c2 = simpleFactory.createLenovoComputer();
c1.play();
c2.play();
}
}
三钝凶、工廠方法模式
3.1、作用:為了避免簡單工廠模式的缺點(diǎn)唁影,不完全滿足開閉原則耕陷,而設(shè)計(jì)的。工廠方法模式和簡單工廠模式最大的不同在于据沈,簡單工廠模式只有一個(gè)(對于一個(gè)項(xiàng)目或者一個(gè)獨(dú)立模塊而言)工廠類哟沫,而工廠方法模式有一組實(shí)現(xiàn)了相同接口的工廠類
3.2、缺點(diǎn):除了是滿足開閉原則外锌介,從結(jié)構(gòu)復(fù)雜度南用、代碼復(fù)雜的、客戶端編程難度掏湾、管理上的難度上看裹虫,工廠方法相比簡單工廠都要復(fù)雜,所以實(shí)際上融击,我們一般只會(huì)用簡單工廠筑公,很少會(huì)用到工廠方法模式
3.3、UML圖:
3.4尊浪、示例:
//電腦接口
public interface Computer {
public void play();
}
//聯(lián)想電腦類
class LenovoComputer implements Computer{
public void play() {
System.out.println("我是聯(lián)想電腦");
}
}
//蘋果電腦類
class MacComputer implements Computer{
public void play() {
System.out.println("我是蘋果電腦");
}
}
--------------------------------------------------------------------------------
//工廠接口
public interface FactoryMethod {
public Computer createComputer();
}
//聯(lián)想工廠
class LenovoComputerFactory implements FactoryMethod{
public Computer createComputer() {
return new LenovoComputer();
}
}
//蘋果工廠
class MacComputerFactory implements FactoryMethod{
public Computer createComputer() {
return new MacComputer();
}
}
--------------------------------------------------------------------------------
//客戶端
public class Client {
public static void main(String[] args) {
FactoryMethod factory1 = new LenovoComputerFactory();
FactoryMethod factory2 = new MacComputerFactory();
LenovoComputer c1 = (LenovoComputer) factory1.createComputer();
MacComputer c2 = (MacComputer) factory2.createComputer();
c1.play();
c2.play();
}
}
結(jié)論:由此看出匣屡,如果再加入一個(gè)華為的電腦,只需加入一個(gè)華為電腦的類和一個(gè)華為電腦工廠就可以了拇涤,不需要修改之前的任何代碼捣作,因此滿足了開閉原則
四、抽象工廠模式
4.1鹅士、作用:用來生產(chǎn)不同產(chǎn)品族的全部產(chǎn)品券躁,在有多個(gè)業(yè)務(wù)品種、業(yè)務(wù)分類時(shí),通過抽象工廠模式產(chǎn)生需要的對象是一種非常好的解決方式也拜。
4.2以舒、缺點(diǎn):對于增加新的產(chǎn)品,無能為力慢哈;支持增加產(chǎn)品族(如在下面例子中蔓钟,若再加入華為電腦,則需要新增華為電腦工廠類卵贱,并要修改每一個(gè)配件類滥沫,去新增產(chǎn)品配件,因此就不能滿足開閉原則了)
4.3键俱、UML圖:
4.4兰绣、示例:
//電腦類
public class Computer {
private Engine engine;
private Keyboard keyboard;
private Mouse mouse;
public Engine getEngine() {
return engine;
}
public void setEngine(Engine engine) {
this.engine = engine;
}
public Keyboard getKeyboard() {
return keyboard;
}
public void setKeyboard(Keyboard keyboard) {
this.keyboard = keyboard;
}
public Mouse getMouse() {
return mouse;
}
public void setMouse(Mouse mouse) {
this.mouse = mouse;
}
public void play(){
System.out.println(engine.getName()+keyboard.getName()+mouse.getName());
};
}
//引擎類(為了簡潔,此處沒有用到接口方妖,直接用名字代表不同的對象)
class Engine{
private String name;
public Engine(String name){this.name=name;}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
//鍵盤類(為了簡潔狭魂,此處沒有用到接口,直接用名字代表不同的對象)
class Keyboard{
private String name;
public Keyboard(String name){this.name=name;}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
//鼠標(biāo)類(為了簡潔党觅,此處沒有用到接口雌澄,直接用名字代表不同的對象)
class Mouse{
private String name;
public Mouse(String name){this.name=name;}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
--------------------------------------------------------------------------------
//抽象工廠接口
public interface AbstractFactory {
public Computer createComputer();
}
//聯(lián)想電腦工廠
class LenovoComputerFactory implements AbstractFactory{
public Computer createComputer() {
Computer c = new Computer();
c.setEngine(new Engine("聯(lián)想CPU"));
c.setKeyboard(new Keyboard("聯(lián)想鍵盤"));
c.setMouse(new Mouse("聯(lián)想鼠標(biāo)"));
return c;
}
}
//蘋果電腦工廠
class MacComputerFactory implements AbstractFactory{
public Computer createComputer() {
Computer c = new Computer();
c.setEngine(new Engine("蘋果CPU"));
c.setKeyboard(new Keyboard("蘋果鍵盤"));
c.setMouse(new Mouse("蘋果鼠標(biāo)"));
return c;
}
}
--------------------------------------------------------------------------------
//客戶端
public class Client {
public static void main(String[] args) {
AbstractFactory Lenovofactory = new LenovoComputerFactory();
AbstractFactory Macfactory = new MacComputerFactory();
Computer LenovoComputer = Lenovofactory.createComputer();
Computer MacComputer = Macfactory.createComputer();
LenovoComputer.play();
MacComputer.play();
}
}
五、建造者模式
5.1杯瞻、作用:分離了對象子組件的單獨(dú)構(gòu)造(由Builder來負(fù)責(zé))和裝配(由Director負(fù)責(zé))镐牺。 從而可以構(gòu)造出復(fù)雜的對象。這個(gè)模式適用于:某個(gè)對象的構(gòu)建過程復(fù)雜的情況下使用魁莉。由于實(shí)現(xiàn)了構(gòu)建和裝配的解耦睬涧。不同的構(gòu)建器,相同的裝配旗唁,也可以做出不同的對象畦浓;相同的構(gòu)建器,不同的裝配順序也可以做出不同的對象检疫。也就是實(shí)現(xiàn)了構(gòu)建算法讶请、裝配算法的解耦,實(shí)現(xiàn)了更好的復(fù)用屎媳。
5.2夺溢、UML圖:
5.3、示例:
//電腦類
public class Computer {
private Engine engine;
private Keyboard keyboard;
private Mouse mouse;
public Engine getEngine() {
return engine;
}
public void setEngine(Engine engine) {
this.engine = engine;
}
public Keyboard getKeyboard() {
return keyboard;
}
public void setKeyboard(Keyboard keyboard) {
this.keyboard = keyboard;
}
public Mouse getMouse() {
return mouse;
}
public void setMouse(Mouse mouse) {
this.mouse = mouse;
}
public void play(){
System.out.println(engine.getName()+keyboard.getName()+mouse.getName());
};
}
//引擎類
class Engine{
private String name;
public Engine(String name){this.name=name;}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
//鍵盤類
class Keyboard{
private String name;
public Keyboard(String name){this.name=name;}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
//鼠標(biāo)類
class Mouse{
private String name;
public Mouse(String name){this.name=name;}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
--------------------------------------------------------------------------------
//電腦構(gòu)建接口
public interface ComputerBuilder {
public Engine createEngine();
public Keyboard createKeyBoard();
public Mouse createMouse();
}
class realComputerBuilder implements ComputerBuilder{
public Engine createEngine() {
return new Engine("聯(lián)想CPU");
}
public Keyboard createKeyBoard() {
return new Keyboard("蘋果鍵盤");
}
public Mouse createMouse() {
return new Mouse("華為鼠標(biāo)");
}
}
--------------------------------------------------------------------------------
//電腦組裝接口
public interface ComputerDirector {
public Computer computerDirector(ComputerBuilder computerBuilder);
}
class realComputerDirector implements ComputerDirector{
public Computer computerDirector(ComputerBuilder computerBuilder) {
Computer c = new Computer();
c.setEngine(computerBuilder.createEngine());
c.setKeyboard(computerBuilder.createKeyBoard());
c.setMouse(computerBuilder.createMouse());
return c;
}
}
--------------------------------------------------------------------------------
//客戶端
public class Client {
public static void main(String[] args) {
ComputerBuilder computerBuilder = new realComputerBuilder();
ComputerDirector computerDirector = new realComputerDirector();
Computer c =computerDirector.computerDirector(computerBuilder);
System.out.println(c.getEngine().getName()+""+c.getKeyboard().getName()+""+c.getMouse().getName()+"");
}
}
--------------------------------------------------------------------------------
總結(jié):如上代碼烛谊,如果要生產(chǎn)不同型號(hào)的配件风响,只需要?jiǎng)?chuàng)建一個(gè)新的構(gòu)造器類,需要組裝成不同型號(hào)的電腦也只需要?jiǎng)?chuàng)建一個(gè)新的組黃器類丹禀,不需要修改之前的代碼
六状勤、原型模式(prototype)
6.1鞋怀、作用:通過new產(chǎn)生一個(gè)對象需要非常繁瑣的數(shù)據(jù)準(zhǔn)備或訪問權(quán)限,則可以使用原型模式荧降。它本身就是java中的克隆技術(shù)接箫,以某個(gè)對象為原型攒读,復(fù)制出新的對象朵诫。顯然,新的對象具備原型對象的特點(diǎn)薄扁。優(yōu)勢有:效率高(直接克隆剪返,避免了重新執(zhí)行構(gòu)造過程步驟) 〉嗣罚克隆類似于new脱盲,但是不同于new。new創(chuàng)建新的對象屬性采用的是默認(rèn)值日缨∏矗克隆出的對象的屬性值完全和原型對象相同。并且克隆出的新對象改變不會(huì)影響原型對象匣距。然后面哥,再修改克隆對象的值。
6.2毅待、重要知識(shí)點(diǎn):克隆問題(淺克隆和深克隆尚卫,此處不詳說,請另行查看我的文章:http://www.reibang.com/p/d2783a7cf031)
6.3尸红、UML圖:
6.4吱涉、示例:
//電腦類
public class Computer implements Serializable{
private Engine engine;
private Keyboard keyboard;
private Mouse mouse;
public Engine getEngine() {
return engine;
}
public void setEngine(Engine engine) {
this.engine = engine;
}
public Keyboard getKeyboard() {
return keyboard;
}
public void setKeyboard(Keyboard keyboard) {
this.keyboard = keyboard;
}
public Mouse getMouse() {
return mouse;
}
public void setMouse(Mouse mouse) {
this.mouse = mouse;
}
public void play(){
System.out.println(engine.getName()+keyboard.getName()+mouse.getName());
};
}
//引擎類
class Engine implements Serializable{
private String name;
public Engine(String name){this.name=name;}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
//鍵盤類
class Keyboard implements Serializable{
private String name;
public Keyboard(String name){this.name=name;}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
//鼠標(biāo)類
class Mouse implements Serializable{
private String name;
public Mouse(String name){this.name=name;}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
--------------------------------------------------------------------------------
public class ComputerClone {
public Computer clone(Computer c){
Computer c2 =null;
try {
ByteArrayOutputStream bas =new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bas);
oos.writeObject(c);
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bas.toByteArray()));
c2 =(Computer) ois.readObject();
bas.flush();oos.flush();
bas.close();oos.close();
ois.close();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return c2;
}
}
--------------------------------------------------------------------------------
public class Client {
public static void main(String[] args) {
ComputerClone computerClone = new ComputerClone();
Computer c = new Computer();
c.setEngine(new Engine("華為CPU"));
c.setKeyboard(new Keyboard("聯(lián)想鍵盤"));
c.setMouse(new Mouse("蘋果鼠標(biāo)"));
Computer c2 = computerClone.clone(c);
System.out.println(c);
System.out.println(c2);
System.out.println(c2.getEngine().getName()+""+c2.getKeyboard().getName()+""+c2.getMouse().getName()+"");
}
}
--------------------------------------------------------------------------------
結(jié)果:
com.primeton.GOF23.prototype.Computer@6727734f
com.primeton.GOF23.prototype.Computer@7176c74b
華為CPU聯(lián)想鍵盤蘋果鼠標(biāo)
--------------------------------------------------------------------------------
總結(jié):通過結(jié)果可以看到克隆出來的對象是一個(gè)新對象,但其中屬性與原型對象一致外里,整個(gè)新對象產(chǎn)生的過程很簡單怎爵,效率高(直接克隆,避免了重新執(zhí)行構(gòu)造過程步驟)