用观察者模式解决点击一次文章 update一次数据库的问题

本文介绍了一种利用观察者模式减少数据库访问频率的方法。通过缓存点击计数并在达到阈值时批量更新数据库,有效提高了系统性能。

接上文http://xuliangyong.iteye.com/blog/171240

对于第二种方法现用观察着模式来解决

思路是这样:当点击a文章(id=1234)够10次后 ,通知文章管理器更新点击次数

update article set hit_count = hit_count+10 where id = 1234

这样就减少了访问数据库的次数

 

代码如下:

Java代码 
  1. public class HitCached extends Observable{  
  2.     private static final int DEFAULT_MAX_HITS = 10;  
  3.     private Map<Long, Integer> hits = Collections.synchronizedMap(new HashMap<Long, Integer>());  
  4.       
  5.     /** 
  6.      * 最大点击量。超过该值就更新数据库 
  7.      */  
  8.     private int maxHits = DEFAULT_MAX_HITS;  
  9.       
  10.     public HitCached(){}  
  11.       
  12.     public HitCached(int maxHits){  
  13.         this.maxHits = maxHits;  
  14.     }  
  15.       
  16.     public void put(Long key, Integer value){  
  17.         hits.put(key, value);  
  18.     }  
  19.       
  20.     /** 
  21.      * 为指定key 增加指定的点击量 
  22.      * @param hitIncreased 增加的点数  
  23.      */  
  24.     public void addHit(Long key, Integer hitIncreased){  
  25.         if( !hits.containsKey(key) )  
  26.                 hits.put(key, 0);  
  27.         Integer value = hits.get(key);  
  28.         if(value + hitIncreased >= maxHits){  
  29.             setChanged();  
  30.             notifyObservers(KeyValuePair.create(key, value + hitIncreased));  
  31.             hits.remove(key);  
  32.         }else{  
  33.             hits.put(key, value + hitIncreased);  
  34.         }  
  35.           
  36.     }  
  37.       
  38.     public Integer get(Long key){  
  39.         return hits.get(key);  
  40.     }  
  41.       
  42.     public void clear(){  
  43.         hits.clear();  
  44.     }  
  45.       
  46. }  
 
