工厂方法模式(Factory Method)
通过对产品类的抽象使其创建业务主要负责用于创建多类产品的实例
比如解决
现有一个需求,后续可能会在增加一个类似需求,后续可能会在增加一个类似需求······,以此类推;而通过简单工厂类每次都需要添加一个类和修改工厂对象
的问题
需求问题
- 广告投入问题:
(注意每个广告的显示形式是不同的)
- 需求1:添加一个 JAVA 宣传广告;
- 需求2:添加一个 C# 宣传广告;
- 需求3:添加一个 UI 宣传广告;
- 需求n:··· ···
- ⚠ 问题:
每次接入新需求都需要去主动添加一个类并修改工厂方法内部判断
需求1来了 ······
// JAVA的广告 let JAVAAd = function (desc) { this.desc = desc; this.show = function () { var div = document.createElement('div'); div.innerHTML = desc; div.style.color = 'green'; document.getElementById('container').appendChild(div); } } /** * 广告工厂 * @param {string} type 广告类型 * @param {string} desc 广告描述 */ let AdFactory = function (type, desc) { switch (type) { case 'JAVA': return new JAVAAd(desc); } } let javaAd = AdFactory('JAVA', '学了就秃头!!!'); javaAd.show();
需求2来了 ······
// JAVA的广告 let JAVAAd = function (desc) { this.desc = desc; this.show = function () { var div = document.createElement('div'); div.innerHTML = desc; div.style.color = 'green'; document.getElementById('container').appendChild(div); } } // C#的广告 let CSharpAd = function (desc) { this.desc = desc; this.show = function () { var div = document.createElement('div'); div.innerHTML = desc; div.style.color = 'red'; document.getElementById('container').appendChild(div); } } /** * 广告工厂 * @param {string} type 广告类型 * @param {string} desc 广告描述 */ let AdFactory = function (type, desc) { switch (type) { case 'JAVA': return new JAVAAd(desc); case 'C#': return new CSharpAd(desc); } } let javaAd = AdFactory('JAVA', '学了就秃头!!!'); javaAd.show(); let csharpAd = AdFactory('C#', '这个语言可以开发游戏!!!'); csharpAd.show();
需求3来了 ······
// JAVA的广告 let JAVAAd = function (desc) { this.desc = desc; this.show = function () { var div = document.createElement('div'); div.innerHTML = desc; div.style.color = 'green'; document.getElementById('container').appendChild(div); } } // C#的广告 let CSharpAd = function (desc) { this.desc = desc; this.show = function () { var div = document.createElement('div'); div.innerHTML = desc; div.style.color = 'red'; document.getElementById('container').appendChild(div); } } // UI的广告 let UIAd = function (desc) { this.desc = desc; this.show = function () { var div = document.createElement('div'); div.innerHTML = desc; div.style.color = 'blue'; document.getElementById('container').appendChild(div); } } /** * 广告工厂 * @param {string} type 广告类型 * @param {string} desc 广告描述 */ let AdFactory = function (type, desc) { switch (type) { case 'JAVA': return new JAVAAd(desc); case 'C#': return new CSharpAd(desc); case 'UI': return new UIAd(desc); } } let javaAd = AdFactory('JAVA', '学了就秃头!!!'); javaAd.show(); let csharpAd = AdFactory('C#', '这个语言可以开发游戏!!!'); csharpAd.show(); let uiAd = AdFactory('UI', '这也太酷了吧!!!'); uiAd.show();
- 需求n来了 ······
解决上述问题 (来了需求只需要添加对应的需求类和调用方法就可以了,无需修改工厂对象)
/**
* 安全模式创建的广告工厂类 - 安全模式:检测你是否用了new进行实例
* @param {string} type 广告类型
* @param {string} desc 广告描述
*/
let AdFactory = function (type, desc) {
// 判断你是否用了new
if (this instanceof AdFactory) {
var instance = new this[type](desc);
return instance;
} else {
return new AdFactory(type, desc);
}
}
// 广告工厂原型中设置创建所有类型数据对象的基类
AdFactory.prototype = {
// JAVA的广告
JAVAAd: function (desc) {
this.desc = desc;
this.show = function () {
var div = document.createElement('div');
div.innerHTML = desc;
div.style.color = 'green';
document.getElementById('container').appendChild(div);
}
},
// C#的广告
CSharpAd: function (desc) {
this.desc = desc;
this.show = function () {
var div = document.createElement('div');
div.innerHTML = desc;
div.style.color = 'red';
document.getElementById('container').appendChild(div);
}
},
// UI的广告
UIAd: function (desc) {
this.desc = desc;
this.show = function () {
var div = document.createElement('div');
div.innerHTML = desc;
div.style.color = 'blue';
document.getElementById('container').appendChild(div);
}
}
};
let javaAd = new AdFactory('JAVAAd', '【广告需求一】学了就秃头!!!');
javaAd.show();
let csharpAd = AdFactory('CSharpAd', '【广告需求二】这个语言可以开发游戏!!!');
csharpAd.show();
let uiAd = new AdFactory('UIAd', '【广告需求三】这也太酷了吧!!!');
uiAd.show();
来了一大波需求
/**
* 安全模式创建的广告工厂类
* @param {string} type 广告类型
* @param {string} desc 广告描述
*/
let AdFactory = function (type, desc) {
if (this instanceof AdFactory) {
var instance = new this[type](desc);
return instance;
} else {
return new AdFactory(type, desc);
}
}
// 广告工厂原型中设置创建所有类型数据对象的基类
AdFactory.prototype = {
// JAVA的广告
JAVAAd: function (desc) {
this.desc = desc;
this.show = function () {
var div = document.createElement('div');
div.innerHTML = desc;
div.style.color = 'green';
document.getElementById('container').appendChild(div);
}
},
// C#的广告
CSharpAd: function (desc) {
this.desc = desc;
this.show = function () {
var div = document.createElement('div');
div.innerHTML = desc;
div.style.color = 'red';
document.getElementById('container').appendChild(div);
}
},
// UI的广告
UIAd: function (desc) {
this.desc = desc;
this.show = function () {
var div = document.createElement('div');
div.innerHTML = desc;
div.style.color = 'blue';
document.getElementById('container').appendChild(div);
}
}
};
let ads = [
{
type: 'JAVAAd', desc: '【广告需求一】学了就秃头!!!'},
{
type: 'CSharpAd', desc: '【广告需求二】这个语言可以开发游戏!!!'},
{
type: 'UIAd', desc: '【广告需求三】这也太酷了吧!!!'},
];
ads.forEach(ad => {
let adFactory = new AdFactory(ad.type, ad.desc);
adFactory.show();
})