1 建造者模式特點
- 定義 : 將一個複雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示
- 特點 : 用戶只需指定需要建造的類型就可以得到它們,建造過程及細節不需要知道
- 類型 : 創建型
適用場景
- 如果一個對象有非常複雜的內部結構(很多屬性)
- 想把複雜對象的創建和使用分離
- 優點 : 封裝性好,創建和使用分離;擴展性好,建造類之間獨立,一定程度上解耦
- 缺點 : 產生多餘的Builder對象;產品內部發生變化,建造者都要修改,成本較大
建造者模式 vs 工廠模式 : 建造者模式更注重於方法的調用順序,工廠模式注重於創建產品;創建對象的粒度不同,建造者模式可以創建複雜的產品,由各種複雜的部件組成,工廠模式創建出來的都是一個樣子;關注點不同,工廠模式注重的是只需要把對象創建出來就ok,建造者模式不只要創建出這個產品,還要知道產品是由那些部件組成的,有些場景還需要關注各個部件的順序
2 Coding
public class Course {
//課程名
private String courseName;
//課程需要的PPT
private String coursePPT;
//課程需要的視頻
private String courseVideo;
//課程的手記
private String courseArticle;
//question & answer
private String courseQA;
//省略 get set toString
}
public abstract class CourseBuilder {
public abstract void buildCourseName(String courseName);
public abstract void buildCoursePPT(String coursePPT);
public abstract void buildCourseVideo(String courseVideo);
public abstract void buildCourseArticle(String courseArticle);
public abstract void buildCourseQA(String courseQA);
public abstract Course makeCourse();
}
public class CourseActualBuilder extends CourseBuilder {
private Course course = new Course();
@Override
public void buildCourseName(String courseName) {
course.setCourseName(courseName);
}
@Override
public void buildCoursePPT(String coursePPT) {
course.setCoursePPT(coursePPT);
}
@Override
public void buildCourseVideo(String courseVideo) {
course.setCourseVideo(courseVideo);
}
@Override
public void buildCourseArticle(String courseArticle) {
course.setCourseArticle(courseArticle);
}
@Override
public void buildCourseQA(String courseQA) {
course.setCourseQA(courseQA);
}
@Override
public Course makeCourse() {
return course;
}
}
public class Coach {
private CourseBuilder courseBuilder;
public void setCourseBuilder(CourseBuilder courseBuilder) {
this.courseBuilder = courseBuilder;
}
public Course makeCourse(String courseName, String coursePPT, String courseVideo, String courseArticle, String courseQA) {
this.courseBuilder.buildCourseName(courseName);
this.courseBuilder.buildCoursePPT(coursePPT);
this.courseBuilder.buildCourseVideo(courseVideo);
this.courseBuilder.buildCourseArticle(courseArticle);
this.courseBuilder.buildCourseQA(courseQA);
return this.courseBuilder.makeCourse();
}
}
public class CourseTest {
@Test
public void test() {
CourseBuilder courseBuilder = new CourseActualBuilder();
Coach coach = new Coach();
coach.setCourseBuilder(courseBuilder);
Course course = coach.makeCourse("Java設計模式精講",
"Java設計模式精講PPT",
"Java設計模式精講視頻",
"Java設計模式精講手記",
"Java設計模式精講問答");
System.out.println(course);
}
}
public class Course {
private String courseName;
private String coursePPT;
private String courseVideo;
private String courseArticle;
//question & answer
private String courseQA;
public Course(CourseBuilder courseBuilder) {
this.courseName = courseBuilder.courseName;
this.coursePPT = courseBuilder.coursePPT;
this.courseVideo = courseBuilder.courseVideo;
this.courseArticle = courseBuilder.courseArticle;
this.courseQA = courseBuilder.courseQA;
}
//內部類
public static class CourseBuilder {
private String courseName;
private String coursePPT;
private String courseVideo;
private String courseArticle;
private String courseQA;
public CourseBuilder buildCourseName(String courseName) {
this.courseName = courseName;
//返回的是本身
return this;
}
public CourseBuilder buildCoursePPT(String coursePPT) {
this.coursePPT = coursePPT;
return this;
}
public CourseBuilder buildCourseVideo(String courseVideo) {
this.courseVideo = courseVideo;
return this;
}
public CourseBuilder buildCourseArticle(String courseArticle) {
this.courseArticle = courseArticle;
return this;
}
public CourseBuilder buildCourseQA(String courseQA) {
this.courseQA = courseQA;
return this;
}
public Course build() {
return new Course(this);
}
}
@Override
public String toString() {
return "Course{" +
"courseName='" + courseName + '\'' +
", coursePPT='" + coursePPT + '\'' +
", courseVideo='" + courseVideo + '\'' +
", courseArticle='" + courseArticle + '\'' +
", courseQA='" + courseQA + '\'' +
'}';
}
}
public class CourseTest {
@Test
public void test() {
Course course = new Course.CourseBuilder()
.buildCourseName("Java設計模式精講")
.buildCoursePPT("Java設計模式精講PPT")
.buildCourseVideo("Java設計模式精講視頻")
.build();
System.out.println(course);
}
}
3 靜態內部類特點
//外部類
public class Out {
//靜態內部類
public static class In {
private int age;
}
}
public class Main {
public static void main(String[] args) {
Out.In a = new Out.In();
System.out.println(System.identityHashCode(a)); //1878246837
Out.In b = new Out.In();
System.out.println(System.identityHashCode(b)); //929338653
}
}
4 源碼分析
//java.lang.StringBuilder
public final class StringBuilder extends AbstractStringBuilder implements java.io.Serializable, CharSequence {
//StringBuffer也是一樣,就是多了一個synchronized
@Override
public StringBuilder append(String str) {
super.append(str);
return this;
}
//<!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
//<dependency>
// <groupId>com.google.guava</groupId>
// <artifactId>guava</artifactId>
// <version>29.0-jre</version>
//</dependency>
@Test
public void test() {
//com.google.common.collect.ImmutableSet
Set<String> set = ImmutableSet.<String>builder()
.add("a")
.add("b")
.build();
System.out.println(set); //[a, b]
//com.google.common.cache.CacheBuilder
LoadingCache<String, String> localCache = CacheBuilder.newBuilder()
.initialCapacity(1000) //cache初始化大小
.maximumSize(10000) //cache的最大容量
.expireAfterAccess(12, TimeUnit.HOURS)//有效期
.concurrencyLevel(5) //併發數
.build(
new CacheLoader<String, String>() {
@Override
public String load(String s) {
return "null";
}
}
);
}
//org.springframework.beans.factory.support.BeanDefinitionBuilder
public final class BeanDefinitionBuilder {
//注意方法的返回值是當前對象
public BeanDefinitionBuilder setFactoryMethod(String factoryMethod) {
this.beanDefinition.setFactoryMethodName(factoryMethod);
return this;
}
@SpringBootApplication
public class VxVideoApplication {
public static void main(String[] args) {
new SpringApplicationBuilder(VxVideoApplication.class)
.web(WebApplicationType.SERVLET)
//還可以設置其他...
.run(args);
}
}
//<dependency>
// <groupId>org.mybatis</groupId>
// <artifactId>mybatis</artifactId>
// <version>3.5.4</version>
//</dependency>
//org.apache.ibatis.session.SqlSessionFactoryBuilder
public class SqlSessionFactoryBuilder {
//裏面再次使用建造者模式
public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
try {
XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
return build(parser.parse());
} catch (Exception e) {
throw ExceptionFactory.wrapException("Error building SqlSession.", e);
} finally {
ErrorContext.instance().reset();
try {
inputStream.close();
} catch (IOException e) {
// Intentionally ignore. Prefer previous error.
}
}
}
public SqlSessionFactory build(Configuration config) {
return new DefaultSqlSessionFactory(config);
}
//<dependency>
// <groupId>org.projectlombok</groupId>
// <artifactId>lombok</artifactId>
// <version>1.18.12</version>
//</dependency>
@Builder //lombok.Builder
public class User {
/**主鍵ID*/
private Long id;
/**用戶名*/
private String userName;
/**密碼*/
private String password;
/**姓名*/
private String name;
/**年齡*/
private Integer age;
/**郵箱*/
private String email;
}
//生產的class如下
public class User {
private Long id;
private String userName;
private String password;
private String name;
private Integer age;
private String email;
User(Long id, String userName, String password, String name, Integer age, String email) {
this.id = id;
this.userName = userName;
this.password = password;
this.name = name;
this.age = age;
this.email = email;
}
public static User.UserBuilder builder() {
return new User.UserBuilder();
}
public static class UserBuilder {
private Long id;
private String userName;
private String password;
private String name;
private Integer age;
private String email;
UserBuilder(){}
public User.UserBuilder id(Long id) {
this.id = id;
return this;
}
public User.UserBuilder userName(String userName) {
this.userName = userName;
return this;
}
public User.UserBuilder password(String password) {
this.password = password;
return this;
}
public User.UserBuilder name(String name) {
this.name = name;
return this;
}
public User.UserBuilder age(Integer age) {
this.age = age;
return this;
}
public User.UserBuilder email(String email) {
this.email = email;
return this;
}
public User build() {
return new User(this.id, this.userName, this.password, this.name, this.age, this.email);
}
public String toString() {
return "User.UserBuilder(id=" + this.id + ", userName=" + this.userName + ", password=" + this.password + ", name=" + this.name + ", age=" + this.age + ", email=" + this.email + ")";
}
}
}
//調用
@Test
public void test() {
User user = User.builder()
.name("喬碧蘿")
.age(58)
.build();
System.out.println(user); //User@61e717c2
}