- 單例模式
- 餓漢式
- 懶漢式:雙重校驗->volatile 在jdk版本較低,禁止指令排序
- 內部類
- 枚舉
單例的劣勢
1. 繼承、多態支持的不友好
2. 隱藏依賴關係
3. 擴展性不好(比如要創建兩個對象)
4. 測試不友好
5. 不支持參數的構造函數
先調用 init(paramA,paramB) 再調用 getInstance()
getInstance(paramA,paramB),有問題
配置靜態參數
線程單例
進程單例:一般默認方式
集羣單例:多個進程也是單例---->加鎖 回寫 釋放鎖 外部共享存儲區(比如文件)
code
//餓漢
public class A {
private static A instance = new A();
private A() {
}
public static A getInstance() {
return instance;
}
}
//懶漢
public class A {
private static A instance ;
public static A getInstance() {
if (instance == null){
synchronized (A.class){
if (instance == null){
instance = new A();
}
}
}
return instance;
}
}
//枚舉
public enum A {
ONE(1),TWO(2),THREE(3),FOUR(4),FIVE(5);
private int value;
A(int i) {
this.value = i;
}
public int getValue() {
return value;
}
}
//靜態內部類
public class A {
private static class B{
private static A instance = new A();
}
public static A getInstance() {
return B.instance;
}
}
- 工廠
- 簡單工廠
- 工廠方法:在構造對象比較複雜的時候 ,工廠裏創建工廠
DI:解析配置文件,工廠類創建對象(反射)
code
public interface IParseConfig {
void parse(String input);
}
public class XMLParse implements IParseConfig {
@Override
public void parse(String input) {
//xml 解析
}
}
public class JsonParse implements IParseConfig {
@Override
public void parse(String input) {
//Json 解析
}
}
public class PropertyParse implements IParseConfig {
@Override
public void parse(String input) {
//properties 解析
}
}
public class ParseFactory {
private static final HashMap<String,IParseConfig> cacheParse = new HashMap<>();
static {
cacheParse.put("json",new JsonParse());
cacheParse.put("xml",new XMLParse());
cacheParse.put("properties",new PropertyParse());
}
public void parse(String filePath){
//簡單工廠
String fileExtension = getFileExtension(filePath);
String input = "解析出來的文件流";
IParseConfig parseConfig;
if ("json".equals(fileExtension)){
parseConfig = new JsonParse();
}else if ("xml".equals(fileExtension)){
parseConfig = new XMLParse();
}else if ("properties".equals(fileExtension)){
parseConfig = new PropertyParse();
}else {
throw new UnsupportedOperationException("UnSupport format");
}
parseConfig.parse(input);
//節省創建時間 直接在緩存拿出來
IParseConfig parseConfig1 = cacheParse.get(fileExtension);
parseConfig1.parse(input);
//工廠方法
IParseFactory parseFactory;
if ("json".equals(fileExtension)){
parseFactory = new JsonParseFactory();
}else if ("xml".equals(fileExtension)){
parseFactory = new XMLParseFactory();
}else if ("properties".equals(fileExtension)){
parseFactory = new PropertyParseFactory();
}else {
throw new UnsupportedOperationException("UnSupport format");
}
parseConfig = parseFactory.createParse();
parseConfig.parse(input);
}
private String getFileExtension(String filePath){
return "json";
}
}
//xml properties相似 省略
public class JsonParseFactory implements IParseFactory {
@Override
public IParseConfig createParse() {
return new JsonParse();
}
}
//抽象工廠 工廠創建多個實例
public interface IConfigParseFactory {
IParseFactory createRuleParser();
ISystemFactory createSystemParser();
}
- 建造者模式
- 如果必填參數比較多,通過構造函數不是很合適
- 各個參數有依賴關係,通過set不太好檢驗
- 如果有需求,對象創建之後,各個屬性不可變
public class Dialog {
private String title;
private int width;
private int height;
private Dialog(Builder builder) {
title = builder.title;
width = builder.width;
height = builder.height;
}
public static class Builder{
private String title;
private int width;
private int height;
public Builder setWidth(int width){
if (width < 0){
throw new UnsupportedOperationException("width should >= 0");
}
this.width = width;
return Builder.this;
}
public Builder setHeight(int height){
if (height < 0){
throw new UnsupportedOperationException("width should >= 0");
}
this.height = height;
return Builder.this;
}
public Builder setTitle(String title){
this.title = title;
return Builder.this;
}
public Dialog build(){
if (title.isEmpty()){
throw new IllegalArgumentException("title should not empty");
}
return new Dialog(this);
}
}
}
Dialog dialog = new Dialog.Builder()
.setTitle("標題")
.setWidth(100)
.setHeight(100)
.build();
- 原型模式
如果創建對象成本比較高,可以直接通過拷貝對象來獲取新對象,拷貝對象有深拷貝和淺拷貝兩種,clone方法是淺拷貝,只拷貝了索引和基本數據類型,沒有拷貝對象,深拷貝是拷貝索引和引用
實現深拷貝的兩種方式
- 序列化對象
- 遞歸拷貝對象 對象引用對象
淺拷貝適用於不可變的數據