一、開閉原則(Open Close Principle)html
對擴展開放,對修改關閉。java
二、里氏代換原則(Liskov Substitution Principle)編程
只有當衍生類能夠替換掉基類,軟件單位的功能不受到影響時,基類才能真正被複用,而衍生類也可以在基類的基礎上增長新的行爲。設計模式
三、依賴倒轉原則(Dependence Inversion Principle)ide
這個是開閉原則的基礎,對接口編程,依賴於抽象而不依賴於具體。函數
四、接口隔離原則(Interface Segregation Principle)工具
使用多個隔離的藉口來下降耦合度。ui
五、迪米特法則(最少知道原則)(Demeter Principle)this
一個實體應當儘可能少的與其餘實體之間發生相互做用,使得系統功能模塊相對獨立。spa
六、合成複用原則(Composite Reuse Principle)
原則是儘可能使用合成/聚合的方式,而不是使用繼承。繼承實際上破壞了類的封裝性,超類的方法可能會被子類修改。
經常使用的工廠模式是靜態工廠,利用static方法,做爲一種相似於常見的工具類Utils等輔助效果,通常狀況下工廠類不須要實例化。
interface food{} class A implements food{} class B implements food{} class C implements food{}
public class StaticFactory {
private StaticFactory(){} public static food getA(){ return new A(); } public static food getB(){ return new B(); } public static food getC(){ return new C(); } } class Client{ //客戶端代碼只須要將相應的參數傳入便可獲得對象 //用戶不須要了解工廠類內部的邏輯。 public void get(String name){ food x = null ; if ( name.equals("A")) { x = StaticFactory.getA(); }else if ( name.equals("B")){ x = StaticFactory.getB(); }else { x = StaticFactory.getC(); } } }
一個基礎接口定義了功能,每一個實現接口的子類就是產品,而後定義一個工廠接口,實現了工廠接口的就是工廠,這時候,接口編程的優勢就出現了,咱們能夠新增產品類(只須要實現產品接口),只須要同時新增一個工廠類,客戶端就能夠輕鬆調用新產品的代碼。
抽象工廠的靈活性就體如今這裏,無需改動原有的代碼,畢竟對於客戶端來講,靜態工廠模式在不改動StaticFactory類的代碼時沒法新增產品,若是採用了抽象工廠模式,就能夠輕鬆的新增拓展類。
實例代碼:
interface food{} class A implements food{} class B implements food{} interface produce{ food get();} class FactoryForA implements produce{ @Override public food get() { return new A(); } } class FactoryForB implements produce{ @Override public food get() { return new B(); } } public class AbstractFactory { public void ClientCode(String name){ food x= new FactoryForA().get(); x = new FactoryForB().get(); } }
在內部建立一個實例,構造器所有設置爲private,全部方法均在該實例上改動,在建立上要注意類的實例化只能執行一次,能夠採用許多種方法來實現,如Synchronized關鍵字,或者利用內部類等機制來實現。
public class Singleton { private Singleton(){} private static class SingletonBuild{ private static Singleton value = new Singleton(); } public Singleton getInstance(){ return SingletonBuild.value ;} }
在瞭解以前,先假設有一個問題,咱們須要建立一個學生對象,屬性有name,number,class,sex,age,school等屬性,若是每個屬性均可覺得空,也就是說咱們能夠只用一個name,也能夠用一個school,name,或者一個class,number,或者其餘任意的賦值來建立一個學生對象,這時該怎麼構造?
難道咱們寫6個1個輸入的構造函數,15個2個輸入的構造函數.......嗎?這個時候就須要用到Builder模式了。給個例子,你們確定一看就懂:
public class Builder { static class Student{ String name = null ; int number = -1 ; String sex = null ; int age = -1 ; String school = null ;
//構建器,利用構建器做爲參數來構建Student對象 static class StudentBuilder{ String name = null ; int number = -1 ; String sex = null ; int age = -1 ; String school = null ; public StudentBuilder setName(String name) { this.name = name; return this ; } public StudentBuilder setNumber(int number) { this.number = number; return this ; } public StudentBuilder setSex(String sex) { this.sex = sex; return this ; } public StudentBuilder setAge(int age) { this.age = age; return this ; } public StudentBuilder setSchool(String school) { this.school = school; return this ; } public Student build() { return new Student(this); } } public Student(StudentBuilder builder){ this.age = builder.age; this.name = builder.name; this.number = builder.number; this.school = builder.school ; this.sex = builder.sex ; } } public static void main( String[] args ){ Student a = new Student.StudentBuilder().setAge(13).setName("LiHua").build(); Student b = new Student.StudentBuilder().setSchool("sc").setSex("Male").setName("ZhangSan").build(); } }
原型模式就是講一個對象做爲原型,使用clone()方法來建立新的實例。
public class Prototype implements Cloneable{ private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } @Override protected Object clone() { try { return super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); }finally { return null; } } public static void main ( String[] args){ Prototype pro = new Prototype(); Prototype pro1 = (Prototype)pro.clone(); } }
此處使用的是淺拷貝,關於深淺拷貝,你們能夠另行查找相關資料。
適配器模式的做用就是在原來的類上提供新功能。主要可分爲3種:
class adapter extends oldClass implements newFunc{}
class adapter implements newFunc { private oldClass oldInstance ;}
abstract class adapter implements oldClassFunc { void newFunc();}
給一類對象增長新的功能,裝飾方法與具體的內部邏輯無關。例如:
interface Source{ void method();} public class Decorator implements Source{ private Source source ; public void decotate1(){ System.out.println("decorate"); } @Override public void method() { decotate1(); source.method(); } }
客戶端經過代理類訪問,代理類實現具體的實現細節,客戶只須要使用代理類便可實現操做。
這種模式能夠對舊功能進行代理,用一個代理類調用原有的方法,且對產生的結果進行控制。
interface Source{ void method();} class OldClass implements Source{ @Override public void method() { } } class Proxy implements Source{ private Source source = new OldClass(); void doSomething(){} @Override public void method() { new Class1().Func1(); source.method(); new Class2().Func2(); doSomething(); } }
爲子系統中的一組接口提供一個一致的界面,定義一個高層接口,這個接口使得這一子系統更加容易使用。這句話是百度百科的解釋,有點難懂,可是沒事,看下面的例子,咱們在啓動中止全部子系統的時候,爲它們設計一個外觀類,這樣就能夠實現統一的接口,這樣即便有新增的子系統subSystem4,也能夠在不修改客戶端代碼的狀況下輕鬆完成。
public class Facade { private subSystem1 subSystem1 = new subSystem1(); private subSystem2 subSystem2 = new subSystem2(); private subSystem3 subSystem3 = new subSystem3(); public void startSystem(){ subSystem1.start(); subSystem2.start(); subSystem3.start(); } public void stopSystem(){ subSystem1.stop(); subSystem2.stop(); subSystem3.stop(); } }
這裏引用下http://www.runoob.com/design-pattern/bridge-pattern.html的例子。Circle類將DrwaApi與Shape類進行了橋接,代碼:
interface DrawAPI { public void drawCircle(int radius, int x, int y); } class RedCircle implements DrawAPI { @Override public void drawCircle(int radius, int x, int y) { System.out.println("Drawing Circle[ color: red, radius: " + radius +", x: " +x+", "+ y +"]"); } } class GreenCircle implements DrawAPI { @Override public void drawCircle(int radius, int x, int y) { System.out.println("Drawing Circle[ color: green, radius: " + radius +", x: " +x+", "+ y +"]"); } } abstract class Shape { protected DrawAPI drawAPI; protected Shape(DrawAPI drawAPI){ this.drawAPI = drawAPI; } public abstract void draw(); } class Circle extends Shape { private int x, y, radius; public Circle(int x, int y, int radius, DrawAPI drawAPI) { super(drawAPI); this.x = x; this.y = y; this.radius = radius; } public void draw() { drawAPI.drawCircle(radius,x,y); } } //客戶端使用代碼 Shape redCircle = new Circle(100,100, 10, new RedCircle()); Shape greenCircle = new Circle(100,100, 10, new GreenCircle()); redCircle.draw(); greenCircle.draw();
組合模式是爲了表示那些層次結構,同時部分和總體也多是同樣的結構,常見的如文件夾或者樹。舉例:
abstract class component{} class File extends component{ String filename;} class Folder extends component{ component[] files ; //既能夠放文件File類,也能夠放文件夾Folder類。Folder類下又有子文件或子文件夾。 String foldername ; public Folder(component[] source){ files = source ;} public void scan(){ for ( component f:files){ if ( f instanceof File){ System.out.println("File "+((File) f).filename); }else if(f instanceof Folder){ Folder e = (Folder)f ; System.out.println("Folder "+e.foldername); e.scan(); } } } }
使用共享對象的方法,用來儘量減小內存使用量以及分享資訊。一般使用工廠類輔助,例子中使用一個HashMap類進行輔助判斷,數據池中是否已經有了目標實例,若是有,則直接返回,不須要屢次建立重複實例。
abstract class flywei{ } public class Flyweight extends flywei{ Object obj ; public Flyweight(Object obj){ this.obj = obj; } } class FlyweightFactory{ private HashMap<Object,Flyweight> data; public FlyweightFactory(){ data = new HashMap<>();} public Flyweight getFlyweight(Object object){ if ( data.containsKey(object)){ return data.get(object); }else { Flyweight flyweight = new Flyweight(object); data.put(object,flyweight); return flyweight; } } }