浅谈JAVA设计模式
没有万行的代码量,就不要想搞清楚设计模式。目前本人代码量大约在六千五百行,2016年需要继续努力,尽快完成万行之约。
工作之余需要,下面提前简单讨论一下设计模式。
创建型模式,共五种:工厂模式、抽象工厂模式、单例模式、建造者模式、原型模式。
结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。
1、代理模式
db数据库组件代理ibatis开源组件
1 public static PersistService createPersistClient(String alias) 2 { 3 PersistService service = null; 4 try 5 { 6 service = new PersistServiceProxy(alias); 7 } 8 catch (Exception e) 9 { 10 logger.error("Failed new Instance PersistProxy.", e); 11 } 12 return service; 13 }
PersistService代理PersistServiceProxy(IbatisPersistServiceImpl),减少操作Connection,ResultSet繁琐对象。
2、单例模式
a、实例化线程池使用单例模式
私有化构造方法,对外暴露一个方法创建单例实例,在多线程情况下只允许一个线程处理业务
1 public class BackThreadCaller 2 { 3 4 private static volatile BackThreadCaller instance; 5 private ThreadPoolExecutor pool; 6 private static Logger log = LoggerFactory.getLogger(BackThreadCaller.class); 7 8 private BackThreadCaller() 9 { 10 int corePoolSize = CalendarConsts.getThreadCorePoolSize(); 11 int maximumPoolSize = CalendarConsts.getThreadMaximumPoolSize(); 12 int keepAliveTime = CalendarConsts.getThreadKeepAliveTime(); 13 int QueueSize = CalendarConsts.getThreadQueueSize(); 14 pool = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, TimeUnit.SECONDS, 15 new ArrayBlockingQueue<Runnable>(QueueSize), 16 new ThreadPoolExecutor.DiscardPolicy()); 17 } 18 19 public static BackThreadCaller getInstance() 20 { 21 if (instance == null) 22 { 23 synchronized (BackThreadCaller.class) 24 { 25 if (instance == null) 26 { 27 instance = new BackThreadCaller(); 28 } 29 } 30 } 31 log.info("BackThreadCaller:ActiveCount={}|CompletedTaskCount={}|CorePoolSize={}|LargestPoolSize={}|PoolSize={}|TaskCount={}", 32 instance.getActiveCount(),instance.getCompletedTaskCount(), 33 instance.getCorePoolSize(),instance.getLargestPoolSize(),instance.getPoolSize(), 34 instance.getTaskCount()); 35 return instance; 36 } 37 38 public void startAThread(Thread thread) 39 { 40 try 41 { 42 pool.execute(thread); 43 } 44 catch (Exception e) 45 { 46 log.error("Exception", e); 47 } 48 } 49 50 /** 51 * 开始执行一个线程 52 * @param thread 53 */ 54 public void startAThread(Runnable thread) 55 { 56 try 57 { 58 pool.execute(thread); 59 } 60 catch (Exception e) 61 { 62 log.error("Exception", e); 63 } 64 } 65 66 // 正在执行的线程任务数,本例中如果为2,则可以观察两个office是否可以同时工作 67 public int getActiveCount() 68 { 69 return pool.getActiveCount(); 70 } 71 72 // 返回池中的当前线程数 73 public int getPoolSize() 74 { 75 return pool.getPoolSize(); 76 } 77 78 // 返回核心线程数 79 public int getCorePoolSize() 80 { 81 return pool.getCorePoolSize(); 82 } 83 84 // 返回曾经同时位于池中的最大线程数 85 public int getLargestPoolSize() 86 { 87 return pool.getLargestPoolSize(); 88 } 89 90 // 已经完成的任务总数 91 public long getCompletedTaskCount() 92 { 93 return pool.getCompletedTaskCount(); 94 } 95 96 // 曾经计划的任务总数 97 public long getTaskCount() 98 { 99 return pool.getTaskCount(); 100 } 101 102 }
调用线程池对象
1 public void setTaskMessages(final CalendarBean calendarBean) 2 { 3 BackThreadCaller.getInstance().startAThread(new Runnable(){ 4 public void run(){ 5 //业务处理 6 } 7 }); 8 }
b、写日志
使用单例生成唯一一个日志处理类,同一时间保证一条日志写入队列
3、简单工厂模式
凡是出现了大量的产品需要创建,并且具有共同的接口时,可以通过工厂方法模式进行创建。例如QueueConnectionFactoryMQ连接工厂,UserLogFactory日志处理类工厂,天气预报数据源提供者工厂
1 public class UserLogFactory 2 { 3 public static UserLog create(String userLogType) 4 { 5 if(Contants.Log.USER_CLICK_LOG_TYPE.equals(userLogType)) 6 { 7 return new ClickLog(); 8 } 9 else if(Contants.Log.USER_ACTION_LOG_TYPE.equals(userLogType)) 10 { 11 return new ActionLog(); 12 } 13 return null; 14 } 15 }
4、观察者模式(发布订阅者模式)
统一配置中用到,维持一个tcp长链接进行一个数据的推送,服务端有个保活的功能,每隔两个小时对客户端发起询问
5、装饰者模式
输入输出流
6、责任链模式
tomcat责任链