目錄
1.單例模式 (推薦使用懶漢和DCL模式)
//懶漢單例
public class Singleton {
private static Singleton mInstance;
private Singleton() {
}
public static Singleton getInstance() {
if (mInstance == null) {
mInstance = new Singleton();
}
return mInstance;
}
}
//DCL單例
public class Singleton {
private volatile static Singleton mInstance = null;
private Singleton() {
}
public static Singleton getInstance() {
if (mInstance == null) {
synchronized (Singleton.class) {
if (mInstance == null) {
mInstance = new Singleton();
}
}
}
return mInstance;
}
}
//靜態內部類單例
public class Singleton {
private volatile static Singleton mInstance = null;
private Singleton() {
}
public static Singleton getInstance() {
return SingletonHolder.mInstance;
}
private static class SingletonHolder {
private static final Singleton mInstance = new Singleton();
}
}
//枚舉單例
public enum SingletonEnum {
INGLETON;
}
//使用容器實現單例
public class SingletonManager {
private static Map<String,Object> objMap = new HashMap<>();
private SingletonManager() {
}
public static void registerService(String key,Object instance) {
if (!objMap.containsKey(key)) {
objMap.put(key,instance);
}
}
public static Object getService(String key) {
return objMap.get(key);
}
}
2.Builder模式
//女朋友配置類 避免目標類中有過多的接口
public class GirlFriendConfig {
/**
* 姓名 年齡 身高
*/
String name = "未知";
int age;
int height = 165;
private GirlFriendConfig() {
}
public static class Builder {
String name;
int age;
int height;
public Builder setName(String name) {
this.name = name;
return this;
}
public Builder setAge(int age) {
this.age = age;
return this;
}
public Builder setHeight(int height) {
this.height = height;
return this;
}
private void applyConfig(GirlFriendConfig config) {
config.name = this.name;
config.age = this.age;
config.height = height;
}
public GirlFriendConfig create() {
GirlFriendConfig config = new GirlFriendConfig();
applyConfig(config);
return config;
}
}
}
//女朋友
public class GirlFriend {
private final static String TAG = "GirlFriend";
private static GirlFriend mInstance;
private GirlFriendConfig mConfig;
private GirlFriend() {
}
public static GirlFriend getInstance() {
if (mInstance == null) {
mInstance = new GirlFriend();
}
return mInstance;
}
public void init(GirlFriendConfig config) {
this.mConfig = config;
}
public void showGirlFriend() {
Log.w(TAG, "姓名:" + mConfig.name + "/年齡:" + mConfig.age == null ? "保密" : mConfig.age + "/身高:" + mConfig.height);
}
public void dissGirlFriend() {
Log.w(TAG,"diss? 想都不要想");
}
}
//您的女朋友
private void newGirlFriend() {
GirlFriendConfig config = new GirlFriendConfig.Builder()
.setName("古力娜扎")
.setHeight(172)
.create();
GirlFriend.getInstance().init(config);
GirlFriend.getInstance().showGirlFriend();
GirlFriend.getInstance().dissGirlFriend();
}
3.原型模式
1.實際上就是對象的拷貝。原型模式多用於創建複雜的或者構造消耗時實例,在這種情況下,複製一個已經存在的實例可使程序運行更高效。
2.通過實現 Cloneable 重寫 clone()方法實現(分爲深拷貝和淺拷貝)
淺拷貝:調用 java.lang.Object的clone()方法
public class Address{
private String city;
private String area;
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getArea() {
return area;
}
public void setArea(String area) {
this.area = area;
}
}
public class User implements Cloneable {
private String name;
private Address address;
@Override
protected Object clone() throws CloneNotSupportedException {
User user = (User) super.clone();
return user;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public void showMessage() {
System.out.println(name.hashCode());
System.out.println(name);
System.out.println(address.hashCode());
System.out.println(address.getCity() + address.getArea());
}
}
public class Test {
public static void main(String[] args) throws CloneNotSupportedException {
User originUser = new User();
originUser.setName("小明");
Address address = new Address();
address.setCity("廣州");
address.setArea("天河區");
originUser.setAddress(address);
System.out.println("---------第一次原對象----------");
originUser.showMessage();
User copyUser = (User) originUser.clone();
copyUser.setName("小紅");
copyUser.getAddress().setCity("深圳");
copyUser.getAddress().setArea("寶安區");
System.out.println("---------複製對象----------");
copyUser.showMessage();
System.out.println("---------再次原對象----------");
originUser.showMessage();
}
}
運行打印日誌:
---------第一次原對象----------
756703
小明
791452441
廣州天河區
---------複製對象----------
762995
小紅
791452441
深圳寶安區
---------再次原對象----------
756703
小明
791452441
深圳寶安區
深拷貝:
(1)對象內部所有引用型對象都實現Cloneable重寫clone()
public class Address implements Cloneable{
private String city;
private String area;
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getArea() {
return area;
}
public void setArea(String area) {
this.area = area;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
public class User implements Cloneable {
private String name;
private Address address;
@Override
protected Object clone() throws CloneNotSupportedException {
User user = (User) super.clone();
//注意這裏
user.address = (Address) address.clone();
return user;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public void showMessage() {
System.out.println(name.hashCode());
System.out.println(name);
System.out.println(address.hashCode());
System.out.println(address.getCity() + address.getArea());
}
}
運行打印日誌:
---------第一次原對象----------
756703
小明
791452441
廣州天河區
---------複製對象----------
762995
小紅
834600351
深圳寶安區
---------再次原對象----------
756703
小明
791452441
廣州天河區
(2)對象序列化
public class User implements Cloneable, Serializable {
private String name;
private Address address;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public User deepClone() { // 使用序列化和反序列化實現深複製
//略
return null;
}
public void showMessage() {
System.out.println(name.hashCode());
System.out.println(name);
System.out.println(address.hashCode());
System.out.println(address.getCity() + address.getArea());
}
}
運行打印日誌:
---------第一次原對象----------
756703
小明
791452441
廣州天河區
---------複製對象----------
762995
小紅
834600351
深圳寶安區
---------再次原對象----------
756703
小明
791452441
廣州天河區
3.用途,例如:
(1)循環體內產生大量對象
(2)保護性拷貝,如不允許修改的登錄後的用戶信息
(3)其他
4.注意:通過clone拷貝的對象不會執行構造方法。
4.工廠方法模式
(1)簡單工廠模式
//抽象產品類 - 朋友
public abstract class Friend {
/**
* 產品類的抽象方法
* 具體由產品類去實現
*/
public abstract void message();
}
//具體產品類 男朋友
public class BoyFriend extends Friend {
@Override
public void message() {
System.out.println("我是男朋友");
}
}
//具體產品類 女朋友
public class GirlFriend extends Friend{
@Override
public void message() {
System.out.println("我是女朋友");
}
}
//抽象工廠類
public abstract class Factory {
/**
* 抽象工廠方法
* 具體生產什麼由子類去實現
* @return 具體的產品對象
*/
public abstract Friend createFriend();
}
//具體工廠類
public class FriendFactory extends Factory {
@Override
public Friend createFriend() {
//需要什麼朋友就new什麼朋友
return new GirlFriend();
//return new BoyFriend();
}
}
//生產使用
public void newFriend() {
Factory factory = new FriendFactory();
Friend friend = factory.createFriend();
friend.message();
}
(2)多工廠模式 (爲每一個產品都定義一個具體的工廠)
//生產男朋友的工廠
public class BoyFriendFactory extends Factory{
@Override
public Friend createFriend() {
return new BoyFriend();
}
}
//生產女朋友的工廠
public class GirlFriendFactory extends Factory{
@Override
public Friend createFriend() {
return new GirlFriend();
}
}
//生產使用
public static void newFriend() {
Factory girlFriendFactory = new GirlFriendFactory();
Friend girlFriend = girlFriendFactory.createFriend();
girlFriend.message();
Factory boyFriendFactory = new BoyFriendFactory();
Friend boyFriend = boyFriendFactory.createFriend();
boyFriend.message();
}
(3)利用反射的方式更簡潔地生產具體產品對象
public abstract class Factory {
public abstract <T extends Friend> T createFriend(Class<T> clz);
}
public class FriendFactory extends Factory {
@Override
public <T extends Friend> T createFriend(Class<T> clz) {
Friend friend = null;
try {
friend = (Friend) Class.forName(clz.getName()).newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return (T) friend;
}
}
//生產使用
public void newFriend() {
Factory factory = new FriendFactory();
Friend friend = factory.createFriend(GirlFriend.class);
friend.message();
}
(4)如果可以確定工廠類只有一個,那麼可以選擇簡化掉抽象類,只需把工廠方法改爲靜態方法
public class Factory {
public static Friend createFriend();
}
5.抽象工廠模式
爲創建一組相關或者相互依賴的對象提供一個接口,而不需要指定它們的具體類。
//男朋友相關類
public interface IBoyFriend {
void showBoyFriend();
}
//具體產品類A款男朋友
public class BoyFriendA implements IBoyFriend {
@Override
public void showBoyFriend() {
System.out.println("A款男朋友");
}
}
//具體產品類B款男朋友
public class BoyFriendB implements IBoyFriend {
@Override
public void showBoyFriend() {
System.out.println("B款男朋友");
}
}
//女朋友相關類
public interface IGirlFriend {
void showGirlFriend();
}
//具體產品類A款女朋友
public class GirlFriendA implements IGirlFriend{
@Override
public void showGirlFriend() {
System.out.println("A款女朋友");
}
}
//具體產品類B款女朋友
public class GirlFriendB implements IGirlFriend{
@Override
public void showGirlFriend() {
System.out.println("B款女朋友");
}
}
//抽象工廠類 - 能夠生產男朋友和女朋友
public abstract class Factory {
public abstract IBoyFriend createBoyFriend();
public abstract IGirlFriend createGirlFriend();
}
//具體工廠類1 看需求生產男女朋友款式
public class FriendFactory1 extends Factory{
@Override
public IBoyFriend createBoyFriend() {
return new BoyFriendA();
}
@Override
public IGirlFriend createGirlFriend() {
return new GirlFriendA();
}
}
//具體工廠類2 看需求生產男女朋友款式
public class FriendFactory2 extends Factory{
@Override
public IBoyFriend createBoyFriend() {
return new BoyFriendA();
}
@Override
public IGirlFriend createGirlFriend() {
return new GirlFriendB();
}
}
//使用生產
public static void newFriend() {
//讓工廠1生產他們的男朋友和女朋友
System.out.println("工廠1 生產:");
Factory factory1 = new FriendFactory1();
factory1.createBoyFriend().showBoyFriend();
factory1.createGirlFriend().showGirlFriend();
//讓工廠2生產他們的男朋友和女朋友
System.out.println("工廠2 生產:");
Factory factory2 = new FriendFactory2();
factory2.createBoyFriend().showBoyFriend();
factory2.createGirlFriend().showGirlFriend();
}
打印日誌:
工廠1 生產:
A款男朋友
A款女朋友
工廠2 生產:
A款男朋友
B款女朋友