抽象的工厂模式

abstract factory pattern

抽象工厂模式的定义:提供一个接口,用于创建相关对象或从属对象的族,而不指定它们的具体类

  • Concrete类在这里意味着什么?
  • 有人能解释在抽象工厂模式中不指定更具体的类的情况下创建对象意味着什么吗?

  • 当客户机需要创建以某种方式相关的对象时,此模式非常有用。如果需要创建相关或依赖对象的族,那么可以使用抽象工厂模式。我们可以在这个模式中使用以下类:

    AbstractFactory:声明用于创建抽象产品的操作的接口

    ConcreteFactory:实现创建具体产品对象的操作

    AbstractProduct:声明产品对象类型的接口

    产品:定义由相应的具体对象创建的产品对象工厂实现抽象产品接口

    客户机:使用AbstractFactory和AbstractProduct类声明的接口

    这里是工厂设计模式的实现。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    interface IWorst
        {
            string Name();
            string Cost();
            string Millage();
        }
        interface IBest
        {
            string Name();
            string Cost();
            string Millage();
        }
        class Splender : IWorst
        {
            public string Name()
            {
                return"Splender";
            }
            public string Cost()
            {
                return"40000 Rupees";
            }
            public string Millage()
            {
                return"70 KM/Lit";
            }
        }
        class platina : IWorst
        {
            public string Name()
            {
                return"Platina";
            }
            public string Cost()
            {
                return"35000 Rupees";
            }
            public string Millage()
            {
                return"90 KM/Lit";
            }
        }
        class Vector : IWorst
        {
            public string Name()
            {
                return"Victor Plus";
            }
            public string Cost()
            {
                return"38000 Rupees";
            }
            public string Millage()
            {
                return"80 KM/Lit";
            }
        }
        class Shine : IWorst
        {
            public string Name()
            {
                return"Shine";
            }
            public string Cost()
            {
                return"45000 Rupees";
            }
            public string Millage()
            {
                return"60 KM/Lit";
            }
        }
        class Karizma : IBest
        {
            public string Name()
            {
                return"Karizma ZMR";
            }
            public string Cost()
            {
                return"115000 Rupees";
            }
            public string Millage()
            {
                return"30 KM/Lit";
            }
        }
        class Plusar : IBest
        {
            public string Name()
            {
                return"Plusar 220";
            }
            public string Cost()
            {
                return"90000 Rupees";
            }
            public string Millage()
            {
                return"35 KM/Lit";
            }
        }
        class Apache : IBest
        {
            public string Name()
            {
                return"Apache 200";
            }
            public string Cost()
            {
                return"85000 Rupees";
            }
            public string Millage()
            {
                return"40 KM/Lit";
            }
        }
        class CBR : IBest
        {
            public string Name()
            {
                return"CBR 250";
            }
            public string Cost()
            {
                return"125000 Rupees";
            }
            public string Millage()
            {
                return"25 KM/Lit";
            }
        }
        interface iBikeFactory
        {
            IBest GetBest();
            IWorst GetWorst();
        }
        class HeroFactory : iBikeFactory
        {
            public IBest GetBest()
            {
                return new Karizma();
            }
            public IWorst GetWorst()
            {
                return new Splender();
            }
        }
        class BajajFactory : iBikeFactory
        {
            public IBest GetBest()
            {
                return new Plusar();
            }
            public IWorst GetWorst()
            {
                return new platina();
            }
        }
        class TVSFactory : iBikeFactory
        {
            public IBest GetBest()
            {
                return new Apache();
            }
            public IWorst GetWorst()
            {
                return new Vector();
            }
        }
        class HondaFactory : iBikeFactory
        {
            public IBest GetBest()
            {
                return new CBR();
            }
            public IWorst GetWorst()
            {
                return new Shine();
            }
        }
        enum MANUFACTURERS
        {
            HERO,
            BAJAJ,
            TVS,
            HONDA
        }
        class BikeTypeChecker
        {
            iBikeFactory factory;
            MANUFACTURERS manu;
            public BikeTypeChecker(MANUFACTURERS m)
            {
                manu = m;
            }
            public void CheckProducts()
            {
                switch (manu)
                {
                    case MANUFACTURERS.HERO:
                        factory = new HeroFactory();
                        break;
                    case MANUFACTURERS.BAJAJ:
                        factory = new BajajFactory();
                        break;
                    case MANUFACTURERS.TVS:
                        factory = new TVSFactory();
                        break;
                    case MANUFACTURERS.HONDA:
                        factory = new HondaFactory();
                        break;
                }
                Console.WriteLine("
    "+manu.ToString() +":

    Best Bike:" +
                factory.GetBest().Name() +"
    Cost :" + factory.GetBest().Cost() +"
    Millage :" + factory.GetBest().Millage()+"

    Worst Bike:" + factory.GetWorst().Name() +"
    Cost :" + factory.GetWorst().Cost() +
               "
    Millage :" + factory.GetWorst().Millage());
            }
        }
        class MainApp
        {
            static void Main(string[] args)
            {
                BikeTypeChecker checker = new BikeTypeChecker(MANUFACTURERS.HERO);
                checker.CheckProducts();
                Console.ReadLine();
                checker = new BikeTypeChecker(MANUFACTURERS.BAJAJ);
                checker.CheckProducts();
                Console.ReadLine();
                checker = new BikeTypeChecker(MANUFACTURERS.HONDA);
                checker.CheckProducts();
                Console.ReadLine();
                checker = new BikeTypeChecker(MANUFACTURERS.TVS);
                checker.CheckProducts();
                Console.Read();
           }
      }


    如果您熟悉.NET,请检查DBProviderFactory类。这个类提供了任何数据库访问的抽象。类定义了用于创建数据库连接、数据库命令等的工厂方法。所有这些方法都再次返回常规抽象类型。依赖于特定的数据库服务器/驱动程序返回连接类或命令类的具体实现取决于工厂的具体实现。例如,SqlClientFactory返回SqlConnectionSqlCommand等,但OracleClientFactory只需通过设置工厂就可以创建OracleConnectionOracleCommand等。您可以单点访问所有依赖于提供程序的类。


    考虑使用工厂模式概念的以下简单代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    #include <iostream>
    #include <string>

    using namespace std;

    // Abstract Base Class
     class Shape {
         public:
            virtual void Draw() = 0;

            // Static class to create objects
            // Change is required only in this function to create a new object type
            static Shape* Create(string type);
     };

     class Circle : public Shape {
         public:
            void Draw() { cout <<"I am circle" << endl; }
            friend class Shape; };

     class Square : public Shape {
         public:
            void Draw() { cout <<"I am square" << endl; }
            friend class Shape; };

     Shape* Shape::Create(string type) {
         if ( type =="circle" ) return new Circle();
         if ( type =="square" ) return new Square();
         return NULL; }

     void main() {

        // Give me a circle    
        Shape* obj1 = Shape::Create("circle");

        // Give me a square    
        Shape* obj2 = Shape::Create("square");

        obj1->Draw();    
        obj2->Draw();
     }

     OUTPUT:
     I am circle
     I am square
  • 现在想象一下,如果形状类在shape.h中,圆形类在circle.h中,方形类在square.h中,因为使用工厂模式,您实际上不需要在circle.hsquare.h中包含main.cpp中。在这里,如果您不使用工厂模式,要使正方形和圆形实例在主视图中,您需要将正方形和圆形concrete classes(即square.h和circle.h)放在main.cpp中。

  • 您不需要包含这两个文件的原因是,创建circlesquare的操作在create成员函数中从main.cpp移动到shape类。


  • 我认为这里的模式是基于一组类。我将它用于类集,这些类通过访问数据库的方式与这些类相关。

    所以我会有一个名为nwindabstractFactory的抽象类。这个类将返回IProductReportory和IOrderRepository的两个抽象方法。您不能直接实现任何东西,但是您的业务逻辑是根据这个抽象工厂和接口编程的。

    然后我将创建iproductrepository和iorderrepository的具体实现。也许它们被称为sqlproductrepository和sqlorderrepository。然后我可以创建一个抽象工厂的具体实现,它的名称类似于nwindsqlfactory。

    也许我会有另一个名为nwindxmlFactory的具体工厂,它可以创建一个xmlProductRepository和xmlOrderRepository。

    然后,我可以在运行时决定要使用抽象工厂的哪个实现。可能是nwindsqlFactory或nwindsxmlFactory,甚至可能是nwindaccessFactory。

    我再次认为,当您有一组相关的类,但您不想针对它们的具体实现进行编程时,它是有效的。

    您可以使用配置设置,该设置将使用反射来实例化您想要的实际实现。你只需要一个设置就可以做到这一点。您只需要指定具体工厂——因为一旦您拥有了具体工厂,它就可以获得所有其他实现。