精华内容
下载资源
问答
  • 抽象工厂模式的意图是
    2022-04-15 21:50:17

    摘自:抽象工厂模式 | 菜鸟教程

    抽象工厂模式

    抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

    在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。

    介绍

    意图:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

    主要解决:主要解决接口选择的问题。

    何时使用:系统的产品有多于一个的产品族,而系统只消费其中某一族的产品。

    如何解决:在一个产品族里面,定义多个产品。

    关键代码:在一个工厂里聚合多个同类产品。

    应用实例:工作了,为了参加一些聚会,肯定有两套或多套衣服吧,比如说有商务装(成套,一系列具体产品)、时尚装(成套,一系列具体产品),甚至对于一个家庭来说,可能有商务女装、商务男装、时尚女装、时尚男装,这些也都是成套的,即一系列具体产品。假设一种情况(现实中是不存在的,要不然,没法进入共产主义了,但有利于说明抽象工厂模式),在您的家中,某一个衣柜(具体工厂)只能存放某一种这样的衣服(成套,一系列具体产品),每次拿这种成套的衣服时也自然要从这个衣柜中取出了。用 OOP 的思想去理解,所有的衣柜(具体工厂)都是衣柜类的(抽象工厂)某一个,而每一件成套的衣服又包括具体的上衣(某一具体产品),裤子(某一具体产品),这些具体的上衣其实也都是上衣(抽象产品),具体的裤子也都是裤子(另一个抽象产品)。

    优点:当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。

    缺点:产品族扩展非常困难,要增加一个系列的某一产品,既要在抽象的 Creator 里加代码,又要在具体的里面加代码。

    使用场景: 1、QQ 换皮肤,一整套一起换。 2、生成不同操作系统的程序。

    注意事项:产品族难扩展,产品等级易扩展。

    实现

    我们将创建 Shape 和 Color 接口和实现这些接口的实体类。下一步是创建抽象工厂类 AbstractFactory。接着定义工厂类 ShapeFactory 和 ColorFactory,这两个工厂类都是扩展了 AbstractFactory。然后创建一个工厂创造器/生成器类 FactoryProducer

    AbstractFactoryPatternDemo 类使用 FactoryProducer 来获取 AbstractFactory 对象。它将向 AbstractFactory 传递形状信息 ShapeCIRCLE / RECTANGLE / SQUARE),以便获取它所需对象的类型。同时它还向 AbstractFactory 传递颜色信息 ColorRED / GREEN / BLUE),以便获取它所需对象的类型。

     下面是实现步骤

    1. 接口实现

      public interface Shape
        {
            void draw();
        }

     2. 创建实现接口的实体类

        public class Rectangle:Shape
        {
            public void draw()
            {
                Console.WriteLine("Inside Rectangle::draw() method.");
            }
        }
       public class Circle : Shape
        {
            public void draw()
            {
                Console.WriteLine("Inside Circle::draw() method.");
            }
        }
       public class Square : Shape
        {
            public void draw()
            {
                Console.WriteLine("Inside Square::draw() method.");
            }

    3.为颜色创建一个接口。

       public interface Color
        {
            void fill();
    
        }

    4.创建实现接口的实体类。

        public class Red : Color
        {
    
            public void fill()
            {
                Console.WriteLine("Inside Red::fill() method.");
            }
        }
      public class Blue : Color
        {
    
            public void fill()
            {
                Console.WriteLine("Inside Blue::fill() method.");
            }
       public class Green : Color
        {
    
            public void fill()
            {
                Console.WriteLine("Inside Green::fill() method.");
            }
        }

    5.为 Color 和 Shape 对象创建抽象类来获取工厂。

      public abstract class AbstractFactory
        {
            public abstract Color getColor(String color);
            public abstract Shape getShape(String shape);
        }

    6. 创建扩展了 AbstractFactory 的工厂类,基于给定的信息生成实体类的对象。

        public class ShapeFactory : AbstractFactory
        {
    
    
            override
            public Shape getShape(String shapeType)
            {
                if (shapeType == null)
                {
                    return null;
                }
                if (shapeType.Trim().ToUpper() == ("CIRCLE").ToUpper())
                {
                    return new Circle();
                }
                else if (shapeType.Trim().ToUpper() == ("RECTANGLE").ToUpper())
                {
                    return new Rectangle();
                }
                else if (shapeType.Trim().ToUpper() == ("SQUARE").ToUpper())
                {
                    return new Square();
                }
                return null;
    
            }
    
            override
            public Color getColor(String color)
            {
                return null;
            }
        }
       public class ColorFactory : AbstractFactory
        {
    
            override
            public Shape getShape(String shapeType)
            {
                return null;
            }
    
            override
            public Color getColor(String color)
            {
                if (color == null)
                {
                    return null;
                }
                if (color.Trim().ToUpper() == "RED".ToUpper())
                {
                    return new Red();
                }
                else if (color.Trim().ToUpper() == "GREEN".ToUpper())
                {
                    return new Green();
                }
                else if (color.Trim().ToUpper() == "BLUE".ToUpper())
                {
                    return new Blue();
                }
    
    
                return null;
            }
        }

    7.创建一个工厂创造器/生成器类,通过传递形状或颜色信息来获取工厂

        public class FactoryProducer
        {
            public static AbstractFactory getFactory(String choice)
            {
                if (choice.Trim().ToUpper() == ("SHAPE").ToUpper())
                {
                    return new ShapeFactory();
                }
                else if (choice.Trim().ToUpper() == ("COLOR").ToUpper())
                {
                    return new ColorFactory();
                }
                return null;
            }
        }

    8.使用 FactoryProducer 来获取 AbstractFactory,通过传递类型信息来获取实体类的对象。

    
    using AbstractFactoryPattern;
    
    //获取形状工厂
    AbstractFactory shapeFactory = FactoryProducer.getFactory("SHAPE");
    
    //获取形状为 Circle 的对象
    Shape shape1 = shapeFactory.getShape("CIRCLE");
    
    //调用 Circle 的 draw 方法
    shape1.draw();
    
    //获取形状为 Rectangle 的对象
    Shape shape2 = shapeFactory.getShape("RECTANGLE");
    
    //调用 Rectangle 的 draw 方法
    shape2.draw();
    
    //获取形状为 Square 的对象
    Shape shape3 = shapeFactory.getShape("SQUARE");
    
    //调用 Square 的 draw 方法
    shape3.draw();
    
    //获取颜色工厂
    AbstractFactory colorFactory = FactoryProducer.getFactory("COLOR");
    
    //获取颜色为 Red 的对象
    Color color1 = colorFactory.getColor("RED");
    
    //调用 Red 的 fill 方法
    color1.fill();
    
    //获取颜色为 Green 的对象
    Color color2 = colorFactory.getColor("GREEN");
    
    //调用 Green 的 fill 方法
    color2.fill();
    
    //获取颜色为 Blue 的对象
    Color color3 = colorFactory.getColor("BLUE");
    
    //调用 Blue 的 fill 方法
    color3.fill();
    
    Console.ReadLine();
    

    运行结果:

     

    更多相关内容
  • 抽象工厂模式(Abstact Factory)是一种常见的软件设计模式。该模式为一个产品族提供了统一的创建接口。当需要这个产品族的某一系列的时候,可以为此系列的产品族创建一个 具体的工厂类。 【意图抽象工厂模式提供...
  • 抽象工厂模式(Abstact Factory)是一种常见的软件设计模式。该模式为一个产品族提供了统一的创建接口。当需要这个产品族的某一系列的时候,可以为此系列的产品族创建一个具体的工厂类。 一、意图 抽象工厂模式提供...
  • 答案是肯定的,抽象工厂模式。 抽象工厂意图 提供一个创建一系列相关或相互依赖对象的接口,而无需制定它们具体的累。 别名 Kit 案例 第三阶段 光生产手机远远不够,还需要生产其他配件,分散到新的工厂成本太高,...
  • 这就是我们要说的抽象工厂模式。 意图 提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。 模型图 逻辑模型: 物理模型: 生活中的例子 抽象工厂的目的是要提供一个创建一系列相关或相互...
  • 抽象工厂模式(Abstract Factory Pattern):属于创建型模式,它提供了一种创建对象的最佳方式。在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类,每个生成的工厂都能按照工厂模式提供...

    抽象工厂模式(Abstract Factory Pattern):属于创建型模式,它提供了一种创建对象的最佳方式。在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类,每个生成的工厂都能按照工厂模式提供对象。
    意图: 提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
    主要解决:主要解决接口选择的问题。
    何时使用:系统的产品有多于一个的产品族,而系统只消费其中某一族的产品。
    如何解决:在一个产品族里面,定义多个产品。
    关键代码: 在一个工厂里聚合多个同类产品。
    优点:当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。抽象工厂模式相较于工厂模式,划分更加明确清晰,面对复杂的生产任务,管理和生产性能会更加高效。
    缺点: 产品族扩展非常困难,要增加一整个系列的某一产品。
    产品等级结构 : 产品等级结构即产品的继承结构,如一个抽象类是电视机,其子类有海尔电视机、海信电视机、TCL电视机,则抽象电视机与具体品牌的电视机之间构成了一个产品等级结构,抽象电视机是父类,而具体品牌的电视机是其子类。
    产品族 : 在抽象工厂模式中,产品族是指由同一个工厂生产的,位于不同产品等级结构中的一组产品,如海尔电器工厂生产的海尔电视机、海尔电冰箱,海尔电视机位于电视机产品等级结构中,海尔电冰箱位于电冰箱产品等级结构中。

    抽象工厂模式包含如下角色

    • AbstractFactory:抽象工厂
    • ConcreteFactory:具体工厂
    • AbstractProduct:抽象产品
    • Product:具体产品
      在这里插入图片描述
      时序图:
      在这里插入图片描述
      应用实例: 对于一个生产水果的工厂,工厂模式主要针对一种水果创建一个涵盖与该水果相关所有业务的工厂(例如:葡萄的运输、保存、加工、包装、售卖等相关业务全部被该工厂承包);而抽象工厂模式主要针对生产其中的某一环节进行创建相应的工厂(例如:运输工厂负责管理所有水果的运输,售卖工厂负责管理所有水果的价格和售卖,库存工厂负责管理所有水果的库存计数等)。
      在这里插入图片描述
      实现代码:
    class FruitClass:
        # 品种工厂
        def get_name(self, name_index):
            if name_index == 0:
                name_object = OrangeClass()
            elif name_index == 1:
                name_object = Hami_MelonClass()
            elif name_index == 2:
                name_object = GrapeClass()
            else:
                name_object = None
    
            return name_object
    
    
    class OrangeClass:
        # 橘子类
        def __init__(self):
            self.name = "橘子"
    
        def print_name(self):
            print("您购买的水果为:%s" % self.name)
    
    
    class Hami_MelonClass:
        # 哈密瓜类
        def __init__(self):
            self.name = "哈密瓜"
    
        def print_name(self):
            print("您购买的水果为:%s" % self.name)
    
    
    class GrapeClass:
        # 葡萄类
        def __init__(self):
            self.name = "葡萄"
    
        def print_name(self):
            print("您购买的水果为:%s" % self.name)
    
    
    class FruitWeight:
        # 称重工厂
        def __init__(self, weight):
            self.weight = float(weight)
    
        def print_weight(self):
            print("该水果的重量为:%.2f千克" % self.weight)
    
    
    class FruitPrice:
        # 价格工厂
        def get_price(self, name_index, variety):
            if name_index == 0:
                price_object = OrangePrice(variety)
            elif name_index == 1:
                price_object = Hami_MelonPrice()
            elif name_index == 2:
                price_object = GrapePrice()
            else:
                price_object = None
    
            return price_object
    
    
    class OrangePrice:
        # 橘子价格类
        def __init__(self, variety):
            self.variety = variety
            if self.variety == 1:
                self.price = 8.5
            else:
                self.price = 11.0
    
        def print_price(self):
            print("该水果的单价为:%.2f元/千克" % self.price)
    
    
    class Hami_MelonPrice:
        # 哈密瓜价格类
        def __init__(self):
            self.price = 24.3
    
        def print_price(self):
            print("该水果的价格为:%.2f元/千克" % self.price)
    
    
    class GrapePrice:
        # 葡萄价格类
        def __init__(self):
            self.price = 16.2
    
        def print_price(self):
            print("该水果的价格为:%.2f元/千克" % self.price)
            return self.price
    
    
    class FruitPack:
        # 包装工厂
        def __init__(self, pack):
            if pack == 1:
                self.pack = "散称"
            else:
                self.pack = "盒装"
    
        def print_pack(self):
            print("该水果的打包方式为:%s" % self.pack)
    
    
    class FruitFactory:
        def __init__(self, name_index, weight, variety, pack):
            # 任务的分配,品种、重量、价格、包装方式
            self.name_object = FruitClass().get_name(name_index)
            self.weight_object = FruitWeight(weight)
            self.price_object = FruitPrice().get_price(name_index, variety)
            self.pack_object = FruitPack(pack)
    
        def print_purchase(self):
            # 计算购买的金额
            money = self.price_object.price * self.weight_object.weight
            print("需要支付的金额共计为:%.2f元" % money)
    
        def show_info(self):
            # 展示最终的购买信息
            self.name_object.print_name()
            self.weight_object.print_weight()
            self.price_object.print_price()
            self.pack_object.print_pack()
            self.print_purchase()
            print("-*-" * 20)
    
    
    class Consumer:
        # 消费者类
        def __init__(self):
            print("-*-" * 20)
            # 输入原始的“购买需求”信息
            self.name = input("请输入你要购买的水果名称:0.橘子 1.哈密瓜 2.葡萄\n")
            self.weight = input("请输入你要购买水果的重量(kg):\n")
            self.variety = input("如果您购买橘子,我们有2种橘子:0.不买橘子 1.甘橘 2.砂糖橘\n")
            self.pack = input("请您选择该水果的包装方式:1.散称 2.盒装\n")
            print("-*-" * 20)
    
        def request(self):
            # 返回相关的购买信息
            return self.name, self.weight, self.variety, self.pack
    
    
    if __name__ == '__main__':
        # 创建顾客
        buyer = Consumer()
        # 拿到顾客的购买信息
        buy_info = buyer.request()
        # 使用水果工厂,传达指令至旗下的子工厂并执行购买操作
        buy_res = FruitFactory(int(buy_info[0]), int(buy_info[1]), int(buy_info[2]), int(buy_info[3]))
        # 购买信息的展示
        buy_res.show_info()
    

    抽象工厂用在车辆织造中。相同的机械装置用来冲压不同的车辆模型的部件(门,面板,车身罩体,挡泥板,以及各种镜子)。聚合了不同机械装置的模型是可配置的,而且在任何时候都可以轻松变更。车辆制造的抽象工厂的例子如下:

    import random
    
    class PetShop:
    
        """A pet shop"""
    
        def __init__(self, animal_factory=None):
            """pet_factory is our abstract factory.  We can set it at will."""
    
            self.pet_factory = animal_factory
    
        def show_pet(self):
            """Creates and shows a pet using the abstract factory"""
    
            pet = self.pet_factory.get_pet()
            print("We have a lovely {}".format(pet))
            print("It says {}".format(pet.speak()))
            print("We also have {}".format(self.pet_factory.get_food()))
    
    # Stuff that our factory makes
    
    class Dog:
    
        def speak(self):
            return "woof"
    
        def __str__(self):
            return "Dog"
    
    
    class Cat:
    
        def speak(self):
            return "meow"
    
        def __str__(self):
            return "Cat"
    
    
    # Factory classes
    
    class DogFactory:
    
        def get_pet(self):
            return Dog()
    
        def get_food(self):
            return "dog food"
    
    
    class CatFactory:
    
        def get_pet(self):
            return Cat()
    
        def get_food(self):
            return "cat food"
    
    
    # Create the proper family
    def get_factory():
        """Let's be dynamic!"""
        return random.choice([DogFactory, CatFactory])()
    
    
    # Show pets with various factories
    
    for i in range(3):
        shop = PetShop(get_factory())
        shop.show_pet()
        print("=" * 20)
    
    ### OUTPUT ###
    # We have a lovely Dog
    # It says woof
    # We also have dog food
    # ====================
    # We have a lovely Dog
    # It says woof
    # We also have dog food
    # ====================
    # We have a lovely Cat
    # It says meow
    # We also have cat food
    # ====================
    
    

    工厂方法和抽象工厂区别

    一开始时使用工厂方法,因为它更简单。如果后来发现应用需要许多工厂方法,那么将创建一系列对象的过程合并在一起更合理,从而最终引入抽象工厂。
    抽象工厂有一个优点,在使用工厂方法时从用户视角通常是看不到的,那就是抽象工厂能够通过改变激活的工厂方法动态地(运行时)改变应用行为。一个经典例子是能够让用户在使用应用时改变应用的观感(比如,Apple风格和Windows风格等),而不需要终止应用然后重新启动。
    实现:在应用中包含一个迷你游戏让用户娱乐娱乐。我们希望至少包含两个游戏, 一个面向孩子,一个面向成人。在运行时,基于用户输入,决定该创建哪个游戏并运行。游戏的创建部分由一个抽象工厂维护。

    class Frog:
    
        def __init__(self, name):
            self.name = name
    
        def __str__(self):
            return self.name
    
        def interact_with(self, obstacle):
            print('{} the Frog encounters {} and {}!'.format(self,
            obstacle, obstacle.action()))
    
    
    class Bug:
    
        def __str__(self):
            return 'a bug'
    
        def action(self):
            return 'eats it'
    
    # FrogWorld类是一个抽象工厂。它的主要责任是游戏的主角和障碍物。保持创建方法的独立和方法名称的普通(例如,make_character(),
    # make_obstacle())让我们可以动态的改变活动工厂(以及活动的游戏)而不设计任何的代码变更。
    class FrogWorld:
    
        def __init__(self, name):
            print(self)
            self.player_name = name
    
        def __str__(self):
            return '\n\n\t------ Frog World -------'
    
        def make_character(self):
            return Frog(self.player_name)
    
        def make_obstacle(self):
            return Bug()
    
    
    class Wizard:
    
        def __init__(self, name):
            self.name = name
    
        def __str__(self):
            return self.name
    
    
        def interact_with(self, obstacle):
            print(
                '{} the Wizard battles against {} and {}!'.format(
                self,
                obstacle,
                obstacle.action()))
    
    
    class Ork:
    
        def __str__(self):
            return 'an evil ork'
    
        def action(self):
            return 'kills it'
    
    
    class WizardWorld:
    
        def __init__(self, name):
            print(self)
            self.player_name = name
    
        def __str__(self):
            return '\n\n\t------ Wizard World -------'
    
        def make_character(self):
            return Wizard(self.player_name)
    
        def make_obstacle(self):
            return Ork()
            
    # GameEnviroment是我们游戏的主要入口。它接受factory作为输入,然后用它创建游戏的世界。
    class GameEnvironment:
    
        def __init__(self, factory):
            self.hero = factory.make_character()
            self.obstacle = factory.make_obstacle()
    
        def play(self):
            self.hero.interact_with(self.obstacle)
    
    def validate_age(name):
        try:
            age = input('Welcome {}. How old are you? '.format(name))
            age = int(age)
        except ValueError as err:
            print("Age {} is invalid, please try again...".format(age))
            return (False, age)
        return (True, age)
    
    def main():
        name = input("Hello. What's your name? ")
        valid_input = False
        while not valid_input:
            valid_input, age = validate_age(name)
        game = FrogWorld if age < 18 else WizardWorld
        environment = GameEnvironment(game(name))
        environment.play()
    
    main()
    
    
    # Hello. What's your name? Nick
    # Welcome Nick. How old are you? 17
    
    
    #   ------ Frog World -------
    # Nick the Frog encounters a bug and eats it!
    

    另一种实现方法:
    https://blog.csdn.net/weixin_51098806/article/details/123928763?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1-123928763-blog-6886039.pc_relevant_default&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1-123928763-blog-6886039.pc_relevant_default&utm_relevant_index=2

    使用场景

    在很多软件系统中需要更换界面主题,要求界面中的按钮、文本框、背景色等一起发生改变时,可以使用抽象工厂模式进行设计。

    抽象工厂模式与工厂方法模式的区别

    工厂方法模式:
    1.一个抽象产品类,可以派生出多个具体产品类
    2.一个抽象工厂类,可以派生出多个具体工厂类
    3.每个具体工厂类,只能创建一个具体产品的实例

    抽象设计模式:
    1.多个抽象产品类,可以派生出多个具体产品类
    2.一个抽象工厂类,可以派生出多个具体工厂类
    3.每个具体工厂类,可以创建多个具体类的实例

    简单工厂模式是客户端用不同的参数通过工厂获取不同的产品实例。
    工厂方法模式是客户端通过工厂的不同实例获取不同的产品实例。
    抽象工厂模式是工厂可以生成不同的产品实例,客户端通过不同实例获取不同的产品。

    总结

    其根本思想就是将产品归类分组,然后将好几组产品构成一族。每个工厂负责生产一族产品,而工厂中的每个方法负责生产一种类型的产品。

    展开全文
  • 抽象工厂设计模式

    Abstract Factory(抽象工厂)

    一、意图

    提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。

    二、结构

    抽象工厂模式的结构如图7-25所示。
    在这里插入图片描述
    其中:
    • AbstiactFactoiy声明一个创建抽象产品对象的操作接口。
    • ConcreteFactoiy实现创建具体产品对象的操作。
    • AbstiactProduct为一类产品对象声明一个接口。
    • ConcieteProduct定义一个将被相应的具体工厂创建的产品对象,实现AbstiactProduct 接口。
    • Client 仅使用由 AbstractFactory 和 AbstractProduct 类声明的接口 。

    三、适用性

    Abstract Factory 模式适用 :
    • 一个系统要独立于它的产品的创建、组合和表示时。
    • 一个系统要由多个产品系列中的一个来配置时。
    • 当要强调一系列相关的产品对象的设计以便进行联合使用时。
    • 当提供一个产品类库,只想显示它们的接口而不是实现时。

    四、实现

    Access数据库中存在User和Department表的CRUD,现需更换DB到SqlServer数据库,提供方便快捷的更换方式
    在这里插入图片描述

    首先 创建用户实体类和部门实体类

    // 用户实体类
     class User {
        private int id;
        private String name;
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }
    
    //部门实体类
    class Department {
         private int id;
         private String deptName;
         public int getId() {
             return id;
         }
         public void setId(int id) {
             this.id = id;
         }
         public String getDeptName() {
             return deptName;
         }
         public void setDeptName(String deptName) {
             this.deptName = deptName;
         }
    
     }
    

    然后 创建用户访问接口和两种数据库对其的实现

    // 用户访问接口
     interface IUser {
        //对数据库操作采取插入和查询(通过ID)
        void insert(User user);
    
        void getUser(int id);
    }
    
    class SqlServerUser implements IUser {
    
        @Override
        public void insert(User user) {
            System.out.println("在SqlServer数据库插入user记录");
        }
    
        @Override
        public void getUser(int id) {
            System.out.println("在SqlServer数据库根据id获取user记录");
        }
    
    }
    
    class AccessUser implements IUser {
    
        @Override
        public void insert(User user) {
            System.out.println("在Access数据库插入user记录");
        }
    
        @Override
        public void getUser(int id) {
            System.out.println("在Access数据库根据id获取user记录");
        }
    
    }
    

    接下来 创建部门访问接口和两种数据库对其的实现

    //部门访问接口
     interface IDepartment {
        void insert(Department dept);
    
        void getDept(String deptName);
    }
    
    class AccessDepartment implements IDepartment {
        @Override
        public void insert(Department dept) {
            System.out.println("在Access数据库插入department记录");
        }
    
        @Override
        public void getDept(String deptName) {
            System.out.println("在Access数据库根据name获取department记录");
        }
    }
    
    class SqlServerDepartment implements IDepartment {
        @Override
        public void insert(Department dept) {
            System.out.println("在SqlServer数据库插入department记录");
        }
    
        @Override
        public void getDept(String deptName) {
            System.out.println("在SqlServer数据库根据name获取department记录");
        }
    }
    

    其次 抽象工厂以及其实现

    //抽象工厂
     interface IFactory {
        IUser createUser();
    
        IDepartment createDepartment();
    }
    
    class SqlServerFactory implements IFactory {
        @Override
        public IUser createUser() {
            return new SqlServerUser();
        }
    
        @Override
        public IDepartment createDepartment() {
            return new SqlServerDepartment();
        }
    }
    
    class AccessFacotry implements IFactory {
    
        @Override
        public IUser createUser() {
            return new AccessUser();
        }
    
        @Override
        public IDepartment createDepartment() {
            return new AccessDepartment();
        }
    }
    

    最后 测试一下

    public class AbstractFactory {
    
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		 	User user = new User();
    		 	user.setId(1);
    	        Department dept = new Department();
    	        dept.setDeptName("sql数据库");
    	        IFactory factory1 = new SqlServerFactory();
    	        IUser iu1 = factory1.createUser();
    	        iu1.insert(user);
    	        iu1.getUser(1);
    	        IDepartment idept1 = factory1.createDepartment();
    	        idept1.insert(dept);
    	        idept1.getDept("sql数据库");
    	        System.out.println("=============================================");
    	        User user2 = new User();
    		 	user2.setId(2);
    	        Department dept2 = new Department();
    	        dept2.setDeptName("access数据库");
    	        IFactory factory2 = new AccessFacotry();
    	        IUser iu2 = factory2.createUser();
    	        iu2.insert(user);
    	        iu2.getUser(2);
    	        IDepartment idept2 = factory2.createDepartment();
    	        idept2.insert(dept);
    	        idept2.getDept("access数据库");
    	}
    
    }
    

    运行结果:
    在这里插入图片描述

    展开全文
  • 抽象工厂模式是一种创建型设计模式,它能创建一系列相关的对象,而无需指定其具体类。 问题 假设你正在开发一款家具商店模拟器。你的代码中包括一些类,用于表示: 一系列相关产品,例如椅子Chair、​...

    意图

    抽象工厂模式是一种创建型设计模式, 它能创建一系列相关的对象, 而无需指定其具体类。

     

     问题

    假设你正在开发一款家具商店模拟器。 你的代码中包括一些类, 用于表示:

    1. 一系列相关产品, 例如 椅子Chair 、 ​ 沙发Sofa和 咖啡桌Coffee­Table 。

    2. 系列产品的不同变体。 例如, 你可以使用 现代Modern 、 ​ 维多利亚Victorian 、 ​ 装饰风艺术Art­Deco等风格生成 椅子 、 ​ 沙发和 咖啡桌 。

     

    系列产品及其不同变体。

    你需要设法单独生成每件家具对象, 这样才能确保其风格一致。 如果顾客收到的家具风格不一样, 他们可不会开心。

     

    现代风格的沙发和维多利亚风格的椅子不搭。

    此外, 你也不希望在添加新产品或新风格时修改已有代码。 家具供应商对于产品目录的更新非常频繁, 你不会想在每次更新时都去修改核心代码的。

     解决方案

    首先, 抽象工厂模式建议为系列中的每件产品明确声明接口 (例如椅子、 沙发或咖啡桌)。 然后, 确保所有产品变体都继承这些接口。 例如, 所有风格的椅子都实现 椅子接口; 所有风格的咖啡桌都实现 咖啡桌接口, 以此类推。

     

    同一对象的所有变体都必须放置在同一个类层次结构之中。

    接下来, 我们需要声明抽象工厂——包含系列中所有产品构造方法的接口。 例如 create­Chair创建椅子 、 ​ create­Sofa创建沙发和 create­Coffee­Table创建咖啡桌 。 这些方法必须返回抽象产品类型, 即我们之前抽取的那些接口: ​ 椅子 , ​ 沙发和 咖啡桌等等。

     

    每个具体工厂类都对应一个特定的产品变体。

    那么该如何处理产品变体呢? 对于系列产品的每个变体, 我们都将基于 抽象工厂接口创建不同的工厂类。 每个工厂类都只能返回特定类别的产品, 例如, ​ 现代家具工厂Modern­Furniture­Factory只能创建 现代椅子Modern­Chair 、 ​ 现代沙发Modern­Sofa和 现代咖啡桌Modern­Coffee­Table对象。

    客户端代码可以通过相应的抽象接口调用工厂和产品类。 你无需修改实际客户端代码, 就能更改传递给客户端的工厂类, 也能更改客户端代码接收的产品变体。

     

    客户端无需了解其所调用工厂的具体类信息。

    假设客户端想要工厂创建一把椅子。 客户端无需了解工厂类, 也不用管工厂类创建出的椅子类型。 无论是现代风格, 还是维多利亚风格的椅子, 对于客户端来说没有分别, 它只需调用抽象 椅子接口就可以了。 这样一来, 客户端只需知道椅子以某种方式实现了 sit­On坐下方法就足够了。 此外, 无论工厂返回的是何种椅子变体, 它都会和由同一工厂对象创建的沙发或咖啡桌风格一致。

    最后一点说明: 如果客户端仅接触抽象接口, 那么谁来创建实际的工厂对象呢? 一般情况下, 应用程序会在初始化阶段创建具体工厂对象。 而在此之前, 应用程序必须根据配置文件或环境设定选择工厂类别。

     抽象工厂模式结构

     

    1. 抽象产品 (Abstract Product) 为构成系列产品的一组不同但相关的产品声明接口。

    2. 具体产品 (Concrete Product) 是抽象产品的多种不同类型实现。 所有变体 (维多利亚/现代) 都必须实现相应的抽象产品 (椅子/沙发)。

    3. 抽象工厂 (Abstract Factory) 接口声明了一组创建各种抽象产品的方法。

    4. 具体工厂 (Concrete Factory) 实现抽象工厂的构建方法。 每个具体工厂都对应特定产品变体, 且仅创建此种产品变体。

    5. 尽管具体工厂会对具体产品进行初始化, 其构建方法签名必须返回相应的抽象产品。 这样, 使用工厂类的客户端代码就不会与工厂创建的特定产品变体耦合。 客户端 (Client) 只需通过抽象接口调用工厂和产品对象, 就能与任何具体工厂/产品变体交互。

     伪代码

    下面例子通过应用抽象工厂模式, 使得客户端代码无需与具体 UI 类耦合, 就能创建跨平台的 UI 元素, 同时确保所创建的元素与指定的操作系统匹配。

     

    跨平台 UI 类示例。

    跨平台应用中的相同 UI 元素功能类似, 但是在不同操作系统下的外观有一定差异。 此外, 你需要确保 UI 元素与当前操作系统风格一致。 你一定不希望在 Windows 系统下运行的应用程序中显示 macOS 的控件。

    抽象工厂接口声明一系列构建方法, 客户端代码可调用它们生成不同风格的 UI 元素。 每个具体工厂对应特定操作系统, 并负责生成符合该操作系统风格的 UI 元素。

    其运作方式如下: 应用程序启动后检测当前操作系统。 根据该信息, 应用程序通过与该操作系统对应的类创建工厂对象。 其余代码使用该工厂对象创建 UI 元素。 这样可以避免生成错误类型的元素。

    使用这种方法, 客户端代码只需调用抽象接口, 而无需了解具体工厂类和 UI 元素。 此外, 客户端代码还支持未来添加新的工厂或 UI 元素。

    这样一来, 每次在应用程序中添加新的 UI 元素变体时, 你都无需修改客户端代码。 你只需创建一个能够生成这些 UI 元素的工厂类, 然后稍微修改应用程序的初始代码, 使其能够选择合适的工厂类即可。

    // 抽象工厂接口声明了一组能返回不同抽象产品的方法。这些产品属于同一个系列
    // 且在高层主题或概念上具有相关性。同系列的产品通常能相互搭配使用。系列产
    // 品可有多个变体,但不同变体的产品不能搭配使用。
    interface GUIFactory is
        method createButton():Button
        method createCheckbox():Checkbox
    
    
    // 具体工厂可生成属于同一变体的系列产品。工厂会确保其创建的产品能相互搭配
    // 使用。具体工厂方法签名会返回一个抽象产品,但在方法内部则会对具体产品进
    // 行实例化。
    class WinFactory implements GUIFactory is
        method createButton():Button is
            return new WinButton()
        method createCheckbox():Checkbox is
            return new WinCheckbox()
    
    // 每个具体工厂中都会包含一个相应的产品变体。
    class MacFactory implements GUIFactory is
        method createButton():Button is
            return new MacButton()
        method createCheckbox():Checkbox is
            return new MacCheckbox()
    
    
    // 系列产品中的特定产品必须有一个基础接口。所有产品变体都必须实现这个接口。
    interface Button is
        method paint()
    
    // 具体产品由相应的具体工厂创建。
    class WinButton implements Button is
        method paint() is
            // 根据 Windows 样式渲染按钮。
    
    class MacButton implements Button is
        method paint() is
            // 根据 macOS 样式渲染按钮
    
    // 这是另一个产品的基础接口。所有产品都可以互动,但是只有相同具体变体的产
    // 品之间才能够正确地进行交互。
    interface Checkbox is
        method paint()
    
    class WinCheckbox implements Checkbox is
        method paint() is
            // 根据 Windows 样式渲染复选框。
    
    class MacCheckbox implements Checkbox is
        method paint() is
            // 根据 macOS 样式渲染复选框。
    
    // 客户端代码仅通过抽象类型(GUIFactory、Button 和 Checkbox)使用工厂
    // 和产品。这让你无需修改任何工厂或产品子类就能将其传递给客户端代码。
    class Application is
        private field factory: GUIFactory
        private field button: Button
        constructor Application(factory: GUIFactory) is
            this.factory = factory
        method createUI() is
            this.button = factory.createButton()
        method paint() is
            button.paint()
    
    
    // 程序会根据当前配置或环境设定选择工厂类型,并在运行时创建工厂(通常在初
    // 始化阶段)。
    class ApplicationConfigurator is
        method main() is
            config = readApplicationConfigFile()
    
            if (config.OS == "Windows") then
                factory = new WinFactory()
            else if (config.OS == "Mac") then
                factory = new MacFactory()
            else
                throw new Exception("错误!未知的操作系统。")
    
            Application app = new Application(factory)
    

     抽象工厂模式适合应用场景

     如果代码需要与多个不同系列的相关产品交互, 但是由于无法提前获取相关信息, 或者出于对未来扩展性的考虑, 你不希望代码基于产品的具体类进行构建, 在这种情况下, 你可以使用抽象工厂。

     抽象工厂为你提供了一个接口, 可用于创建每个系列产品的对象。 只要代码通过该接口创建对象, 那么你就不会生成与应用程序已生成的产品类型不一致的产品。

    • 如果你有一个基于一组抽象方法的类, 且其主要功能因此变得不明确, 那么在这种情况下可以考虑使用抽象工厂模式。

    • 在设计良好的程序中, 每个类仅负责一件事。 如果一个类与多种类型产品交互, 就可以考虑将工厂方法抽取到独立的工厂类或具备完整功能的抽象工厂类中。

     实现方式

    1. 以不同的产品类型与产品变体为维度绘制矩阵。

    2. 为所有产品声明抽象产品接口。 然后让所有具体产品类实现这些接口。

    3. 声明抽象工厂接口, 并且在接口中为所有抽象产品提供一组构建方法。

    4. 为每种产品变体实现一个具体工厂类。

    5. 在应用程序中开发初始化代码。 该代码根据应用程序配置或当前环境, 对特定具体工厂类进行初始化。 然后将该工厂对象传递给所有需要创建产品的类。

    6. 找出代码中所有对产品构造函数的直接调用, 将其替换为对工厂对象中相应构建方法的调用。

     抽象工厂模式优缺点

    •  你可以确保同一工厂生成的产品相互匹配。
    •  你可以避免客户端和具体产品代码的耦合。
    •  单一职责原则。 你可以将产品生成代码抽取到同一位置, 使得代码易于维护。
    •  开闭原则。 向应用程序中引入新产品变体时, 你无需修改客户端代码。
    •  由于采用该模式需要向应用中引入众多接口和类, 代码可能会比之前更加复杂。

     与其他模式的关系

    • 在许多设计工作的初期都会使用工厂方法模式 (较为简单, 而且可以更方便地通过子类进行定制), 随后演化为使用抽象工厂模式、 原型模式或生成器模式 (更灵活但更加复杂)。

    • 生成器重点关注如何分步生成复杂对象。 抽象工厂专门用于生产一系列相关对象。 抽象工厂会马上返回产品, 生成器则允许你在获取产品前执行一些额外构造步骤。

    • 抽象工厂模式通常基于一组工厂方法, 但你也可以使用原型模式来生成这些类的方法。

    • 当只需对客户端代码隐藏子系统创建对象的方式时, 你可以使用抽象工厂来代替外观模式。

    • 你可以将抽象工厂和桥接模式搭配使用。 如果由桥接定义的抽象只能与特定实现合作, 这一模式搭配就非常有用。 在这种情况下, 抽象工厂可以对这些关系进行封装, 并且对客户端代码隐藏其复杂性。

    • 抽象工厂、 生成器和原型都可以用单例模式来实现。

    展开全文
  • 在本人所编写的关于23种设计模式的文章中,前言基本上都是一样的,读者可以从章节2开始阅读,本篇是关于创建型模式中抽象工厂模式(Abstract Factory Pattern)的详解。 文章目录1.前言 1.前言 根据Design Patterns ...
  • 文章目录前言一、抽象工厂模式二、实现1.步骤一2.读入数据总结 前言 本人对于设计模式的学习,仅供参考! 一、抽象工厂模式 抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。该超级工厂又...
  • 简单工厂模式、工厂方法模式、抽象工厂模式比较相像,很多同学傻傻分不清楚,本文进行详细对比说明,建议对三个模式有一定基础再进行阅读,如不了解可查看往期文章。 一、简单工厂模式 1.描述 简单工厂模式是属于...
  • 抽象工厂模式是一种创建型设计模式, 它能创建一系列相关的对象, 而无需指定其具体类。
  • 抽象工厂模式

    2021-05-28 14:12:53
    一、前言 代码一把梭,兄弟来背锅。 大部分做开发的小伙伴初心都希望把代码写好,除了把编程当作工作以外他们还是具备工匠精神的从业者。但很多时候又很难让你把初心坚持下去,就像;接了个烂手的项目、产品功能要...
  • C++实现抽象工厂模式

    2021-04-02 17:08:26
    抽象工厂模式3.1 模式介绍3.2 模式图解3.3 代码分析3.4 抽象工厂模式总结 1. 设计模式介绍    设计模式其实是一套提高代码复用性,健壮性,可维护性等一系列优化编程的结局方案,是代码美观,安.
  • 一、试画出抽象工厂模式的模式结构图,并对模式进行分析 1.1 抽象工厂模式结构图: 1.2 抽象工厂模式的实现(Java) 1.3 抽象工厂模式的优缺点 1.4 抽象工厂模式的实现(Python) 二、试画出建造者模式的模式...
  • 1、抽象工厂模式的定义   抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。在...
  • 抽象工厂模式实验报告书 1 实验四:抽象工厂模式 2 一、实验目的 2 二、实验内容 2 三、实验步骤 2 3.1抽象工厂模式:电器工厂 2 3.2 car 6 3.3 电脑 12 四、实验结果分析 17 抽象工厂的意图 17 抽象工厂...
  • 文章目录工厂模式介绍例子优缺点抽象工厂模式介绍例子优缺点 工厂模式 介绍 工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 在...
  • 抽象工厂模式就针对这种情况,对工厂类再进行了另一层封装,使得即使有多种不同类的产品,暴露给应用程序的接口仍然只有一个。 2. 抽象工厂模式说明 什么是抽象工厂模式 抽象工厂模式同工厂模式一样也属于创建型...
  • why 抽象工厂模式意图:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。主要使用场景为: 生活中的服装管理。工作中为了参加一些聚会,肯定有多套衣服,比如说有商务装(成套,一系列...
  • 抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 在抽象工厂模式中,接口是负责...
  • 抽象工厂模式简介 抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。抽象工厂模式...
  • 抽象工厂模式实现对产品家族的创建,一个产品家族是这样的一系列产品:具有不同分类维度的产品组合,采用抽象工厂模式则是不需要关系构件过程,只关心什么产品由什么工厂生产即可。而建造者模式则是要求按照指定的...
  • 抽象工厂(Abstract Factory)模式意图:为创建一组相关或相互依赖对象提供了一个接口,而且无需指定它们的具体类。 抽象工厂可以向客户提供一个接口,是客户可以在不必指定产品具体类型的情况下,创建多个产品家族...
  • 抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 在抽象工厂模式中,接口是负责...
  • 常用设计模式 ------抽象工厂模式

    多人点赞 热门讨论 2021-11-29 10:45:26
    文章目录前言简单的介绍抽象工厂模式的定义与特点抽象工厂模式的结构与实现模式的结构 前言   前面介绍的工厂方法模式中考虑的是一类产品的生产,如畜牧场只养动物、电视机厂只生产电视机、计算机软件学院只培养...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 14,769
精华内容 5,907
关键字:

抽象工厂模式的意图是