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