Skip to content

Latest commit

 

History

History
261 lines (209 loc) · 6.02 KB

3个简单设计模式.md

File metadata and controls

261 lines (209 loc) · 6.02 KB

一、单例模式

  • 饿汉式单例

    public class Singleton1{
      private Singleton1(){}
      private static final Singleton1 instance=new Singleton1();
      public static Singleton1 getInstance
        {
          return instance;
        }
    }
  • 懒汉式单例(线程不安全)

    public class Singleton2{
      private Singleton2(){}
      private static Singleton2 instance=null;
      public static Singleton2 getInstance(){
        if(instance==null)
          {
            instance=new Singleton2;
          }
        else
          {
            return instance;
          }
      }
    }
    • 懒汉的加锁实现

      public class Singleton2{
        private Singleton2(){}
        private static Singleton2 instance=null;
        public static synchronized Singleton2 getInstance(){
          if(instance==null)
            {
              instance=new Singleton2;
            }
          else
            {
              return instance;
            }
        }
      }
    • 懒汉的双重判断实现方式

      public class Singleton2{
        private Singleton2(){}
        private static Singleton2 instance=null;
        public static Singleton getInstance() {  
              if (singleton == null) {    
                  synchronized (Singleton.class) {    
                     if (singleton == null) {    
                        singleton = new Singleton();   
                     }    
                  }    
              }    
              return singleton;   
          }  
      }
    • 懒汉的内部类实现方式

    public class Singleton2{
      private Singleton2(){}
      public class InSingleton{
       		private static final Singleton2 INSTANCE=new Singleton2();
      }
      public static final Singleton2 getInstance(){
        return InSingleton.INSTANCE;
      }
    }

    内部类实现方式比双重判断和加锁的方法都好

  • 双判断的懒汉式单例应用

    public class TestSingleton {
    	String name = null;
    
            private TestSingleton() {
    	}
    
    	private static volatile TestSingleton instance = null;
    
    	public static TestSingleton getInstance() {
               if (instance == null) {  
                 synchronized (TestSingleton.class) {  
                    if (instance == null) {  
                       instance = new TestSingleton(); 
                    }  
                 }  
               } 
               return instance;
    	}
    
    	public String getName() {
    		return name;
    	}
    
    	public void setName(String name) {
    		this.name = name;
    	}
    
    	public void printInfo() {
    		System.out.println("the name is " + name);
    	}
    
    }

    对于应用volatile的解释如下:

    应该加上volatile关键字,不加的情况下可能发生下面2、3步骤发生指令重排序,所以只是在内存中开辟一片存储对象的内存后直接返回内存的引用,之后instance便不为空了,但实际操作却还没有执行,这时如果B线程进来看到,就会看到一个不为空但是还没有初始化的对象,返回后使用就会出现错误。所以需要给instance加上volatile。

    创建对象可以分解为如下的3行伪代码

    memory=allocate(); //1:分配对象的内存空间

    ctorInstance(memory); //2:初始化对象 instance=memory; //3:设置instance指向刚分配的内存地址 上面3行代码中的2和3之间,可能会被重排序导致先3后2,

    二、工厂方法模式

    • 代码实例

      public class Demo1{
          public static class LeiFeng
          {
              public void Sweep()
              {
                  System.out.println("扫地");
              }
              public void Wash()
              {
                  System.out.println("洗");
              }
              public void Buy()
              {
                  System.out.println("买");
              }
          }
          public static abstract class IFactory
          {
              public abstract LeiFeng CreatLei();
          }
          public static class Student extends LeiFeng
          {
              public void Sweep()
              {
                  System.out.println("1扫地");
              }
              public void Wash()
              {
                  System.out.println("2洗");
              }
              public void Buy()
              {
                  System.out.println("3买");
              }
          }
          public static class Com extends LeiFeng
          {
      
          }
          public static class StudentFactory extends IFactory
          {
              public LeiFeng CreatLei()
              {
                  return new Student();
              }
          }
          public static class ComFactory extends IFactory
          {
              public LeiFeng CreatLei()
              {
                  return new Com();
              }
          }
      
          public static void main(String[] args) {
              IFactory factory=new StudentFactory();//只需要在这里修改一行就可以改变继承对象
              LeiFeng con=factory.CreatLei();
      
              con.Buy();
              con.Sweep();
              con.Wash();
          }
      }

三、抽象工厂模式

  • 反射+抽象工厂的数据访问程序,实现不用在打码处改就可改变所用数据库,即使加原本没预算的也没关系

    //App.config
    <?xml version="1.0" encoding="utf-8"?>
      <configuration>
      	<appSettings>
      		<add key="DB" value="Sqlserver"/>
      	</appSettings>
      </configuration>
    private static readonly String db=ConfigurationManager.AppSettings["DB"];
    using System.Reflection;
    //一下写主要步骤,传参为主。
    class DataAccess
      {
        public static IUser CreatUser()
          {
            String className=AssemblyName+"."+db+"User";
            return (IUser)Assembly.Load(AssemblyName).CreatInstance(className); 
          }
      public static IDepartment CreatDepartment()
          {
            String className=AssemblyName+"."+db+"Department";
            return 	(IDepartment)Assembly.Load(AssemblyName).CreatInstance(className); 
          }
      }