抽象工厂模式.docx

上传人:b****5 文档编号:2876864 上传时间:2022-11-16 格式:DOCX 页数:33 大小:161.46KB
下载 相关 举报
抽象工厂模式.docx_第1页
第1页 / 共33页
抽象工厂模式.docx_第2页
第2页 / 共33页
抽象工厂模式.docx_第3页
第3页 / 共33页
抽象工厂模式.docx_第4页
第4页 / 共33页
抽象工厂模式.docx_第5页
第5页 / 共33页
点击查看更多>>
下载资源
资源描述

抽象工厂模式.docx

《抽象工厂模式.docx》由会员分享,可在线阅读,更多相关《抽象工厂模式.docx(33页珍藏版)》请在冰豆网上搜索。

抽象工厂模式.docx

抽象工厂模式

抽象工厂模式(3.1)

镇楼

在某些书中使用了二维图说明抽象工厂模式,很好,但是yqj2065不喜欢他们的产品族/产品等级,改成品牌/产品类型。

抽象工厂模式(abstractfactorypattern)较工厂方法模式强大之处,是一个工厂能够创建多个配套的产品。

日常生活中,抽象工厂模式比比皆是。

例如服装厂可以生产配套的上衣/Tops、下装/Bottoms。

电器公司如美的、海尔可以生产其品牌的冰箱、空调、电视机等。

抽象工厂模式的特点就是工厂接口中有两个以上的工厂方法。

[java] viewplaincopy

1.例程 2-6 品牌公司  

2.package creational.factory.abstractFactory;  

3.public class NikeFactory implements IClothingFactory{  

4.    @Override public Tops getTops(){  

5.        return new NikeTops();  

6.    }  

7.    @Override public Bottoms getBottoms(){  

8.        return new NikeBottoms();  

9.    }  

10.}  

抽象工厂模式概念简单,但是编写演示程序是至少要编写10个类(含Client)。

如图所示。

显然的,NikeFactory只会生产NikeTops和NikeBottoms,毕竟品牌公司不是山寨或贴牌公司。

(yqj2065在后面考虑山寨问题)

[java] viewplaincopy

1.package creational.factory.abstractFactory;  

2.public class Client{  

3.    public static void test(){  

4.        IClothingFactory f =(IClothingFactory)tool.God.create("2-6-Factory");  

5.        Tops tops = f.getTops();  

6.        Bottoms bt =f.getBottoms();  

7.        System.out.println(tops.getName());  

8.        System.out.println(bt.getName() );  

9.    }  

10.}  

抽象工厂模式包含4个角色。

抽象工厂角色,如IClothingFactory;具体工厂角色,前者的子类型;抽象产品角色,如Tops和Bottoms;而具体产品角色,是抽象产品角色的子类型。

从Client的角度看,抽象工厂模式下,通过配置文件指定IClothingFactory,从而获得其生产的上衣/Tops,可以再指定其他的厂家,获得其生产裤子/Bottoms;Client仅仅依赖于抽象工厂角色和抽象产品角色;避免代码中的newNikeTops()和newAdidasBottoms。

2.扩展性

IClothingFactory的子类,可以按照需要增添,符合OCP。

另一方面,假设现在的服装厂/IClothingFactory除了生产配套的上衣、裤子外,还生产鞋子/Shoe。

IClothingFactory中需要添加

publicBottomsgetShoe();

Java8之前,接口不能升级。

如果定义了接口,将接口送给客户程序员使用,这时定义的接口就不能修改。

因为在接口中添加一个方法,会导致老版本接口的所有实现类的中断。

如今,在IClothingFactory广泛使用而且非常需要与时俱进地添加getShoe()时,Java8的默认方法(defendermethods,Virtualextensionmethods)如同神奇的后悔药。

[java] viewplaincopy

1.例程 2-7 默认方法  

2.package creational.factory.abstractFactory;  

3.public interface IClothingFactory{  

4.    public Tops getTops();  

5.    public Bottoms getBottoms();  

6.    default public Shoe getShoe(){  

7.        return null;  

8.    }  

9.}  

