原文地址:http://te-amo.site/user/article/info/ARTICLE20180411032005619
文章中部分定義和解釋性文字,都是引用百度百科,主要的代碼及場景應用爲本人原創
工廠方法模式的核心精神是封裝類中不變的部分,提取其中個性化善變的部分爲獨立類,通過依賴注入以達到解耦、複用和方便後期維護拓展的目的
場景:在簡單工廠的場景上,有了新的需求:創建管理員用戶時,需要指定ID:0~100,名字爲:admin,有效時長:10分鐘;創建一般用戶時,需要指定ID:100~200,名字爲:與ID相同,有效時長:5分鐘;創建匿名用戶時,需要指定ID:200~300,名字爲:anonymous,有效時長:1分鐘 。用戶實例化完成後要激活用戶。
設計
結構
- 抽象工廠(Creator)角色:任何在模式中創建的對象的工廠類必須實現這個接口。(UserFactory)
- 具體工廠(Concrete Creator)角色:這是實現抽象工廠接口的具體工廠類,包含與應用程序密切相關的邏輯,並且受到應用程序調用以創建產品對象。(AdminUserFactory,AnonymousUserFactory,NormalUserFactory)
- 抽象產品(Product)角色:工廠方法模式所創建的對象的超類型,也就是產品對象的共同父類或共同擁有的接口。(User)
- 具體產品(Concrete Product)角色:這個角色實現了抽象產品角色所定義的接口。某具體產品有專門的具體工廠創建。(AdminUser,AnonymousUser,NormalUser)
實現
代碼地址:https://github.com/telundusiji/designpattern
抽象產品 抽象用戶
@Data
public abstract class User {
private int id;
private String name;
private String role;
private long active;
private boolean status;
public abstract void init(int id,String name,long active);
}
具體產品 管理員用戶
public class AdminUser extends User {
@Override
public void init(int id, String name, long active) {
setId(id);
setName(name);
setRole("管理員");
setActive(active);
}
}
具體產品 匿名用戶
public class AnonymousUser extends User {
@Override
public void init(int id, String name, long active) {
setId(id);
setName(name);
setRole("匿名用戶");
setActive(active);
}
}
具體產品 一般用戶
public class NormalUser extends User {
@Override
public void init(int id, String name, long active) {
setId(id);
setName(name);
setRole("一般用戶");
setActive(active);
}
}
抽象工廠
@Slf4j
public abstract class UserFactory {
public abstract User createUser();
public void userActive(User user){
user.setStatus(true);
log.info("{}激活成功!",user.toString());
}
}
具體工廠 管理員工廠
public class AdminUserFactory extends UserFactory {
@Override
public User createUser() {
AdminUser adminUser = new AdminUser();
adminUser.init((int)(Math.random()*100),"admin",1000*60*10);
userActive(adminUser);
return adminUser;
}
}
具體工廠 匿名用戶工廠
public class AnonymousUserFactory extends UserFactory{
@Override
public User createUser() {
AnonymousUser anonymousUser = new AnonymousUser();
anonymousUser.init((int)(Math.random()*100+200),"anonymous",1000*60*1);
userActive(anonymousUser);
return anonymousUser;
}
}
具體工廠 一般用戶工廠
public class NormalUserFactory extends UserFactory {
@Override
public User createUser() {
NormalUser normalUser = new NormalUser();
int id = (int)(Math.random()*100+100);
normalUser.init(id,String.valueOf(id),1000*60*5);
userActive(normalUser);
return normalUser;
}
}
經典應用
java.net.URLStreamHandlerFactory 是一個工廠方法的典型應用:
- 抽象工廠:java.net.URLStreamHandlerFactory
- 具體工廠:實現URLStreamHandlerFactory 接口的類
- 抽象產品:java.net.URLStreamHandler
- 具體產品:繼承URLStreamHandler抽象類並實現其抽象方法的類
總結
- 工廠方法(Factory Method)模式的意義是定義一個創建產品對象的工廠接口,將實際創建工作推遲到子類當中。核心工廠類不再負責產品的創建,僅負責具體工廠子類必須實現的接口,可以使系統在不修改具體工廠角色的情況下引進新的產品。
- 工廠方法模式是簡單工廠模式的衍生,實現‘開-閉 原則’,實現了可擴展。其次更復雜的層次結構,可以應用於產品結果複雜的場合。