應用場景:
用java寫一個服務端程式,可以接受訂閱和取消訂閱,或拉取,和主動推送。初步一想,似乎很簡單,但做成容易擴充和類似架構結構,就沒那麼随意設計了。當然,本人也是個新手,閱讀了設計模式一書中的觀察者模式,不斷寫一些小demo,為了充分了解面向接口面層,也是從定義頂層接口入手了。
功能說明:
貼測試類代碼了。注釋很明白了。
public static void main(String[] args) {
//init register
//1.currentTObserver,displyTObserver兩個觀察者(用戶端)。
CurrentTObserver currentTObserver=new CurrentTObserver("CurObserver1");
DisplyTObserver displyTObserver=new DisplyTObserver("DisObserver");
//2.兩個觀察者(用戶端)訂閱了不同類型,品種的資料。currentTObserver訂閱了兩種個容器的資料,另外一個隻訂閱了天氣容器中的資料。
WeatherSubjectContainer.getInstance().registerObserver(currentTObserver);
WeatherSubjectContainer.getInstance().registerObserver(displyTObserver);
CarSubjectContainer.getInstance().registerObserver(currentTObserver);
//3.WeatherSubjectContainer和CarSubjectContainer兩種資料發生了改變的時候,調用自己的dateChange方法,兩個用戶端就可以收到對應資料了。
//4.擴充資料品種增加一個container,增加一種資料類型即可。
int te = 1;
int hum = 3;
while (true) {
try {
Thread.sleep(1000);
System.out.println(" data rescore push data ...");
te++;
hum++;
WeaterDate weaterDate = new WeaterDate("WD_DATA");
weaterDate.setTemperature(te);
weaterDate.setHumidity(hum);
WeatherSubjectContainer.getInstance().dateChange(weaterDate);
CarDate carDate = new CarDate("CAR_DATA");
carDate.setCarNum("CarA0000");
carDate.setCarStatus("空");
CarSubjectContainer.getInstance().dateChange(carDate);
//模拟取消訂閱
if (te>5){
WeatherSubjectContainer.getInstance().rmoveObserver(currentTObserver);
}
System.out.println("WE->"+WeatherSubjectContainer.getInstance().getMapSize());
System.out.println("Cr->"+CarSubjectContainer.getInstance().getMapSize());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
1.項目結構:
2.結構說明:
core包中包括兩個頂層接口,一個主題抽象類,資料的抽象類,基類,觀察者的基類。所有的相關的新寫的對象都要繼承或實作其中的特有方法。model包中定義資料具體類,繼承BaseDate,observer包中是所有觀察者,自己定義,需要繼承BaseTobserver類。subject包中就是資料容器了。資料添加進容器不在這裡讨論了。
3.核心如下代碼:其中沒使用到的方法和接口中的内容是為了擴充應用。實際是用不到可以削減方法。後面的subject和model,就看實際業務資料怎麼樣就怎麼寫了。做好繼承就行。觀察者的話,接收到資料分類處理即可。
public abstract class BaseDate {
private String dataId;
public BaseDate(String dataId) {
this.dataId = dataId;
}
public String getDataId() {
return dataId;
}
public void setDataId(String dataId) {
this.dataId = dataId;
}
}
public abstract class BaseToserver implements TObserver {
private String observerId;
public BaseToserver(String observerId) {
this.observerId = observerId;
}
public abstract void update(BaseDate baseDate);
public abstract void init(BaseDate baseDate);
public String getObserverId() {
return observerId;
}
public void setObserverId(String observerId) {
this.observerId = observerId;
}
}
public abstract class Subject implements TObservable {
public static Logger LOG = LoggerFactory.getLogger(Subject.class);
private BaseDate data;
private ConcurrentHashMap<String, BaseToserver> submap = new ConcurrentHashMap<>();
@Override
public void registerObserver(BaseToserver o) {
submap.put(o.getObserverId(), o);
}
@Override
public void rmoveObserver(BaseToserver o) {
if (submap.containsKey(o.getObserverId())) {
submap.remove(o.getObserverId());
} else {
LOG.error(" remove failed " + o.getObserverId());
}
}
@Override
public void notifyObsevers() {
Set<Map.Entry<String, BaseToserver>> entrySet = submap.entrySet();
for (Map.Entry<String, BaseToserver> entry : entrySet
) {
entry.getValue().update(data);
}
}
@Override
public void dateChange(BaseDate o) {
this.data = o;
notifyObsevers();
}
public int getMapSize() {
return submap.size();
}
}
public interface TObservable {
public void registerObserver(BaseToserver o);
public void rmoveObserver(BaseToserver o);
public void notifyObsevers();
public void dateChange(BaseDate o);
}
public interface TObserver<T> {
public void TestHandle();
}
public class CarDate extends BaseDate{
public CarDate(String dateId) {
super(dateId);
}
private String carNum;
private String carStatus;
public String getCarNum() {
return carNum;
}
public void setCarNum(String carNum) {
this.carNum = carNum;
}
public String getCarStatus() {
return carStatus;
}
public void setCarStatus(String carStatus) {
this.carStatus = carStatus;
}
}
public class CurrentTObserver extends BaseToserver {
public CurrentTObserver(String observerId) {
super(observerId);
}
@Override
public void update(BaseDate baseDate) {
if (baseDate instanceof WeaterDate) {
WeaterDate date = (WeaterDate) baseDate;
System.out.println(" Current observer receive WeaterDate-> " + date.getHumidity() + "-" + date.getTemperature());
} else if (baseDate instanceof CarDate) {
CarDate carDate = (CarDate) baseDate;
System.out.println(" Current observer receive carDate> " + carDate.getCarNum() + "-" + carDate.getCarStatus());
}
}
@Override
public void init(BaseDate BaseDate) {
}
@Override
public void TestHandle() {
}
}
public class CarSubjectContainer extends Subject{
private static WeatherSubjectContainer ourInstance = new WeatherSubjectContainer();
public static WeatherSubjectContainer getInstance() {
return ourInstance;
}
}
4.總結:根據設計模式和合理使用抽象類的程式設計設計,還是第一次從這種角度去考慮。感覺很不錯。模型有了,解讀源碼和架構就更舒服了。觀察者和資料類型完整代碼資料下載下傳位址:https://download.csdn.net/download/flybridy/10460374