10.class Client{  

11.    public static void test(){  

12.        IClothingFactory f =(IClothingFactory)tool.God.create("2-6-Factory-Nike");          

13.        //f =(IClothingFactory)tool.God.create("2-6-Factory-Ad");  

14.        Shoe shoe =f.getShoe();  

15.        System.out.println(shoe.getName() );  

16.    }  

17.}  

NikeFactory改写了getShoe(),测试代码中Client可以正常获得Shoe对象;如果指定的具体工厂没有改写了getShoe(),则Shoe对象为null。

接口中添加默认方法,对于没有改写该默认方法的子类,都是一种退化继承——如同鸵鸟是鸟,违反LSP因而违反OCP。

接口中添加默认方法,保证以前的代码能够正常运行——因为以前的代码不可能知道也不存在使用getShoe(),因而保证了向前兼容。

但是,编写新代码时就必须注意,IClothingFactory有方法getShoe(),但是并非其实现类都给出有效的实现。

你凭什么认为IClothingFactory的实例都能够生产鞋子呢?

工厂方法模式(3.3)

工厂方法模式(factorymethodpattern)从2方面认识。

编程技巧:

这是对参数化工厂方法加以改进的经典技术,以多态来重构if-else、switch-case等分支结构。

设计思路:

你一定要注意,工厂方法模式中Client关注的不是的产品(所以静态工厂中Door的例子,不适合),Client关注的是工厂!

1.以多态来重构分支结构

静态工厂的缺点是分支结构,需要增添新的分支时,程序不符合OCP。

[java] viewplaincopy

1.package creational.factory;  

2.public class DoorFactory{  

3.    public static Door getObject(String typeName)   {//int ID  

4.        if(typeName.equals("D1")){  

5.            return new D1();  

6.        }else if(typeName.equals("D2")){  

7.            return new D2();  

8.        }else{  

9.            return null;  

10.        }  

11.    }  

12.}  

13.  

14.package creational.factory;  

15.public class Hand{  

16.    static Door d = null;      

17.    public static void test(){  

18.        d = DoorFactory.getObject("D2") ;  

19.        d.m();  

20.    }  

21.}  

在不使用配置文件和反射机制的情况下,

[java] viewplaincopy

1.interface IDoorFactory {  

2.    public Door createDoor();  

3.}  

4.  

5.class D1Factory implements IDoorFactory {  

6.    public D1 createDoor() {  

7.        return new D1();  

8.    }  

9.}//D2Factory 略  

10.  

11.  

12.public class Client {  

13.    public static void main(String[] args) {  

14.        IDoorFactory factory = new D1Factory();  

15.        Door door= factory.createDoor();//生产D1  

16.        door.m();  

17.    }  

18.}  

将工厂类泛化成抽象类型,以其子类多态地创建不同的产品如Door的子类。

它体现了一种非常重要的思考方式——以多态来重构if-else或switch-case结构。

从重构分支结构的角度看,策略模式与[2.1.3工厂方法模式(3.3)]和[4.2状态模式(5.8)]是三胞胎。

2.颠倒黑白

上面例子中Hand采用工厂方法模式并不令人信服。

Hand避免了依赖Door的具体子类D1、D2等,却变成了依赖具体的D1Factory、D2Factory。

通过依赖注入,可以使得Hand仅仅依赖Factory,但是,这样做不如直接通过依赖注入让Hand依赖抽象类型Door。

编程实践中,通常工厂是Client关注的主体,而工厂生产的产品被Client所忽视。

例如Client开车ICar,不管什么车Client都可以开。

现在,Car要找它的4S店/I4S,Client会关注各种4S店吗?

[java] viewplaincopy

1.interface ICar{ //工厂接口    

2.    public I4S get4S();//管你是那个4S店  

3.    public void move();  

4.}  

5.class BBCar implements ICar{  

6.    public I4S get4S() {  

7.        return new BB4S();  

8.    }  

9.  

10.    public void move(){  

11.        System.out.println("BBCar move");  

12.    }  

13.}//QQCar 略  

14.  

15.interface I4S{      

16.    void doShomthing();  

17.}//实现类略  

18.public class Client{  

19.    public static void main(String[] args) {  

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 幼儿教育 > 幼儿读物

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1