Java设计模式之单例模式[笔记] 定义 一个类有且仅有一个实例,并且自行实例化向整个系统提供实例调用。
在应用中,单例模式可以使得单例对象保存在JVM中,该对象只有一个实例存在。
应用场景 1. 某些类创建频繁(对于大型对象如果每次都去new对象,将会增大系统开销)
2.省去new操作符,降低内存使用频率,减轻GC(垃圾回收)的压力
3.保证核心功能实例对象可以控制整个系统流程
示例 One
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 package javaClassExercise.designPatterns.singleton;public class Singleton { private static Singleton instance = null ; private Singleton () {} public static Singleton getInstance () { if (instance == null ) { synchronized (Singleton.class) { if (instance == null ) { return new Singleton (); } } } return instance; } public Object readResolve () { return instance; } }
Two 使用一个内部类来维护、创建单例类的实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 package javaClassExercise.designPatterns.singleton;public class CompleteSingleton { private CompleteSingleton () {} private static class SingletonFactory { private static CompleteSingleton instance = new CompleteSingleton (); } public static CompleteSingleton getInstance () { return SingletonFactory.instance; } public Object readResove () { return getInstance(); } }
Three 使用synchronized关键字,提供一个单例类实例创建的方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 package javaClassExercise.designPatterns.singleton;public class SingletonTest { private static SingletonTest instance = null ; private SingletonTest () {} private static synchronized void syncInit () { if (instance == null ) { new SingletonTest (); } } public static SingletonTest getInstance () { if (instance == null ) { syncInit(); } return instance; } }
第二种和第三种大同小异,视情况选择.
实际项目分析 公司内部项目代码简单分析
一条测试case
1 2 3 4 5 6 7 8 9 10 11 public class FinancialServicePageClickTest extends AbstractTestCases { @Test(testName = "xx001", description = "xxxx", groups = "pc") public void ClickJiuDingInvestmentTest () throws Exception { NavigationPage navigationPage = new NavigationPage (driver); EnterprisePCPage enterprisePCPage = navigationPage.clickEnterpriseLink(); FinancialServicePCPage financialServicePCPage = enterprisePCPage.clickFinancialServiceLink(); financialServicePCPage.GoToJiuDingInvestment(); WebReporter.log(driver, driver.getTitle(), true , true ); } }
测试子类FinancialServicePageClickTest
继承自AbstractTestCases
类,父类AbstractTestCases实现了针对APP、PC端的driver的初始化(在执行具体的测试方法前就为测试类中的方法准备好必须的driver)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 @Listeners({ filter.MethodSelector.class }) public class AbstractTestCases { public static WebDriver driver; public static AppiumDriver appiumDirver; @BeforeMethod public void initDriver () throws Exception { switch (ConfigUtil.getConfigUtil().getConfigFileContent("deviceType" )) { case "pc" : driver = DriverFactory.createNewDriver(); break ; case "phone" : appiumDirver = DriverFactory.createAppiumDriver(); break ; default : break ; } } @AfterMethod public void destoryDriver () { switch (ConfigUtil.getConfigUtil().getConfigFileContent("deviceType" )) { case "phone" : WebReporter.log(appiumDirver, true , true , true ); DriverFactory.closeAppiumDriver(); break ; case "pc" : WebReporter.log(driver, driver.getTitle(), true , true ); DriverFactory.CloseDriver(); break ; default : break ; } } public static void logMessage (String str) { Reporter.log(str, 5 , true ); } }
关于TestNG的@Listeners
注解:
看TestNG这个注解的源码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 package org.testng.annotations;import static java.lang.annotation.ElementType.TYPE;import org.testng.IAnnotationTransformer;import org.testng.IAnnotationTransformer2;import org.testng.ITestNGListener;import java.lang.annotation.Retention;import java.lang.annotation.Target;@Retention(java.lang.annotation.RetentionPolicy.RUNTIME) @Target({TYPE}) public @interface Listeners { Class<? extends ITestNGListener >[] value() default {}; }
关于TestNG此注解的详细,可点我查看
关于 TestNG 的详细使用教程, 可参考这篇全英文教程, 很详细. 点我
DriverFactory
类:
使用单例的设计模式实现对driver的初始化,使得在case运行过程中,都保障其操作都是一个driver实例.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 public class DriverFactory { private static WebDriver driver = null ; private static AppiumDriver appiumDriver = null ; private static Logger log = LogFactory.getLogger(DriverFactory.class); private static ConfigUtil configUtil = ConfigUtil.getConfigUtil(); private static String osType = System.getProperty("os.name" ).toLowerCase(); private DriverFactory () { } private static boolean isMacOS () { return osType.indexOf("mac" ) >= 0 ; } private static boolean isWindows () { return osType.indexOf("window" ) >= 0 ; } private static WebDriver CreateBroswerDriver () throws Exception { if (configUtil.getConfigFileContent("isRemoteDriver" ).equals("false" )) { switch (configUtil.getConfigFileContent("broswerType" )) { case "firefox" : return new FirefoxDriver (switchLocalDriverPath()); case "chrome" : return new ChromeDriver (switchLocalDriverPath()); case "ie" : return new InternetExplorerDriver (switchLocalDriverPath()); case "safari" : return new SafariDriver (switchLocalDriverPath()); default : return driver; } } else { URL remoteUrl = new URL (configUtil.getConfigFileContent("remoteDriverURL" )); switch (configUtil.getConfigFileContent("broswerType" )) { case "firefox" : return new RemoteWebDriver (remoteUrl, switchLocalDriverPath()); case "chrome" : return new RemoteWebDriver (remoteUrl, switchLocalDriverPath()); case "ie" : return new RemoteWebDriver (remoteUrl, switchLocalDriverPath()); case "safari" : return new RemoteWebDriver (remoteUrl, switchLocalDriverPath()); default : return driver; } } } public static WebDriver createNewDriver () throws Exception { log.info("Current Driver is null : " + (driver == null )); if (driver == null ) { synchronized (WebDriver.class) { if (driver == null ) { driver = CreateBroswerDriver(); setUpDriverSize(driver).get(configUtil.getConfigFileContent("defaultURL" )); return driver; } } } return driver; } public static WebDriver getCurrentDriver () throws Exception { return createNewDriver(); } public static AppiumDriver createAppiumDriver () throws MalformedURLException { log.info("Current Driver is null : " + (appiumDriver == null )); if (appiumDriver == null ) { synchronized (AppiumDriver.class) { if (appiumDriver == null ) { DesiredCapabilities capabilities = new DesiredCapabilities (); capabilities.setCapability("platformName" , ConfigUtil.getConfigUtil().getConfigFileContent("phonePlatform" )); capabilities.setCapability("platformVersion" , ConfigUtil.getConfigUtil().getConfigFileContent("platformVersion" )); capabilities.setCapability("deviceName" , ConfigUtil.getConfigUtil().getConfigFileContent("deviceName" )); capabilities.setCapability("app" , ConfigUtil.getConfigUtil().getConfigFileContent("applactionLocation" )); if (ConfigUtil.getConfigUtil().getConfigFileContent("phonePlatform" ).equals("iOS" )) { capabilities.setCapability("autoAcceptAlerts" , true ); appiumDriver = new IOSDriver ( new URL (ConfigUtil.getConfigUtil().getConfigFileContent("appiumDriverURL" )), capabilities); } else appiumDriver = new AndroidDriver ( new URL (ConfigUtil.getConfigUtil().getConfigFileContent("appiumDriverURL" )), capabilities); return appiumDriver; } } } return appiumDriver; } public static void CloseDriver () { driver.quit(); driver = null ; } public static void closeAppiumDriver () { appiumDriver.quit(); appiumDriver = null ; } }
在DriverFactory类中,分别实现了对PC Driver的初始化和对APP端包括iOS、Android的Driver初始化,其可以进一步使用抽象工厂设计模式,将其进一步优化.