Java设计模式
2016/6/16 13:36:56 SeventeenWen
单例模式
单例模式(Singleton):保证一个类仅有一个实例,并提供一个访问它的全局访问点。
使用场景:
- 要求生成唯一序列号的环境。
- 在整个项目中需要一个共享访问点或共享数据,
- 创建一个对象需要消耗太多系统资源的
懒汉式
懒汉式主要是在第一次被引用时实例对象,它是线程不安全,需要加上同步synchronized方法,
public class SingletonDemo_02 {
private static SingletonDemo_02 singletonDemo_02 =null;
private SingletonDemo_02(){
}
public SingletonDemo_02 getInstance(){
if(singletonDemo_02==null){
singletonDemo_02 =new SingletonDemo_02();
}
return singletonDemo_02;
}
public void say(){
System.out.println("懒汉式");
}
}
饿汉式
饿汉式主要是在类一被加载,对象就已经创建好了,在需要的地方直接get就可以获得。
public class SingletonDemo {
private static final SingletonDemo singletonDemo =new SingletonDemo();
// 私有的构造方法
private SingletonDemo(){
}
public SingletonDemo getInstance(){
return singletonDemo;
}
public void say(){
System.out.println("饿汉式");
}
}
有上限的单例模式
public class SingletonDemo_03 {
private SingletonDemo_03(){
}
private SingletonDemo_03(String name){
nameSinglenton.add(name);
}
// 最多只能有3个实例 定义上限
private static int maxOfSingleton =3;
private static ArrayList<String> nameSinglenton =new ArrayList<String>();
private static ArrayList<SingletonDemo_03> singletonList =new ArrayList<SingletonDemo_03>();
private static int count=0;
static{
for (int i = 0; i < maxOfSingleton; i++) {
singletonList.add(new SingletonDemo_03("单例"+"【"+i+"】"));
}
}
public static SingletonDemo_03 getInstance(){
Random random =new Random();
count = random.nextInt(maxOfSingleton);
return singletonList.get(count);
}
public void say(){
System.out.println(nameSinglenton.get(count));
}
}
工厂方法模式
工厂方法模式
定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法是一个类的实例化延迟到其子类。
工厂方法模式基本的结构
/**
* 定义工厂方法创建对象的抽象类
* @author seventeenWen
*/
public abstract class Product {
//产品的通用方法
void method1();
void method2();
}
/**
*
* 实现产品的类,可以有多个
* @author seventeenWen
*
*/
public class ConcreteProduct implements Product{
public void method1() {
System.out.println("属于自己的方法1");
}
public void method2() {
System.out.println("属于自己的方法2");
}
}
/**
*
* 抽象工厂方法,用来创建对象
* @author seventeenWen
* @param <T>
*
*/
public abstract class Creator {
//创建对象的方法
public abstract <T extends Product> T createProduct(Class<T> c);
}
public class ConcreteCreator extends Creator{
@Override
public <T extends Product> T createProduct(Class<T> c) {
Product product = null;
try{
product = (Product) Class.forName(c.getName()).newInstance();
}catch(Exception e){
e.printStackTrace();
}
return (T) product;
}
}
public class Run {
public static void main(String[] args) {
Creator creator =new ConcreteCreator();
Product product =creator.createProduct(ConcreteProduct.class);
product.method1();
product.method2();
}
}
工厂方法模式的变形
- 简单工厂模式
去除工厂的继承抽象,将创建对象的方法用static修饰,变成:
// public class ConcreteCreator extends Creator{
public class ConcreteCreator {
// @Override
// public <T extends Product> T createProduct(Class<T> c) {
public static <T extends Product> T createProduct(Class<T> c) {
Product product = null;
try{
product = (Product) Class.forName(c.getName()).newInstance();
}catch(Exception e){
e.printStackTrace();
}
return (T) product;
}
}
public class Run {
public static void main(String[] args) {
Product product =CpmcreteCreator.createProduct(ConcreteProduct.class);
product.method1();
product.method2();
}
}
运行的结果没变,但是不符合开闭原则,
简单工厂模式最大的优点是工厂类中包含了必要的逻辑判断,根据客户的选择动态实例化相关类,去除了产品的依赖。
替代单例模式
/**
* 要单例的类
* @author seventeenWen
*
*/
public class Singleton {
private Singleton(){
}
public void doSomething(){
System.out.println("业务");
}
}
通过工厂模式的单例:
public class SingletonFactory {
private static Singleton singleton;
static{
try {
Class cl = Class.forName(Singleton.class.getName());
Constructor ct = cl.getDeclaredConstructor();
ct.setAccessible(true);
singleton = (Singleton) ct.newInstance();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static Singleton getSingleton(){
return singleton;
}
}