• 简洁 Abstract Factory模式(3.1)



    镇楼

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


    抽象工厂模式(abstract factory pattern)较工厂方法模式强大之处。是一个工厂可以创建多个配套的产品。

    日常生活中。抽象工厂模式比比皆是。比如服装厂能够生产配套的上衣/Tops、下装/Bottoms。电器公司如美的、海尔能够生产其品牌的冰箱、空调、电视机等。

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

    例程 2-6 品牌公司
    package creational.factory.abstractFactory;
    public class NikeFactory implements IClothingFactory{
        @Override public Tops getTops(){
            return new NikeTops();
        }
        @Override public Bottoms getBottoms(){
            return new NikeBottoms();
        }
    }
    
    抽象工厂模式概念简单,可是编写演示程序是至少要编写10个类(含Client)。如图所看到的。

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

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

    package creational.factory.abstractFactory;
    public class Client{
        public static void test(){
            IClothingFactory f =(IClothingFactory)tool.God.create("2-6-Factory");
            Tops tops = f.getTops();
            Bottoms bt =f.getBottoms();
            System.out.println(tops.getName());
            System.out.println(bt.getName() );
        }
    }
    

    抽象工厂模式包括4个角色。抽象工厂角色,如IClothingFactory。详细工厂角色,前者的子类型;抽象产品角色,如Tops和Bottoms;而详细产品角色,是抽象产品角色的子类型。

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

    2. 扩展性

    IClothingFactory的子类,能够依照须要增添。符合OCP。

    还有一方面,如果如今的服装厂/IClothingFactory除了生产配套的上衣、裤子外。还生产鞋子/Shoe。

    IClothingFactory中须要加入

    public Bottoms getShoe ();

    Java8之前。接口不能升级。假设定义了接口。将接口送给客户程序猿使用,这时定义的接口就不能改动。由于在接口中加入一个方法,会导致老版本号接口的全部实现类的中断。

    现在,在IClothingFactory广泛使用并且很须要与时俱进地加入getShoe()时。Java8的默认方法(defender methods,Virtualextension methods)如同奇妙的懊悔药。
    例程 2-7 默认方法
    package creational.factory.abstractFactory;
    public interface IClothingFactory{
        public Tops getTops();
        public Bottoms getBottoms();
        default public Shoe getShoe(){
            return null;
        }
    }
    class Client{
        public static void test(){
            IClothingFactory f =(IClothingFactory)tool.God.create("2-6-Factory-Nike");        
            //f =(IClothingFactory)tool.God.create("2-6-Factory-Ad");
            Shoe shoe =f.getShoe();
            System.out.println(shoe.getName() );
        }
    }
    

    NikeFactory改写了getShoe(),測试代码中Client能够正常获得Shoe对象;假设指定的详细工厂没有改写了getShoe()。则Shoe对象为null。

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

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

    可是。编写新代码时就必须注意,IClothingFactory有方法getShoe()。可是并不是事实上现类都给出有效的实现。你凭什么觉得IClothingFactory的实例都可以生产鞋子呢?


  • 相关阅读:
    【原创】kafka consumer源代码分析
    【原创】kafka server源代码分析(二)
    【原创】kafka server源代码分析(一)
    【原创】kafka controller源代码分析(二)
    棋盘格检测
    人脸三维建模A Morphable Model For The Synthesis Of 3D Faces(三维人脸合成的变形模型)
    汉字识别关键技术与应用
    城市研究中的常见数据类型及其应用场景
    OpenCV Sift源码分析
    OpenCV feature2d
  • 原文地址:https://www.cnblogs.com/hrhguanli/p/5041048.html
Copyright © 2020-2023  润新知