一、建造者模式(生成器模式)
定义:将一个复杂对象的构建和它的表示分离开,使得同样的构建过程可以得到不同的表示。
效果:采用建造者模式,用户只需要选择建造的类型就可以得到它们,而具体的建造过程和细节就不需要知道。
示意图
实例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;
}