一.工厂模式
为什么工厂模式中不用父类而要用接口呢?(暂时没想明白)
二.超级工厂模式
1.注意AbstractFoctory是抽象类不能被实例化
AbstractFoctory shapeFactory = FactoryProducer.getFactory("shape");//向下兼容
三.单例模式
1.不考虑多线程
(1)懒汉式(条件判断是否为null)
public class Singleton {
private static Singleton instance=null;
private Singleton() {
}
public static Singleton getInstance(){
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
(2)饿汉式(类装载时实例化)
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton() {
}
public static Singleton getInstance(){
return instance;
}
}
不推荐
2.考虑多线程安全(对线程加锁 synchronized)
对线程加锁用的synchronized关键字,这个关键字的用法主要也分为两种:
一种是加在方法名之前,形如:synchronized methodeName(params){……};
二是声明同步块,形如:synchronized(this){……};
掌握这种 DCL
public class Singleton {
private static Singleton instance;
private final static Object syncLock = new Object();
private Singleton() {
}
public static Singleton getInstance(){
if (instance == null) {
synchronized (syncLock) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
public static Singleton getInstance(){
if (instance == null) {
synchronized (syncLock) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
四.建造者模式
1.建造者模式与工厂模式相比较
(1)建造者模式除了创建出实例以外还关心实例的各个组成,前者的Builder会用一个个简单的类拼凑出一个复杂的类,后者的Factory则是只产生一个简单对象
五.原型模式
原型模式主要用于对象的复制,它的核心是就是类图中的原型类Prototype。Prototype类需要具备以下两个条件:
(1)实现Cloneable接口。在java语言有一个Cloneable接口,它的作用只有一个,就是在运行时通知虚拟机可以安全地在实现了此接口的类上使用clone方法。在java虚拟机中,只有实现了这个接口的类才可以被拷贝,否则在运行时会抛出CloneNotSupportedException异常。
(2)重写Object类中的clone方法。Java中,所有类的父类都是Object类,Object类中有一个clone方法,作用是返回对象的一个拷贝,但是其作用域protected类型的,一般的类无法调用,因此Prototype类需要将clone方法的作用域修改为public类型。
浅克隆(当被克隆对象里面又有其他引用类型的时候会出现问题)
/*
* 书本类型,扮演的是ConcretePrototype角色,而Cloneable扮演Prototype角色
*/
public class Book implements Cloneable {
private String title;// 标题
private ArrayList<String> image = new ArrayList<String>();// 图片名列表
public Book() {
super();
}
/**
* 重写拷贝方法
*/
@Override
protected Book clone() {
try {
Book book = (Book) super.clone();
return book;
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return null;
}
public ArrayList<String> getImage() {
return image;
}
public void addImage(String img) {
this.image.add(img);
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
/**
* 打印内容
*/
public void showBook() {
System.out.println("----------------------Start----------------------");
System.out.println("title:" + title);
for (String img : image) {
System.out.println("image name:" + img);
}
System.out.println("----------------------End----------------------");
}
}
public class Client {
public static void main(String[] args) {
// 1.构建书本对象
Book book1 = new Book();
// 2.编辑书本,添加图片
book1.setTitle("书1");
book1.addImage("图1");
book1.showBook();
// 以原型文档为原型,拷贝一份副本
Book book2 = (Book) book1.clone();
book2.showBook();
// 修改图书副本,不会影响原始书本
book2.setTitle("书2");
book2.showBook();
// 再次打印原始书本
book1.showBook();
}
}
不用new是因为new十分消耗计算机资源
2.深度克隆(当被克隆对象里面有其他引用类型时)
protected AutoTank clone() {
AutoTank autotank = null;
try {
autotank = (AutoTank) super.clone();//强制类型转换
autotank.AutoTankbullets = (ArrayList<Bullet>) AutoTankbullets.clone();//将其它引用类型也clone一次
return autotank;
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}