1.工厂模式出现的原因,即有什么样的需求?
简单的举个例子:好多游戏都存在皮肤的概念,当你换皮肤的时候整个游戏的风格比如按钮、菜单、对话框等等 全部都替换了,再者,当新建一套新的皮肤的时候,要尽量做到无需修改已有的东西。在这一套皮肤中,这都是一系列的产品。如何能实现这样效果?
简单的举个例子:好多游戏都存在皮肤的概念,当你换皮肤的时候整个游戏的风格比如按钮、菜单、对话框等等 全部都替换了,再者,当新建一套新的皮肤的时候,要尽量做到无需修改已有的东西。在这一套皮肤中,这都是一系列的产品。如何能实现这样效果?
工厂模式的概念:为创建对象提供过度接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的。
这是我demo实现的效果:
public static void main(String[] args) {
/**
* 1.当你想换整个一系列产品或者主题的时候 只要改这一个地方就可以了 (将要我把这东西卸载配置文件中 源代码都不用改变 只要改配置文件就好)
* 2.当你想创建自己新的主题时 只要根据创建相应的属性属性就可
* 这就比较偏向于 更容易的扩展 和 更便捷的替换
*/
// AbstarctFactory factory = new BlueThemeFactory();
AbstarctFactory factory = new BlackThemeFactory();
Button button = factory.createButton();
button.click();
Dialog dialog = factory.createDialog();
dialog.tips();
Menu menu = factory.createMenu();
menu.dragger();
}
当我想切换主题的时候 只要改为BlackThemeFactory()即可,或者再想新加一套皮肤的时候同样操作简单。效果如下:
改为BlackThemeFactory()后:
看到了没,当你想替换一整套时改动的地方只要一点就可以了。
首先我认为面向抽象编程在这里的体现就是 1.替换方便 2.扩展容易。
2.怎么去实现呢?
这该怎么说呢,抽象的东西本来就难理解。
先看代码吧。
定义父类的工厂:
/**
* 创建工厂的父类
*/
public abstract class AbstarctFactory {
public abstract Button createButton();
public abstract Dialog createDialog();
public abstract Menu createMenu();
}
按钮:
/**
* 抽象的按钮 定义为抽象
*/
public abstract class Button {
public abstract void click();
}
对话框:
public abstract class Dialog {
public abstract void tips();
}
public abstract class Menu {
public abstract void dragger();
}
黑色主题:
/**
* 产生黑色主题的工厂
*/
public class BlackThemeFactory extends AbstarctFactory {
@Override
public Button createButton() {
return new BlackButton();
}
@Override
public Dialog createDialog() {
return new BlackDialog();
}
@Override
public Menu createMenu() {
return new BlackMenu();
}
}
对应的:
/**
* 黑色按钮
*/
public class BlackButton extends Button {
/**
* 按钮可以点击
*/
@Override
public void click() {
System.out.println("黑色按钮点击");
}
}
/**
* 黑色对话框
*/
public class BlackDialog extends Dialog {
/**
* 可以提示的对话框
*/
@Override
public void tips() {
System.out.println("黑色对话框提示");
}
}
/**
* 黑色菜单
*/
public class BlackMenu extends Menu {
/**
* 可以拖拽的属性
*/
@Override
public void dragger() {
System.out.println("黑色菜单拖拽");
}
}
蓝色主题相关:
/**
* 产生蓝色主题的工厂
*/
public class BlueThemeFactory extends AbstarctFactory{
@Override
public Button createButton() {
return new BlueButton();
}
@Override
public Dialog createDialog() {
return new BuleDialog();
}
@Override
public Menu createMenu() {
return new BlueMenu();
}
}
对应的
/**
* 蓝色按钮
*/
public class BlueButton extends Button{
/**
* 按钮可以点击
*/
@Override
public void click() {
System.out.println("蓝色按钮点击");
}
}
/**
* 蓝色菜单
*/
public class BlueMenu extends Menu {
/**
* 可以拖拽的属性
*/
@Override
public void dragger() {
System.out.println("蓝色菜单拖拽");
}
}
/**
* 蓝色对话框
*/
public class BuleDialog extends Dialog {
/**
* 可以提示的对话框
*/
@Override
public void tips() {
System.out.println("蓝色对话框提示");
}
}
当我们想切换一套主题的时候只要改一点地方就好了:
public class TestAbstractFactory {
public static void main(String[] args) {
/**
* 1.当你想换整个一系列产品或者主题的时候 只要改这一个地方就可以了 (将要我把这东西卸载配置文件中 源代码都不用改变 只要改配置文件就好)
* 2.当你想创建自己新的主题时 只要根据创建相应的属性属性就可
* 这就比较偏向于 更容易的扩展 和 更便捷的替换
*/
// AbstarctFactory factory = new BlueThemeFactory();
AbstarctFactory factory = new BlackThemeFactory();
Button button = factory.createButton();
button.click();
Dialog dialog = factory.createDialog();
dialog.tips();
Menu menu = factory.createMenu();
menu.dragger();
}
}
我觉得的这样代码的扩展性太好了,具体的代码 需要自己认认真真敲一遍,仔细体会面向抽象编程的好处和多态的意义;相关的demo连接如下:
http://download.csdn.net/download/yezhuandroid/10039409
(怎么设置下载不用积分啊)
要注意这一点:
依赖倒置原则:
①不要让一个变量指向一个具体的对象
②尽量不要覆盖父类已有的实现 父类中定义的抽象方法 没有实现,仅仅只是一个指针。
抽象工厂的优缺点是:
优点:
①向客户隐藏了创建对象的细节
②工厂可以自主创建何种产品
③无需修改已有的东西
缺点:
①需要引入抽象层