Java代码 
  1. public class ArticleManagerImpl extends HibernateGenericDao<Article, Long> implements ArticleManager ,Oberver{  
  2.       
  3.     public void update(Observable o, Object arg){  
  4.         KeyValuePair keyValue = (KeyValuePair)arg;  
  5.         Article article = this.get(keyValue.getKey());  
  6.         article.setHitCount(article.getHitCount() + keyValue.getValue());  
  7.         save(article);  
  8.     }  
 

 

action中调用

Java代码 
  1. private static HitCached hitCached = new HitCached(5);  
  2.   
  3. public String view() {  
  4.         if (id != null){  
  5.             entity = articleManager.get(id);  
  6.             hitCached.addObserver(articleManager);  
  7.             hitCached.addHit(id, 1);  
  8.         }  
  9. }  

 这样没十次查看才update一次数据库 更新一次缓存 性能得到了大的提升

存在的问题:

停止服务会丢失一些数据 可加一个监听器 来处理

<think>嗯,用户想了解Java中常见的设计模式,特别是单例模式、观察者模式和工厂模式。我需要先回顾一下这些模式的定义和用途,然后整理出清晰的解释和示例代码。 首先,单例模式确保一个类只有一个实例,并提供全局访问点。记得饿汉式和懒汉式的区别,饿汉式在类加载时就创建实例,线程安全;而懒汉式延迟加载,但需要同步处理。用户提供的引用中有几个代码示例,比如引用[2]中的饿汉式实现和引用[3]中的懒汉式示例。需要确认这些代码的正确性,并解释它们的特点。 接下来是工厂模式,它负责对象的创建,将实例化过程封装起来。工厂模式分为简单工厂、工厂方法和抽象工厂。用户的问题中提到工厂模式,可能需要先介绍简单工厂,再说明其他变体。引用[3]提到了工厂模式的基本概念,但需要具体的代码示例。例如,可以创建一个形状工厂,根据输入参数返回不同的形状对象。需要确保示例代码简洁,并说明如何通过工厂类解耦客户端和具体类。 然后是观察者模式,用于对象间的一对多依赖关系,当一个对象状态改变时,所有依赖者都会收到通知。引用中并没有给出具体的观察者模式示例,所以需要自己构造。比如,定义一个主题接口和观察者接口,然后实现具体的主题和观察者类。需要展示如何注册观察者、更新状态和通知观察者的过程。 在整理过程中,要注意引用用户提供的参考文献,例如在单例模式部分引用[1]、[2]、[3]、[4]和[5]。同时,按照用户的要求,所有行内公式用$...$,独立公式用$$...$$,但当前问题可能不需要数学公式,但需要确保LaTeX语法正确,如果有变量或代码中的数学符号的话。 用户要求生成相关问题,可能需要包括设计模式的其他类型、如何选择合适的设计模式、各模式的优缺点比较等。例如,可以问“如何选择单例模式的饿汉式和懒汉式?”或者“观察者模式有哪些实际应用场景?” 还需要检查回答的结构是否清晰,分点解释每个模式,并附上代码示例。确保代码格式正确,使用中文回答,并自然添加引用标识。最后,验证所有引用是否准确对应到提供的参考文献,例如引用[1]提到单例模式的不同实现方式,引用[3]有工厂模式的解释,引用[5]则概述设计模式的基本概念。</think>### Java常见设计模式解析与示例 #### 一、单例模式(Singleton Pattern) **定义**:确保一个类仅有一个实例,并提供全局访问点[^1][^5]。 **适用场景**:日志记录器、配置管理、线程池等需要唯一实例的场景。 ##### 实现方式: 1. **饿汉式** 类加载时立即创建实例,线程安全但可能占用资源。 ```java public class EagerSingleton { private static final EagerSingleton instance = new EagerSingleton(); private EagerSingleton() {} // 私有构造函数 public static EagerSingleton getInstance() { return instance; } } ``` 引用示例:[^2] 2. **懒汉式(线程安全)** 延迟加载,通过`synchronized`保证线程安全,但可能影响性能。 ```java public class LazySingleton { private static LazySingleton instance; private LazySingleton() {} public static synchronized LazySingleton getInstance() { if (instance == null) { instance = new LazySingleton(); } return instance; } } ``` 引用示例:[^3] --- #### 二、工厂模式(Factory Pattern) **定义**:将对象创建逻辑封装在工厂类中,解耦调用方与具体实现类。 **适用场景**:需要灵活扩展对象类型时,如数据库连接、UI组件生成。 ##### 简单工厂示例: ```java // 接口定义 interface Shape { void draw(); } // 具体实现类 class Circle implements Shape { public void draw() { System.out.println("绘制圆形"); } } class Rectangle implements Shape { public void draw() { System.out.println("绘制矩形"); } } // 工厂类 class ShapeFactory { public Shape createShape(String type) { if ("Circle".equals(type)) return new Circle(); else if ("Rectangle".equals(type)) return new Rectangle(); throw new IllegalArgumentException("未知类型"); } } // 使用 public class Client { public static void main(String[] args) { ShapeFactory factory = new ShapeFactory(); Shape circle = factory.createShape("Circle"); circle.draw(); // 输出:绘制圆形 } } ``` 引用示例:[^3][^4] --- #### 三、观察者模式(Observer Pattern) **定义**:定义对象间的一对多依赖关系,当主题对象状态变化时,自动通知所有观察者[^1]。 **适用场景**:事件驱动系统、消息订阅、GUI事件监听。 ##### 示例代码: ```java // 主题接口 interface Subject { void registerObserver(Observer o); void notifyObservers(String message); } // 具体主题类 class NewsPublisher implements Subject { private List<Observer> observers = new ArrayList<>(); public void registerObserver(Observer o) { observers.add(o); } public void notifyObservers(String message) { for (Observer o : observers) { o.update(message); } } } // 观察者接口 interface Observer { void update(String message); } // 具体观察者类 class Subscriber implements Observer { private String name; public Subscriber(String name) { this.name = name; } public void update(String message) { System.out.println(name + " 收到消息:" + message); } } // 使用 public class Client { public static void main(String[] args) { NewsPublisher publisher = new NewsPublisher(); publisher.registerObserver(new Subscriber("用户A")); publisher.registerObserver(new Subscriber("用户B")); publisher.notifyObservers("新文章发布!"); } } ``` 输出: ``` 用户A 收到消息:新文章发布! 用户B 收到消息:新文章发布! ``` 引用示例:[^1] ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值