A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 小江哥 黑马粉丝团   /  2018-5-23 18:36  /  993 人查看  /  2 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

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();
              }
      }


  


2 个回复

倒序浏览
我来占层楼啊   
回复 使用道具 举报
单例设计模式,只能创建一个对象,让别人调用
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马