java設計模式之——建造者模式、原型模式(建立性)【讀書筆記】
一、建造者模式(生成器模式)
定義:將一個複雜物件的構建和它的表示分離開,使得同樣的構建過程可以得到不同的表示。
效果:採用建造者模式,使用者只需要選擇建造的型別就可以得到它們,而具體的建造過程和細節就不需要知道。
示意圖
例項1
1、定義產品類 PersonDemo,使用者端需要得到不同表現形式的產品(瘦的、胖的)。
public class PersonDemo {
public List<String> partList = new ArrayList<String>();
public void addPartA(String partA){
partList.add(partA);
}
public void addPartB(String partB){
partList.add(partB);
}
public void show(){
System.out.println("開始建立產品!");
for(String part:partList){
System.out.println(part);
}
}
}
2、定義建造產品各屬性的建造類介面IPersonBuilder,建立產品的各部分的的不同屬性,和對應的實現類。
public interface IPersonBuilder {
public IPersonBuilder builderPartA();
public IPersonBuilder builderPartB();
public PersonDemo builder();
}
public class PersonBuilderThin implements IPersonBuilder {
private PersonDemo personDemo ;
public PersonBuilderThin (PersonDemo personDemo){
this.personDemo =personDemo ;
}
@Override
public PersonBuilderThin builderPartA() {
personDemo.addPartA("建立瘦人的A部分!");
return this;
}
@Override
public PersonBuilderThin builderPartB() {
// TODO Auto-generated method stub
personDemo.addPartB("建立瘦人的B部分!");
return this;
}
@Override
public PersonDemo builder() {
// TODO Auto-generated method stub
return personDemo;
}
}
public class PersonBuilderFat implements IPersonBuilder{
private PersonDemo personDemo;
public PersonBuilderFat(PersonDemo personDemo){
this.personDemo = personDemo;
}
@Override
public PersonBuilderFat builderPartA() {
// TODO Auto-generated method stub
personDemo.addPartA("建立胖人A部分!");
return this;
}
@Override
public PersonBuilderFat builderPartB() {
// TODO Auto-generated method stub
personDemo.addPartB("建立胖人B部分!");
return this;
}
@Override
public PersonDemo builder() {
// TODO Auto-generated method stub
return personDemo;
}
}
3、定義指揮者類Director,指揮建造者類按照不同規則構建產品類不同屬性,組合成客戶端需要的產品的表現形 態。
public class Director{
public static void construct(IPersonBuilder personBuilder){
personBuilder.builderPartA();
personBuilder.builderPartB();
}
}
4、測試Test,測試例項是否建立成功。
public class Test {
public static void main(String[] args) {
IPersonBuilder personBuilderThin = new PersonBuilderThin(new PersonDemo ());
IPersonBuilder personBuilderFat = new PersonBuilderFat(new PersonDemo ());
Director.construct(personBuilderThin);
Director.construct(personBuilderFat);
PersonDemo personDemoThin = personBuilderThin.builder();
PersonDemo personDemoFat = personBuilderFat.builder();
personDemoThin.show();
personDemoFat.show();
}
}
例項2
也可以省略指揮者類,再構建的時候按照不同的順序建立客戶端需要產品不同部分的表現形式。
public class Person {
private String header;
private String body;
private String leg;
public Person(Builder builder){
this.header=builder.header;
this.body=builder.body;
this.leg=builder.leg;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return this.header+"----"+this.body+"----"+this.leg;
}
static class Builder{
private String header;
private String body;
private String leg;
public Builder builderHeader(String header){
this.header = header;
return this;
}
public Builder builderBody(String body){
this.body = body;
return this;
}
public Builder builderLeg(String leg){
this.leg = leg;
return this;
}
public Person builderPerson(){
return new Person(this);
}
}
public static void main(String[] args) {
Person person = new Builder().builderHeader("頭").
builderBody("身體").builderLeg("腿").builderPerson();
System.out.println(person.toString());
}
}
總結
1、當建立比較複雜的物件時,又不想知道建立物件內部的具體實現細節。
2、當新增一個具體物件時,只要新增一個具體的建立者類就行,符合軟體設計的開閉原則。
3、程式碼的設計過程更加的規範,降低了出錯的機率。
二、原型模式
定義:所謂原型模式就是用原型例項指定建立物件的種類,並且通過複製這些原型建立新的物件。
淺拷貝:使用一個已知例項對一個新的例項各屬性逐一賦值,這種方式稱為淺拷貝。
深拷貝:對一個已知例項進行拷貝時,不僅對各屬性值進行逐一賦值,而且對引用變數建立新例項並逐一賦值。
示意圖
例項
通過繼承Cloneable類實現淺拷貝
public class Person implements Cloneable{
private Name name;
private int age;
private int sex;
public Name getName() {
return name;
}
public void setName(Name name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getSex() {
return sex;
}
public void setSex(int sex) {
this.sex = sex;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", sex=" + sex + "]";
}
/**
* 克隆該例項
*/
public Object clone(){
Person resume = null;
try {
resume = (Person) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return resume;
}
}
public class Name {
private String englishName;
private String chineseName;
public String getEnglishName() {
return englishName;
}
public void setEnglishName(String englishName) {
this.englishName = englishName;
}
public String getChineseName() {
return chineseName;
}
public void setChineseName(String chineseName) {
this.chineseName = chineseName;
}
}
public class Test {
public static void main(String[] args) {
Name name1 = new Name();
name1.setChineseName("小明");
name1.setEnglishName("xiaoming");
Person person1 = new Person();
person1.setAge(18);
person1.setName(name1);
person1.setSex(1);
System.out.println("person1: "+person1);
Person person2 = (Person)person1.clone();
person1.setName(null);
System.out.println("person2: "+person2);
}
}
通過繼承Cloneable類實現深拷貝,修改Name和Person類
public class Name implements Cloneable{
private String englishName;
private String chineseName;
public String getEnglishName() {
return englishName;
}
public void setEnglishName(String englishName) {
this.englishName = englishName;
}
public String getChineseName() {
return chineseName;
}
public void setChineseName(String chineseName) {
this.chineseName = chineseName;
}
@Override
public Object clone(){
Object name = null;
try {
name = (Name) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return name;
}
}
Person類,修改克隆方法
/**
* 克隆該例項
*/
@Override
public Object clone(){
Person resume = null;
try {
resume = (Person) super.clone();
resume.name=(Name)resume.name.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return resume;
}