[设计模式]3.2工厂模式
一、C++的浅拷贝与深拷贝对比Java的浅克隆与深克隆案例
C++部分
#include<iostream>
#include<string>
using namespace std;
class Email {
private:
string title;
/*这里是一个指针,当经行拷贝时,会产生另一个指针也指向它堆对应的地址。
当用户删除原来的指针时,会把对象里面的这个指针也删除,那么此时,第二个指向里面的对象就会丢失对象中的int指针。
*/
int* pNumber;
public:
Email(string title) {
this->title = title;
this->pNumber = new int(666);
}
Email(const Email& email) {
this->title = email.title;
this->pNumber = email.pNumber;
}
~Email() {
delete pNumber;
}
};
int main() {
Email e1("message");
Email e2 = e1;
return 0;
}
Java部分
import java.util.ArrayList;
import java.util.List;
public class Student implements Cloneable{//想要拷贝就得实现这个接口
private String name;
private int age;
private String gender;
private List<String> friends;
public Student clone() throws CloneNotSupportedException{
Student student=(Student) super.clone();
List<String> new_friends=new ArrayList<String>();//在这里自己重新开辟一个新的对象,把新的对象赋给新cpoy的Students
for(String friends:this.getFriends()){
new_friends.add(friends);//把以前的list中的数据拷贝到新的friends中去
}
student.setFriends(new_friends);
return student;//把加工后的student返回
}
//set、get方法略
}
////////////////////////////////////////////////////////////////////////////
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
Student s1=new Student();
/*Student s2=s1;
System.out.println(s1==s2);//true,指向的是堆里面的同一个对象的地址*/
//继承了Cloneable方法
List<String> friends=new ArrayList<String>();
friends.add("swift");
friends.add("jack");
s1.setFriends(friends);
Student s2=s1.clone();//调用Java给的克隆方法实现克隆
System.out.println(s1==s2);//false
System.out.println(s1.getFriends());//[swift, jack]
System.out.println(s2.getFriends());//[swift, jack]
friends.add("newFriend");
s1.setFriends(friends);//对s1更改,看s2是否变化
System.out.println(s1.getFriends());
System.out.println(s2.getFriends());//s2也变了,说明两个对象指向的是同一个friends对象
//对clone方法更改后,发现s2没有变化了,说明他们两个student对象独立了
/*false
[swift, jack]
[swift, jack]
[swift, jack, newFriend]
[swift, jack]*/
}
}
二、建造者模式
1、建造者(Builder)模式的定义
是指将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示,这样的设计模式被称为建造者模式。它是将一个复杂的对象分解为多个简单的对象,然后一步一步构建而成。它将变与不变相分离,即产品的组成部分是不变的,但每一部分是可以灵活选择的。
2、模式的结构
建造者(Builder)模式的主要角色:
-
产品角色(Product):它是包含多个组成部件的复杂对象,由具体建造者来创建其各个零部件。
-
抽象建造者(Builder):它是一个包含创建产品各个子部件的抽象方法的接口,通常还包含一个返回复杂产品的方法 getResult()。
-
具体建造者(Concrete Builder):实现 Builder 接口,完成复杂产品的各个部件的具体创建方法。
-
指挥者(Director):它调用建造者对象中的部件构造与装配方法完成复杂对象的创建,在指挥者中不涉及具体产品的信息。
3、 模式的实现
(1) 产品角色:包含多个组成部件的复杂对象。
//Actor类
public class Actor {
private String type;
private String sex;
private String face;
private String costume;
private String hairstyle;
//set.get方法略
}
(2) 抽象建造者:包含创建产品各个子部件的抽象方法。
//ActorBuilder 类
public abstract class ActorBuilder {
Actor actor = new Actor(); //创建角色对象
public abstract void BuildType();
public abstract void BuildSex();
public abstract void BuildFace();
public abstract void BuildCostume();
public abstract void BuildHairstyle();
//返回角色对象
public Actor CreateActor(){
return actor;
}
}
(3) 具体建造者:实现了抽象建造者接口。
//DevilBuilder类
public class DevilBuilder extends ActorBuilder{
@Override
public void BuildType() {
this.actor.setType("恶魔");
}
@Override
public void BuildSex() {
this.actor.setSex("男");
}
// BuildFace()、BuildCostume()、BuildHairstyle()省略
@Override
public Actor CreateActor() {
BuildType();BuildSex();BuildFace();BuildCostume();BuildHairstyle();
return this.actor;
}
////////////////////////////////////////
//AngelBuilder类
public class AngelBuilder extends ActorBuilder{
//省略。。。
}
(4) 指挥者:调用建造者中的方法完成复杂对象的创建。
//ActorController类
public class ActorController {
public Actor Construct(ActorBuilder ab){
return ab.CreateActor();
}
}
(5) 客户类。
// Client测试类
public class Client {
public static void main(String[] args) {
ActorController ac = new ActorController();
ActorBuilder ab = new DevilBuilder();
Actor actor = ac.Construct(ab);
System.out.println(actor);
}
}
4、建造者模式和工厂模式的区别
区别:
- 建造者模式更加注重方法的调用顺序,工厂模式注重创建对象。
- 创建对象的力度不同,建造者模式创建复杂的对象,由各种复杂的部件组成,工厂模式创建出来的对象都一样
- 关注重点不一样,工厂模式只需要把对象创建出来就可以了,而建造者模式不仅要创建出对象,还要知道对象由哪些部件组成。
- 建造者模式根据建造过程中的顺序不一样,最终对象部件组成也不一样。