觀察者模式簡單說就是朝鮮放原子彈,中美俄都知道了
下面通過一個項目中的需求來說明
比如有兩個頁面對用戶登錄敏感,也就是用戶登錄后要有相應的變化.怎么辦?用觀察者
下面看看具體實現(xiàn):
1.首先定義一個用戶登錄的接口
//用戶登錄的接口
public interface onUserLoginListener {
void userLogin();
}
2.然后實現(xiàn)一個該監(jiān)聽的管理類
public class ListenerManager {
//單例
public static volatile ListenerManager instance;
private List<onUserLoginListener> list = new ArrayList<>();
private ListenerManager(){}
public static ListenerManager getInstance(){
if (instance == null){
synchronized (ListenerManager.class){
if (instance == null){
instance = new ListenerManager();
}
}
}
return instance;
}
//添加監(jiān)聽
public void addListener(onUserLoginListener listener){
list.add(listener);
}
//移除監(jiān)聽
public void removeListener(onUserLoginListener listener){
list.remove(listener);
}
//獲取所有的監(jiān)聽
public List<onUserLoginListener> getAllListeners(){
return list;
}
}
3.然后在需要監(jiān)聽用戶登錄的頁面設置監(jiān)聽,比如這里的MainActivity和Main2Activity
public class MainActivity extends AppCompatActivity implements onUserLoginListener {
private TextView tv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//將該頁面添加到監(jiān)聽中
ListenerManager.getInstance().addListener(this);
tv = (TextView) findViewById(R.id.tv);
//去Main2Activity頁面
tv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startActivity(new Intent(MainActivity.this,Main2Activity.class));
}
});
}
//實現(xiàn)onUserLoginListener接口,這里寫用戶登錄后這個頁面的操作
@Override
public void userLogin() {
System.out.println("MainActivity頁面收到了用戶登錄的監(jiān)聽");
}
@Override
protected void onDestroy() {
super.onDestroy();
//移除監(jiān)聽
ListenerManager.getInstance().removeListener(this);
}
}
public class Main2Activity extends AppCompatActivity implements onUserLoginListener{
private TextView tv_login;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
//將該頁面添加到監(jiān)聽中
ListenerManager.getInstance().addListener(this);
tv_login = (TextView) findViewById(R.id.tv_login);
//去登錄頁面
tv_login.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startActivity(new Intent(Main2Activity.this,LoginActivity.class));
}
});
}
@Override
public void userLogin() {
System.out.println("Main2Activity頁面收到了用戶登錄的監(jiān)聽");
}
@Override
protected void onDestroy() {
super.onDestroy();
ListenerManager.getInstance().removeListener(this);
}
}
4.在實現(xiàn)登錄的頁面把登錄的消息發(fā)送給所有的監(jiān)聽者
//登錄頁面
public class LoginActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login2);
}
@Override
protected void onResume() {
super.onResume();
//這里模擬登錄操作,3s后該頁面銷毀,返回上一頁面,登錄成功
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//登錄成功后要通知所有的監(jiān)聽用戶登錄的頁面,這里是關鍵!!!
//ListenerManager記錄了所有監(jiān)聽用戶登錄的頁面,也就是記錄了所有實現(xiàn)了onUserLoginListener接口的類
List<onUserLoginListener> allListeners = ListenerManager.getInstance().getAllListeners();
if (allListeners != null){
for (int i = 0; i < allListeners.size(); i++) {
//每個實現(xiàn)了監(jiān)聽的類都調(diào)用其實現(xiàn)的userLogin()方法,就像MainActivity在收到監(jiān)聽后會調(diào)用其重寫的userLogin()
allListeners.get(i).userLogin();
}
}
finish();
}
}
我們的操作是由MainActivity進入到Main2Activity,再進入到LoginActivity
LoginActivity等待3秒后關閉
最后打印日志:
16:15:38.986 7976-7976/com.dgtech.sss.observedemo I/System.out: MainActivity頁面收到了用戶登錄的監(jiān)聽
16:15:38.986 7976-7976/com.dgtech.sss.observedemo I/System.out: Main2Activity頁面收到了用戶登錄的監(jiān)聽
以上就是觀察者模式的精髓所在,具體實現(xiàn)要根據(jù)需求來寫,不要被網(wǎng)上的各種例子局限.