看了百度文库里的“深入浅出设计模式”,觉得写得挺通俗易懂的,新手上路,能够理解一些。不过希望自己能够举一反三再多思考思考。
工厂模式分为3类:
1.简单工厂模式(simple factory):由“工厂类角色”,“抽象产品角色”,“具体产品角色”组成。
2.工厂方法模式(factory method):由“抽象工厂角色”,“具体工厂角色”,“抽象产品角色”,“具体产品角色”
3.抽象工厂模式(abstract factory):最为抽象,最具一般性的。由抽象工厂角色”,“具体工厂角色”,“抽象产品角色”,“具体产品角色”。
介绍个产品族的概念,比如车子,可分成跑车,商务车等类别。跑车就可以理解成一个产品族。
简单工厂模式举例:
//抽象产品角色
public interface Car{
public void drive();
}
//具体产品角色
public class Benz implements Car{
public void drive() {
System.out.println("Driving Benz ");
}
}
public class Bmw implements Car{
public void drive() {
System.out.println("Driving Bmw ");
}
}
//工厂类角色
public class Driver{
//工厂方法.注意返回类型为抽象产品角色
public static Car driverCar(String s)throws Exception {
//判断逻辑,返回具体的产品角色给Client
if(s.equalsIgnoreCase("Benz"))
return new Benz();
else if(s.equalsIgnoreCase("Bmw"))
return new Bmw();
......
else throw new Exception();
。。。
}
}
public class Magnate{
public static void main(String[] args){
try{
//告诉司机我今天坐奔驰
Car car = Driver.driverCar("benz");
//下命令:开车
car.drive();
}
}
从开闭原则(对扩展开放;对修改封闭)上,把简单工厂模式修改成工厂方法模式。我的理解就是本来简单方法模式就是一个大的厂房,你给票据,然后根据你出示的票据给你对应的东西,但是当有新的产品产生的时候,工厂本身多了一个新增产品的过程,这破坏了修改封闭原则。
所以引进工厂方法模式,这就类似先定义好一个空壳工厂,规定好他的业务。然后有对应的工厂去生产对应的产品。如果新增一个产品,只要增加一个生产对应产品的工厂就可以。不需要修改原代码。满足开闭原则。
工厂方法模式举例:
//抽象工厂角色 public interface Driver{ public Car driverCar(); } public class BenzDriver implements Driver{ public Car driverCar(){ return new Benz(); } } public class BmwDriver implements Driver{ public Car driverCar() { return new Bmw(); } } public class Magnate { public static void main(String[] args) { try{ Driver driver = new BenzDriver(); Car car = driver.driverCar(); car.drive(); } …… }
抽象工厂模式 会涉及到产品类的概念,用以上例子,在多品种车下分成跑车,商务车之类,所以需要分支出跑车工厂生产各种品牌的跑车。
抽象工厂模式的优点
- 封装性,每个产品的实现类不是高层模块要关系的,要关心的是什么?是接口,是抽象,它不关心对象是如何创建出来,这由谁负责呢?工厂类,只要知道工厂类是谁,我就能创建出一个需要的对象,省时省力,优秀设计就应该如此。
- 产品族内的约束为非公开状态。例如生产男女比例的问题上,猜想女娲娘娘肯定有自己的打算,不能让女盛男衰,否则女性的优点不就体现不出来了吗?那在抽象工厂模式,就应该有这样的一个约束:每生产1个女性,就同时生产出1.2个男性,这样的生产过程对调用工厂类的高层模块来说是透明的,它不需要知道这个约束,我就是要一个黄色女性产品就可以了,具体的产品族内的约束是在工厂内实现的。
抽象工厂模式的缺点
抽象工厂模式的最大缺点就是产品族扩展非常困难,为什么这么说呢?我们以通用代码为例,如果要增加一个产品C,也就是说有产品家族由原来的2个,增加到3个,看看我们的程序有多大改动吧!抽象类AbstractCreator要增加一个方法createProductC(),然后,两个实现类都要修改,想想看,这在项目中的话,还这么让人活!严重违反了开闭原则,而且我们一直说明抽象类和接口是一个契约,改变契约,所有与契约有关系的代码都要修改,这段代码叫什么?叫“有毒代码”,——只要这段代码有关系,就可能产生侵害的危险!
抽象工厂模式的使用场景
抽象工厂模式的使用场景定义非常简单:一个对象族(或是一组没有任何关系的对象)都有相同的约束,则可以使用抽象工厂模式,什么意思呢?例如一个文本编辑器和一个图片处理器,都是软件实体,但是*nix下的文本编辑器和WINDOWS下的文本编辑器虽然功能和界面都相同,但是代码实现是不同的,图片处理器也是类似情况,也就是具有了共同的约束条件:操作系统类型,于是我们可以使用抽象工厂模式,产生不同操作系统下的编辑器和图片处理器