#學習記錄(剛剛學習之後進行了簡單的總結)
github https://github.com/gaoruiqiang2017/factory.git
簡單工廠模式
簡單工廠模式(Simple Factory Pattern)是指由一個工廠對象決定創建出哪一種產品類
的實例,但它不屬於GOF,23 種設計模式
/**
* 課程
*/
public interface Course {
void record();
}
public class JavaCourse implements Course {
@Override
public void record() {
System.out.print("錄製JAVA課程");
}
}
public class PythonCourse implements Course {
@Override
public void record() {
System.out.print("錄製Python課程");
}
}
public class CourseFactory {
//如果增加類型就需要修改代碼,不符合開閉原則
/*
public Course create(String name) {
if ("java".equals(name)) {
return new JavaCourse();
} else if ("python".equals(name)) {
return new PythonCourseFactory();
} else {
return null;
}
}
*/
//是使用反射
/* public Course create(String name) {
try {
if (null != name && !"".equals(name)) {
return (Course) Class.forName(name).newInstance();
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}*/
//參數直接就是類
public Course create(Class<? extends Course> clazz) {
try {
if (null != clazz) {
return clazz.newInstance();
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public class SimpleFactoryTest {
public static void main(String[] args) {
//第一層 父類指向子類引用
/* Course course = new JavaCourse();
course.record();*/
//第二層 簡單工廠,將創建細節隱藏
/* CourseFactory courseFactory = new CourseFactory();
courseFactory.create("python").record();*/
//第三層,使用反射,參數是字符串,還需要強制轉型,還可以優化
/* CourseFactory courseFactory = new CourseFactory();
courseFactory.create("com.study.factory.JavaCourse").record();*/
//第四層,可控制性提升
CourseFactory courseFactory = new CourseFactory();
courseFactory.create(JavaCourse.class).record();
}
}
簡單工廠模式在JDK 源碼也是無處不在,如:Calendar和logback
工廠方法模式
工廠方法模式(Fatory Method Pattern)是指定義一個創建對象的接口,但讓實現這個接口的類來決定實例化哪個類,工廠方法讓類的實例化推遲到子類中進行。在工廠方法模式中用戶只需要關心所需產品對應的工廠,無須關心創建細節,而且加入新的產品符合開閉原則。
工廠方法模式主要解決產品擴展的問題,在簡單工廠中,隨着產品鏈的豐富,如果每個課程的創建邏輯有區別的話,工廠的職責會變得越來越多,有點像萬能工廠,並不便於維護。根據單一職責原則我們將職能繼續拆分,專人幹專事。Java 課程由Java 工廠創建,Python 課程由Python 工廠創建,對工廠本身也做一個抽象
public interface CourseFactory {
Course create();
}
public class JavaCourseFactory implements CourseFactory {
@Override
public Course create() {
return new JavaCourse();
}
}
public class PythonCourseFactory implements CourseFactory {
@Override
public Course create() {
return new PythonCourse();
}
}
public class FactoryMethodTest {
/* 工廠方法適用於以下場景:
1、創建對象需要大量重複的代碼。
2、客戶端(應用層)不依賴於產品類實例如何被創建、實現等細節。
3、一個類通過其子類來指定創建哪個對象。
工廠方法也有缺點:
1、類的個數容易過多,增加複雜度。
2、增加了系統的抽象性和理解難度。*/
public static void main(String[] args) {
//工廠模式,每種語言都有自己的工廠來創建實例,創建的邏輯可以不同
CourseFactory courseFactory = new JavaCourseFactory();
Course course = courseFactory.create();
course.record();
CourseFactory python = new PythonCourseFactory();
python.create().record();
}
}
抽象工廠模式
抽象工廠模式(Abastract Factory Pattern)是指提供一個創建一系列相關或相互依賴對象的接口,無須指定他們具體的類。客戶端(應用層)不依賴於產品類實例如何被創建、實現等細節,強調的是一系列相關的產品對象(屬於同一產品族)一起使用創建對象需要大量重複的代碼。需要提供一個產品類的庫,所有的產品以同樣的接口出現,從而使客戶端不依賴於具體實現。
public interface Note {
void edit();
}
public interface Video {
void record();
}
/**
* 抽象工廠是用戶的主入口
* 在Spring 中應用得最爲廣泛的一種設計模式
* 易於擴展
*/
public interface CourseFactory {
Note createNote();
Video createVideo();
}
public class JavaNote implements Note {
@Override
public void edit() {
System.out.println("JAVA筆記");
}
}
在這裏插入代碼片
public class JavaVideo implements Video {
@Override
public void record() {
System.out.println("錄製JAVA視頻");
}
}
public class JavaCourseFactory implements CourseFactory {
@Override
public Note createNote() {
return new JavaNote();
}
@Override
public Video createVideo() {
return new JavaVideo();
}
}
public class PythonNote implements Note {
@Override
public void edit() {
System.out.println("python 筆記");
}
}
public class PythonVideo implements Video {
@Override
public void record() {
System.out.println("python 視頻");
}
}
public class PythonCourseFactory implements CourseFactory {
@Override
public Note createNote() {
return new PythonNote();
}
@Override
public Video createVideo() {
return new PythonVideo();
}
}
public class AbstractFactoryTest {
/* 這段抽象工廠代碼完整地描述了兩個產品族Java 課程和Python 課程,也描述了兩個產品等級
視頻和手記。抽象工廠非常完美清晰地描述這樣一層複雜的關係。但是,不知道大家有
沒有發現,如果我們再繼續擴展產品等級,將源碼Source 也加入到課程中,那麼我們的
代碼從抽象工廠,到具體工廠要全部調整,很顯然不符合開閉原則。因此抽象工廠也是
有缺點的:
1、規定了所有可能被創建的產品集合,產品族中擴展新的產品困難,需要修改抽象工廠
的接口。
2、增加了系統的抽象性和理解難度。
但在實際應用中,我們千萬不能犯強迫症甚至有潔癖。在實際需求中產品等級結構升級
是非常正常的一件事情。我們可以根據實際情況,只要不是頻繁升級,可以不遵循開閉
原則。代碼每半年升級一次或者每年升級一次又有何不可呢?*/
public static void main(String[] args) {
CourseFactory courseFactory = new JavaCourseFactory();
courseFactory.createNote().edit();
courseFactory.createVideo().record();
CourseFactory factory = new PythonCourseFactory();
factory.createVideo().record();
factory.createNote().edit();
}
}