1.设计模式:
a.使用目的:
提高代码的复用性,代码扩展性
b.单例设计模式(单个对象设计模式):最终保证该类在内存中只有一个对象
1.饿汉式:当类加载的时候,静态变量会被加载,该静态变量会被初始化(立即加载)
public class 类名{
pirvate 类名(){//为了不让外界创建该类对象,我们把构造函数私有
}
private static 类名 变量名=new 类名();//由于静态方法只能直接访问静态成员,因此该变量也必须为静态
public static 类名 getInstance(){//由于外部无法通过对象访问该方法,因此将该方法声明为静态
return 变量名;
}
}
public class Single{
private Single(){}
private static final Single s = new Single();
public static Single getInstance(){
return s;
}
}
2.懒汉式:相对于饿汉式,懒汉式延迟对象的加载,饿汉式是当类加载的时候,本类对象就产生
而懒汉式当调用getInstance()方法的时候才产生对象
/*
* 单例模式懒汉式,对象的延迟加载
* 安全的,高效的应用
*
*
*
*/
public class Single {
private Single(){}
private static Single s = null;
public static Single getInstance(){
if( s == null)
s = new Single();
}
return s;
}
}
多线程启动懒汉式可能会产生多个对象,不能保证对象唯一
分析:
// Thread-0
public static Single getInstance(){
if( s == null){
//1.CPU切换到Thread-0,由于s==null为true,进入if
s = new Single();//3.CPU切换回Thread-0,此时new Single()(Single@654fb)
}
return s;//4.Thread-0执行return 返回s指向的对象
}
// Thread-1
public static Single getInstance(){
if( s == null){
//2.CPU切换到Thread-1,由于s==null为true,进入if
s = new Single();//5CPU切换到Thread-1,此时new Single()(Single@76fc)
}
}
return s;//6.Thread-1执行return 返回s指向的对象
}
最终解决方案:
public class Single {
private Single(){}
private static Single s = null;
public static Single getInstance(){
if(s == null){//当其中一个线程创建完本类的对象后,另外一个线程在执行getInstance()方法
//不需要走同步代码,减少判断是否有锁,直接return
synchronized(Single.class){
if( s == null)//保证多个线程执行getInstance()方法,创建的对象的唯一
s = new Single();
}
}
return s;
}
}
2.工厂设计模式(静态工厂,工厂里面的方法都是静态的)
a.第一种写法:
/*
优点:只创建一个工厂类,里面技能创建狗也能创建猫
缺点:
1.如果新来一种动物,我们需要在createAnimal添加if....else语句
创建新的动物对象
2.无法控制用户传入非动物的类
*/
public abstract class Animal {
public abstract void eat();
}
public class Cat extends Animal{
public void eat(){
System.out.println("猫在吃鱼");
}
}
public class Dog extends Animal {
public void eat() {
System.out.println("狗吃骨头");
}
}
/*
* 工厂类,生产对象,创建对象
* 只创建动物对象,其他对象不做
*/
public class Factory {
//定义方法,创建动物对象
public static Animal createAnimal(String name){
if("cat".equals(name))
return new Cat();
else if ("dog".equals(name))
return new Dog();
return null;
}
}
public class Test {
public static void main(String[] args) {
//直接调用工厂类的静态方法,传递参数,获取对象
Animal a = Factory.createAnimal("cat");
a.eat();
a = Factory.createAnimal("dog");
a.eat();
a = Factory.createAnimal("car");
a.eat();
}
}
b.工厂中使用反射:
/*
优点:避免写一堆if,else语句,根据类的完全限定名来创建对象
缺点:由于createAnimal方法需要接收类名,无法控制用户传递过来的类是非动物类
*/
public class Factory {
public static Animal createAnimal(String className)
throws ClassNotFoundException, InstantiationException,
IllegalAccessException {
Animal a;
try {
a = (Animal) Class.forName(className).newInstance();
} catch (ClassCastException cle) {
return null;
}
return a;
}
}
public class Demo {
public static void main(String[] args) throws Exception {
Animal a1 = Factory.createAnimal("com.itheima.demo.Cat");
a1.eat();
Animal a2 = Factory.createAnimal("com.itheima.demo.Dog");
a2.eat();
Animal a3 = Factory.createAnimal("com.itheima.demo.Cloth");
System.out.println(a3);
}
}
c.多个工厂(每种动物一个工厂)
/*
优点:可以避免前两种的隐患,不让用户传递任何参数,在工厂中写死创建的对象
缺点:每来一种动物,都需要创建一个对应的工厂类
*/
public interface Factory {
public abstract Animal createAnimal();
}
public class CatFactory implements Factory {
@Override
public Animal createAnimal() {
return new Cat();
}
}
public class DogFactory implements Factory {
@Override
public Animal createAnimal() {
return new Dog();
}
}
/*
* 工厂方法设计模式:
* 将每个对象,交给了各自工厂去创建
* 有猫工厂,狗工厂,作用就是建立对象
*/
public class Test {
public static void main(String[] args) {
Factory f = new CatFactory();
Animal a = f.createAnimal();
a.eat();
f = new DogFactory();
a = f.createAnimal();
a.eat();
}
}
|
|