今回はMediatorパターン。Mediatorは仲介者で、オブジェクト間の連携を一手に担ってくれます。
下例のようなGUIプログラミングによく使われるそうです。MVCモデルに通じますね。
今回はGUIが絡んでいるので、JavaScriptで書いてみました。
JavaScriptはほぼ初挑戦なので、変な実装とかあったら指摘もらえると助かります。
(JavaScriptのOOPってこんなにしんどいんですか?)
実行結果
ソースコード
// id="my_content" のelementがあると仮定している function onLoad(){ var container = document.getElementById("my_content"); var loginform = new LoginForm(); loginform.appendInto(container); } // class declaration function ColleagueInputButton(){ // implements Colleague Interface this.initialize.apply(this, arguments); } ColleagueInputButton.prototype = { initialize: function(caption){ this.content = document.createElement('input'); this.content.setAttribute('type', 'button'); this.content.setAttribute('value', caption); } ,appendInto: function(parentContainer){ parentContainer.appendChild(this.content); } ,setMediator: // Colleague Interface method function(mediator){ this.content.onclick = mediator.onClick; } ,setColleagueEnabled: // Colleague Interface method function(enabled){ this.content.disabled = !enabled; } }; // class declaration function ColleagueInputTextField(){ // implements Colleague Interface this.initialize.apply(this, arguments); } ColleagueInputTextField.prototype = { initialize: function(text, columns, passwordtype){ this.content = document.createElement('input'); if(passwordtype){ this.content.setAttribute('type', 'password'); }else{ this.content.setAttribute('type', 'text'); } this.content.setAttribute('value', text); this.content.setAttribute('size', columns); } ,appendInto: function(parentContainer){ parentContainer.appendChild(this.content); } ,getText: function(){ return this.content.value; } ,setText: function(text){ this.content.value = text; this.content.onchange(); } ,setMediator: // Colleague Interface method function(mediator){ this.content.onchange = mediator.colleagueChanged; } ,setColleagueEnabled: // Colleague Interface method function(enabled){ this.content.disabled = !enabled; if(enabled){ this.content.setAttribute('style', 'background-color: #FFF;'); }else{ this.content.setAttribute('style', 'background-color: #EEE;'); } } }; // class declaration function ColleagueInputRadioButton(){ // implements Colleague Interface this.initialize.apply(this, arguments); } ColleagueInputRadioButton.prototype = { initialize: function(caption, groupname, state){ this.content = document.createElement('input'); this.content.setAttribute('type', 'radio'); this.content.setAttribute('name', groupname); this.content.defaultChecked = state; } ,appendInto: function(parentContainer){ parentContainer.appendChild(this.content); } ,isChecked: function(){ return this.content.checked; } ,setMediator: // Colleague Interface method function(mediator){ this.content.onchange = mediator.colleagueChanged; } ,setColleagueEnabled: // Colleague Interface method function(enabled){ this.content.disabled = !enabled; } }; // class declaration function LoginForm(){ // implements Mediator Interface this.radioGuest = null; this.radioLogin = null; this.textUser = null; this.textPass = null; this.buttonOK = null; this.buttonCancel = null; this.initialize.apply(this, arguments); } LoginForm.prototype = { initialize: function(){ self = this; this.content = document.createElement('form'); this.createColleagues(); this.radioGuest.appendInto(this.content); span = document.createElement('span'); span.innerHTML = "Guest"; this.content.appendChild(span); this.radioLogin.appendInto(this.content); span = document.createElement('span'); span.innerHTML = "Login"; this.content.appendChild(span); this.content.appendChild(document.createElement('br')); span = document.createElement('span'); span.innerHTML = "Username: "; this.content.appendChild(span); this.textUser.appendInto(this.content); this.content.appendChild(document.createElement('br')); span = document.createElement('span'); span.innerHTML = "Password: "; this.content.appendChild(span); this.textPass.appendInto(this.content); this.content.appendChild(document.createElement('br')); this.buttonOK.appendInto(this.content); this.buttonCancel.appendInto(this.content); this.colleagueChanged(); } ,appendInto: function(parentContainer){ parentContainer.appendChild(this.content); } ,createColleagues: // Mediator Interface method function(){ this.radioGuest = new ColleagueInputRadioButton("Guest", "usertype", true); this.radioLogin = new ColleagueInputRadioButton("Login", "usertype", false); this.textUser = new ColleagueInputTextField("", 10); this.textPass = new ColleagueInputTextField("", 10, true); this.buttonOK = new ColleagueInputButton("OK"); this.buttonCancel = new ColleagueInputButton("Cancel"); this.radioGuest.setMediator(this); this.radioLogin.setMediator(this); this.textUser.setMediator(this); this.textPass.setMediator(this); this.buttonOK.setMediator(this); this.buttonCancel.setMediator(this); } ,colleagueChanged: // Mediator Interface method function(){ if(self.radioGuest.isChecked() === true){ self.textUser.setColleagueEnabled(false); self.textPass.setColleagueEnabled(false); self.buttonOK.setColleagueEnabled(true); }else{ self.textUser.setColleagueEnabled(true); // and also needs to check textUser&textPass if(self.textUser.getText().length === 0){ self.textPass.setColleagueEnabled(false); self.buttonOK.setColleagueEnabled(false); }else{ self.textPass.setColleagueEnabled(true); if(self.textPass.getText().length === 0){ self.buttonOK.setColleagueEnabled(false); }else{ self.buttonOK.setColleagueEnabled(true); } } } } ,onClick: function(){ if(this.value === "Cancel"){ self.textUser.setText(""); self.textPass.setText(""); } else{ if(self.radioGuest.isChecked() === true){ alert("Hello, Guest!"); }else{ alert("Hello, "+self.textUser.getText()+"!\nYour pass is "+self.textPass.getText()+", right??"); } } } }; window.onload = onLoad;
0 件のコメント:
コメントを投稿