精华内容
下载资源
问答
  • 工厂方法
    千次阅读
    2022-07-10 14:49:10

    【设计模式】抽象工厂方法模式(C#)

    1、概述

    是一种为访问类提供一个创建一组相关或相互依赖对象的接口,且访问类无须指定所要产品的具体类就能得到同族的不同等级的产品的模式结构。(同族的不同等级的产品可以理解为Apple公司的iPhone、iPad、Mac,这里建议大家搜索产品等级和产品族。)

    抽象工厂模式是工厂方法模式的升级版本,工厂方法模式只生产一个等级的产品,而抽象工厂模式可生产多个等级的产品。

    2、抽象工厂方法模式实现思路

    现披萨店业务发生改变,不仅要生产披萨还要生产牛排,如希腊牛排、奶酪牛排(费城)等,要是按照工厂方法模式,需要定义牛排类、希腊牛排类、奶酪牛排类、希腊牛排工厂、奶酪牛排工厂、牛排工厂类,很容易发生类爆炸情况。其中希腊披萨、奶酪披萨是一个产品等级,都是披萨;希腊牛排、奶酪牛排也是一个产品等级;希腊披萨和希腊牛排是同一产品族,奶酪披萨和奶酪牛排是同一产品族。所以这个案例可以使用抽象工厂模式实现。

    首先,我们先创建一个简单的类。

    //抽象产品类
    public abstract class Pizza
        {
            //名字
            public string Name;
    
            //准备原材料
            public abstract void Prepare();
    
            public void Bake()
            {
                Console.WriteLine($"{this.Name} bake");
            }
    
            public void Cut()
            {
                Console.WriteLine($"{this.Name} cut");
            }
    
            public void Box()
            {
                Console.WriteLine($"{this.Name} box");
            }
    
        }
    
    //具体产品类
    public class GreekPizza : Pizza
        {
            public override void Prepare()
            {
                Console.WriteLine("GreekPizza 准备原材料");
            }
        }
    
    //具体产品类
    public class CheessPizza : Pizza
        {
            public override void Prepare()
            {
                Console.WriteLine("CheessPizza 准备原材料");
            }
        }
    
    //抽象产品类
    public abstract class Steak
        {
            //名字
            public string Name;
    
            //准备原材料
            public abstract void Prepare();
    
            public void Bake()
            {
                Console.WriteLine($"{this.Name} bake");
            }
    
            public void Cut()
            {
                Console.WriteLine($"{this.Name} cut");
            }
    
            public void Box()
            {
                Console.WriteLine($"{this.Name} box");
            }
        }
    
    //具体产品类
    public class CheessSteak : Steak
        {
            public override void Prepare()
            {
                Console.WriteLine("CheessSteak 准备原材料");
            }
        }
    
    //具体产品类
     public class GreekSteak : Steak
        {
            public override void Prepare()
            {
                Console.WriteLine("GreekSteak 准备原材料");
            }
        }
    
    //抽象工厂类
    public abstract class PizzaFactory
        {
           public abstract Pizza CreatePizza();
        }
    
    //具体工厂类
    public abstract class WesternStyleFoodFactory
        {
            public abstract Pizza CreatePizza();
    
            public abstract Steak CreateSteak();
        }
    
    //具体工厂类
    public class GreekFactory:WesternStyleFoodFactory
        {
            public override Pizza CreatePizza()
            {
                GreekPizza greekPizza = new GreekPizza();
                greekPizza.Name = "希腊披萨";
                greekPizza.Prepare();
                greekPizza.Bake();
                greekPizza.Cut();
                greekPizza.Box();
                return greekPizza;
            }
    
            public override Steak CreateSteak()
            {
                GreekSteak greekSteak = new GreekSteak();
                greekSteak.Name = "希腊牛排";
                greekSteak.Prepare();
                greekSteak.Bake();
                greekSteak.Cut();
                greekSteak.Box();
                return greekSteak;
            }
        }
    
    //具体工厂类
    public class CheessFactory : WesternStyleFoodFactory
        {
            public override Pizza CreatePizza()
            {
                CheessPizza cheessPizza = new CheessPizza();
                cheessPizza.Name = "奶酪披萨";
                cheessPizza.Prepare();
                cheessPizza.Bake();
                cheessPizza.Cut();
                cheessPizza.Box();
                return cheessPizza;
            }
    
            public override Steak CreateSteak()
            {
                CheessSteak cheessSteak = new CheessSteak();
                cheessSteak.Name = "奶酪牛排";
                cheessSteak.Prepare();
                cheessSteak.Bake();
                cheessSteak.Cut();
                cheessSteak.Box();
                return cheessSteak;
            }
        }
    
    //订购披萨
       public class PizzaStore
        {
            WesternStyleFoodFactory _factory;
            public void setFactory(WesternStyleFoodFactory factory)
            {
                this._factory = factory;
            }
            public Pizza OrderPizza()
            {
                Pizza pizza = _factory.CreatePizza();
                return pizza;
            }
    
            public Steak OrderSteak()
            {
                Steak steak = _factory.CreateSteak();
                return steak;
            }
        }
    
    //使用工厂方法模式
    class Program
        {
            static void Main(string[] args)
            {
                PizzaStore pizzaStore = new PizzaStore();
                WesternStyleFoodFactory greekPizzaFactory = new GreekFactory();
                pizzaStore.setFactory(greekPizzaFactory);
                pizzaStore.OrderPizza();
                pizzaStore.OrderSteak();
    
                WesternStyleFoodFactory cheessPizzaFactory = new CheessFactory();
                pizzaStore.setFactory(cheessPizzaFactory);
                pizzaStore.OrderPizza();
                pizzaStore.OrderSteak();
            }
        }
    
    ******************【运行结果】******************
    GreekPizza 准备原材料
    希腊披萨 bake
    希腊披萨 cut
    希腊披萨 box
    GreekSteak 准备原材料
    希腊牛排 bake
    希腊牛排 cut
    希腊牛排 box
    CheessPizza 准备原材料
    奶酪披萨 bake
    奶酪披萨 cut
    奶酪披萨 box
    CheessSteak 准备原材料
    奶酪牛排 bake
    奶酪牛排 cut
    奶酪牛排 box
    

    如果要加同一个产品族的话,只需要再加一个对应的工厂类即可,不需要修改其他的类。

    3、 优缺点

    优点:

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

    缺点:

    • 当产品族中需要增加一个新的产品时,所有的工厂类都需要进行修改。

    4、 使用场景

    • 当需要创建的对象是一系列相互关联或相互依赖的产品族时,如电器工厂中的电视机、洗衣机、空调等。

    • 系统中有多个产品族,但每次只使用其中的某一族产品。如有人只喜欢穿某一个品牌的衣服和鞋。

    • 系统中提供了产品的类库,且所有产品的接口相同,客户端不依赖产品实例的创建细节和内部结构。

    如:输入法换皮肤,一整套一起换。生成不同操作系统的程序。

    更多相关内容
  • 工厂方法 工厂方法的主要是通过继承一个AnimalFactory来实现具体的工厂,比如CatFatory主要负责生产Cat,而TigerFacotory主要负责生产Tiger,其类图如下: 代码如下: class AnimalFactory { public: virtual ...

    在面向对象的编程中,一般通过继承和虚函数来提供抽象能力,多态让程序在执行期,调用者只需要看到父类类型,而不需要关心继承的子类类型。举个例子: 比如有个游戏,里面的游戏的活动对象为动物,比如有老虎和猫,会对主人公进行攻击。那么可能会实现为如下:
    在这里插入图片描述
    代码如下:

    class Animal
    {
    public:
    	virtual void Attack() = 0;
    };
    
    class Tiger : public Animal
    {
    public:
    	virtual void Attack() { std::cout << "Tiger Attack!" << std::endl; };
    };
    
    class Cat : public Animal
    {
    public:
    	virtual void Attack() { std::cout << "Cat Attack!" << std::endl; };
    };
    

    那如果在外面有个方法,并不需要关心具体的对象类型,只需要使用基类Animal的指针去操作对象, 利用多态机制变可以实现对具体对象类型的方法调用:

    void Attack(Animal* pAnimal)
    {
    	pAnimal->Attack();
    }
    

    比如这个时候采用如下方法进行调用(忽略里面内存释放的问题):

    	Animal* pAnimal = new Tiger;
    	Attack(pAnimal);
    	pAnimal = new Cat;
    	Attack(pAnimal);
    

    输出结果为:

    Tiger Attack!
    Cat Attack!
    

    上面多态例子说明了在程序实现的时候只需要操控Animal,知道其方法即可操作继承自Animal的对象。那么也就是说:

    1. 继承自AnimalCatTiger的不需要暴露给使用者
    2. 可以屏蔽CatTiger的创建过程,不需要被调用者所关心

    那么这个时候模块化和工厂设计模式可以对其进行实现:

    1. 比如将Animal, Cat, Tiger的实现都放进一个动态链接库的模块中,并且只暴露Animal的头文件给调用者
    2. 工厂方法设计模式,可以使用一个工厂方法创建具体的对象,返回的时候只返回基类Animal的指针。

    本文将先从简单工厂说起,然后再谈一谈工厂方法以及抽象工厂

    简单工厂

    我相信这个是大家最常见的一种实现方法,如下:
    在这里插入图片描述

    class AnimalFactory
    {
    public:
    	enum class AnimalType
    	{
    		TIGER,
    		CAT
    	};
    
    	static Animal* CreateAnimal(const AnimalType type)
    	{
    		if (AnimalType::TIGER == type)
    		{
    			return new Tiger;
    		}
    		else if (AnimalType::CAT == type)
    		{
    			return new Cat;
    		}
    		return nullptr;
    	}
    };
    

    调用方法如下:

    Animal* pAnimal = AnimalFactory::CreateAnimal(AnimalFactory::AnimalType::TIGER);
    Attack(pAnimal);
    pAnimal = AnimalFactory::CreateAnimal(AnimalFactory::AnimalType::CAT);
    Attack(pAnimal);
    

    但是这种方式违背了软件开发原则的开闭原则(Open-Closed Principle, OCP),如果你需要新增一个叫做Dog的对象,则需要在CreateAnimal方法中修改分支判断逻辑。简单来说这种扩展方式,破坏了原有的逻辑,扩展中可能对软件的原有的稳定性产生影响。

    可能有些人是不能够容忍代码,但也有人认为这种书写方式比较简单。从我个人在工程实践经验,认为软件开发设计原则是有非常好的指导性意义,但是也并不是所有的代码一定要符合软件开发的设计原则。个人的理解大致如下:

    1. 工程实践中有时候为了代码完全遵循软件开发设计原则,反而是有负担的,比如过度设计问题,一来有些代码模块可能甚至几年都不会对其进行修改扩展了,二来当逻辑实现比较简单的时候,过度设计也会让代码维护的人阅读代码实际是更加费劲的。毕竟大多数人都只是普通的程序员。
    2. 往往可扩展的代码编写时间是更长的,但是压在程序员头上的还有软件开发时间,对于一般的程序员来说,在规定时间内,有质量的完成需求是第一位的,而这个时候很可能就不会完全照顾软件开发设计原则了。

    如果要符合开闭原则,那么我们可以实现工厂方法模式,让我们一起来看看吧。

    工厂方法

    工厂方法的主要是通过继承一个AnimalFactory来实现具体的工厂,比如CatFatory主要负责生产Cat,而TigerFacotory主要负责生产Tiger,其类图如下:
    在这里插入图片描述
    代码如下:

    class AnimalFactory
    {
    public:
    	virtual Animal* CreateAnimal() = 0;
    };
    
    class CatFactory : public AnimalFactory
    {
    public:
    	virtual Animal* CreateAnimal()
    	{
    		return new Cat;
    	}
    };
    
    class TigerFactory : public AnimalFactory
    {
    public:
    	virtual Animal* CreateAnimal()
    	{
    		return new Tiger;
    	}
    };
    

    调用方式如下代码:

    AnimalFactory* pFactory = new TigerFactory;
    Animal* pAnimal = pFactory->CreateAnimal();
    Attack(pAnimal);
    
    pFactory = new CatFactory;
    pAnimal = pFactory->CreateAnimal();
    Attack(pAnimal);
    

    可以发现工厂方法模式如果需要扩展一个新的动物类型,也可以对应扩展一个新的工厂,比如增加一个新的DogFactory继承AnimalFactory去生产Dog,从而符合开闭原则,更加安全的进行扩展。但是这种方式也可以看出来,每增加一个新的动物类型就得新增一个Fatory。个人对这种模式理解如下:

    1. 当这种动物类型创建并不是很繁琐的时候,采用这种方式相比较简单工程而言会繁琐一些;但是当初始化过程比较多的时候,用工厂方法模式方式扩展会显得更加清晰;
    2. 这种设计模式的本身实现是取消了条件判断的逻辑,但是其实是把这个条件判断任务交给了使用者去判断选择哪个工厂了。

    抽象工厂

    对于新手来说可能不太好理解抽象工厂模式,容易和工厂方法模式混淆起来。工厂方法模式中的每一个工厂是生产一个动物角色,而在抽象工厂中是生产一类动物角色的抽象。
    一个动物角色比较好理解,就是我们上面的CatFactory生产Cat角色, 而TigerFactory生产Tiger角色。
    一类动物角色,我们可以理解在这个游戏中,这些动物角色的攻击性也分普通模式和困难模式。

    那么我们首先要将Tiger分成SimpleModeTigerHardModeTiger; Cat分为SimpleModeCatHardModeCat。然后抽象工厂提供CreateAnimal的接口,继承的SimpleModeFactory可以生产简单模式的Cat角色和Tiger角色,继承的HardModeFactory可以生产困难模式的Cat角色和Tiger角色。
    在这里插入图片描述
    实现的代码如下所示:

    #include <iostream>
    
    class Animal
    {
    public:
    	virtual void Attack() = 0;
    };
    
    class AbstructTiger : public Animal
    {
    public:
    	virtual void Attack() = 0;
    };
    
    class SimpleModeTiger : public AbstructTiger
    {
    public:
    	virtual void Attack()  { std::cout << "Tiger Simple Attack!" << std::endl; }
    };
    
    class HardModeTiger : public AbstructTiger
    {
    public:
    	virtual void Attack()  { std::cout << "Tiger Hard Attack!" << std::endl; }
    };
    
    class AbstructCat : public Animal
    {
    public:
    	virtual void Attack() = 0;
    };
    
    class SimpleModeCat : public AbstructCat
    {
    public:
    	virtual void Attack()  { std::cout << "Cat Simple Attack!" << std::endl; }
    };
    
    class HardModeCat : public AbstructCat
    {
    public:
    	virtual void Attack()  { std::cout << "Cat Hard Attack!" << std::endl; }
    };
    
    enum class AnimalType
    {
    	TIGER,
    	CAT
    };
    
    class AbscractAnimalFactory
    {
    public:
    	virtual Animal* CreateAnimal(const AnimalType type) = 0;
    };
    
    class SimpleModeAnimalFactory : public AbscractAnimalFactory
    {
    public:
    	virtual Animal* CreateAnimal(const AnimalType type)
    	{
    		if (AnimalType::TIGER == type)
    		{
    			return new SimpleModeTiger;
    		}
    		else if (AnimalType::CAT == type)
    		{
    			return new SimpleModeCat;
    		}
    		return nullptr;
    	}
    };
    
    class HardModeAnimalFactory : public AbscractAnimalFactory
    {
    public:
    	virtual Animal* CreateAnimal(const AnimalType type)
    	{
    		if (AnimalType::TIGER == type)
    		{
    			return new HardModeTiger;
    		}
    		else if (AnimalType::CAT == type)
    		{
    			return new HardModeCat;
    		}
    		return nullptr;
    	}
    };
    
    void Attack(Animal* pAnimal)
    {
    	pAnimal->Attack();
    }
    
    int main()
    {
    	//简单模式
    	AbscractAnimalFactory* pFactory = new SimpleModeAnimalFactory;
    	Animal* pAnimal = pFactory->CreateAnimal(AnimalType::TIGER);
    	Attack(pAnimal);
    
    	pAnimal = pFactory->CreateAnimal(AnimalType::CAT);
    	Attack(pAnimal);
    
    	//困难模式
    	pFactory = new HardModeAnimalFactory;
    	pAnimal = pFactory->CreateAnimal(AnimalType::TIGER);
    	Attack(pAnimal);
    
    	pAnimal = pFactory->CreateAnimal(AnimalType::CAT);
    	Attack(pAnimal);
    }
    

    为了让结构简单便于读者理解抽象工厂模式,以及和工厂方法模式的区别,上面的SimpleModeFactoryHardModeFactory用的是简单工厂的形式实现的,如果需要符合开闭原则,可以再对SimpleModeFactoryHardModeFactory进行工厂方法的实现。可以想象如果抽象工厂再加上工厂方法这个类的结构是有多么的庞大,而且这还仅仅只是两个游戏角色的描述。所以笔者认为在做工程实践的时候,尽量不要做过度设计,有时候反而不利于代码阅读,修改也未必简单。自己要权衡好工程和理论的平衡点。

    参考

    1. <<C++设计新思维>>中的两个章节对象工厂抽象工厂
    2. 秦小波<<设计模式之禅>>
    3. Does the Factory Pattern violate the Open/Closed Principle?
    展开全文
  • 工厂模式将目的将创建对象的具体过程屏蔽隔离起来,从而达到更高的灵活性,工厂模式可以分为三类:简单工厂模式、工厂方法模式、抽象工厂模式;简单工厂模式的核心是定义一个创建对象的接口,将对象的创建和本身的...

            在面向对象编程中,创建对象实例最常用的方式就是通过 new 操作符构造一个对象实例,但在某些情况下,new 操作符直接生成对象会存在一些问题。举例来说,对象的创建需要一系列的步骤:可能需要计算或取得对象的初始位置、选择生成哪个子对象实例、或在生成之前必须先生成一些辅助对象。 在这些情况,新对象的建立就是一个 “过程”,而不仅仅是一个操作,就像一部大机器中的一个齿轮传动。

            针对上面这种情况,我们如何轻松方便地构造对象实例,而不必关心构造对象示例的细节和复杂过程?解决方案就是使用一个工厂类来创建对象。

    一、什么是工厂模式:

            工厂模式将目的将创建对象的具体过程屏蔽隔离起来,从而达到更高的灵活性,工厂模式可以分为三类:

    • 简单工厂模式(Simple Factory)
    • 工厂方法模式(Factory Method)
    • 抽象工厂模式(Abstract Factory)

    这三种模式从上到下逐步抽象,并且更具一般性。《设计模式》一书中将工厂模式分为两类:工厂方法模式与抽象工厂模式。将简单工厂模式看为工厂方法模式的一种特例,两者归为一类。 我们先从以下案例对工厂模式做个初步的了解:

    (1)在没有工厂的时代,如果客户需要一款宝马车,那么就需要客户去创建一款宝马车,然后拿来用。

    (2)简单工厂模式:后来出现了工厂,用户不再需要去创建宝马车,由工厂进行创建,想要什么车,直接通过工厂创建就可以了。比如想要320i系列车,工厂就创建这个系列的车。

    (3)工厂方法模式:为了满足客户,宝马车系列越来越多,如320i、523i等等系列,一个工厂无法创建所有的宝马系列,于是又单独分出来多个具体的工厂,每个具体工厂创建一种系列,即具体工厂类只能创建一个具体产品。但是宝马工厂还是个抽象,你需要指定某个具体的工厂才能生产车出来。

    (4)抽象工厂模式:随着客户要求越来越高,宝马车必须配置空调,于是这个工厂开始生产宝马车和需要的空调。最终是客户只要对宝马的销售员说:我要523i空调车,销售员就直接给他523i空调车了。而不用自己去创建523i空调车宝马车。

    下面我们就针对几种不同的工厂模式进行详细的说明:

    二、简单工厂模式:

            简单工厂模式的核心是定义一个创建对象的接口,将对象的创建和本身的业务逻辑分离,降低系统的耦合度,使得两个修改起来相对容易些,当以后实现改变时,只需要修改工厂类即可。

    如果不使用工厂,用户将自己创建宝马车,具体UML图和代码如下:

    public class BMW320 {
    	public BMW320(){
    		System.out.println("制造-->BMW320");
    	}
    }
     
    public class BMW523 {
    	public BMW523(){
    		System.out.println("制造-->BMW523");
    	}
    }
     
    public class Customer {
    	public static void main(String[] args) {
    		BMW320 bmw320 = new BMW320();
    		BMW523 bmw523 = new BMW523();
    	}
    }

            用户需要知道怎么创建一款车,这样子客户和车就紧密耦合在一起了,为了降低耦合,就出现了简单工厂模式,把创建宝马的操作细节都放到了工厂里,而客户直接使用工厂的创建方法,传入想要的宝马车型号就行了,而不必去知道创建的细节。

    1、简单工厂模式的UML图:

    • 工厂类角色: 该模式的核心,用来创建产品,含有一定的商业逻辑和判断逻辑
    • 抽象产品角色:它一般是具体产品继承的父类或者实现的接口。   
    • 具体产品角色:工厂类所创建的对象就是此角色的实例。在java中由一个具体类实现。

    2、代码实现:

    产品类:

    abstract class BMW {
    	public BMW(){}
    }
     
    public class BMW320 extends BMW {
    	public BMW320() {
    		System.out.println("制造-->BMW320");
    	}
    }
    public class BMW523 extends BMW{
    	public BMW523(){
    		System.out.println("制造-->BMW523");
    	}
    }
    

    工厂类:

    public class Factory {
    	public BMW createBMW(int type) {
    		switch (type) {
    		
    		case 320:
    			return new BMW320();
     
    		case 523:
    			return new BMW523();
     
    		default:
    			break;
    		}
    		return null;
    	}
    }

    用户类:

    public class Customer {
    	public static void main(String[] args) {
    		Factory factory = new Factory();
    		BMW bmw320 = factory.createBMW(320);
    		BMW bmw523 = factory.createBMW(523);
    	}
    }

    3、简单工厂模式的优缺点:

            简单工厂模式提供专门的工厂类用于创建对象,实现了对象创建和使用的职责分离,客户端不需知道所创建的具体产品类的类名以及创建过程,只需知道具体产品类所对应的参数即可,通过引入配置文件,可以在不修改任何客户端代码的情况下更换和增加新的具体产品类,在一定程度上提高了系统的灵活性。

            但缺点在于不符合“开闭原则”,每次添加新产品就需要修改工厂类。在产品类型较多时,有可能造成工厂逻辑过于复杂,不利于系统的扩展维护,并且工厂类集中了所有产品创建逻辑,一旦不能正常工作,整个系统都要受到影响。

            为了解决简单工厂模式的问题,出现了工厂方法模式。

    三、工厂方法模式:

            工厂方法模式将工厂抽象化,并定义一个创建对象的接口。每增加新产品,只需增加该产品以及对应的具体实现工厂类,由具体工厂类决定要实例化的产品是哪个,将对象的创建与实例化延迟到子类,这样工厂的设计就符合“开闭原则”了,扩展时不必去修改原来的代码。在使用时,用于只需知道产品对应的具体工厂,关注具体的创建过程,甚至不需要知道具体产品类的类名,当我们选择哪个具体工厂时,就已经决定了实际创建的产品是哪个了。

            但缺点在于,每增加一个产品都需要增加一个具体产品类和实现工厂类,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。

    1、工厂方法的 UML 结构图如下:

    • 抽象工厂 AbstractFactory: 工厂方法模式的核心,是具体工厂角色必须实现的接口或者必须继承的父类,在 Java 中它由抽象类或者接口来实现。 
    • 具体工厂 Factory:被应用程序调用以创建具体产品的对象,含有和具体业务逻辑有关的代码
    • 抽象产品 AbstractProduct:是具体产品继承的父类或实现的接口,在 Java 中一般有抽象类或者接口来实现。 
    • 具体产品 Product:具体工厂角色所创建的对象就是此角色的实例。

    2、代码实现:

    产品类:

    abstract class BMW {
    	public BMW(){}
    }
    public class BMW320 extends BMW {
    	public BMW320() {
    		System.out.println("制造-->BMW320");
    	}
    }
    public class BMW523 extends BMW{
    	public BMW523(){
    		System.out.println("制造-->BMW523");
    	}
    }
    

    工厂类:

    interface FactoryBMW {
    	BMW createBMW();
    }
     
    public class FactoryBMW320 implements FactoryBMW{
     
    	@Override
    	public BMW320 createBMW() {
    		return new BMW320();
    	}
     
    }
    public class FactoryBMW523 implements FactoryBMW {
    	@Override
    	public BMW523 createBMW() {
    		return new BMW523();
    	}
    }
    

    客户类:

    public class Customer {
    	public static void main(String[] args) {
    		FactoryBMW320 factoryBMW320 = new FactoryBMW320();
    		BMW320 bmw320 = factoryBMW320.createBMW();
     
    		FactoryBMW523 factoryBMW523 = new FactoryBMW523();
    		BMW523 bmw523 = factoryBMW523.createBMW();
    	}
    }
    

    四、抽象工厂模式:

            在工厂方法模式中,我们使用一个工厂创建一个产品,一个具体工厂对应一个具体产品,但有时候我们需要一个工厂能够提供多个产品对象,而不是单一的对象,这个时候我们就需要使用抽象工厂模式。

            在介绍抽象工厂模式前,我们先厘清两个概念:

    • 产品等级结构:产品等级结构指的是产品的继承结构,例如一个空调抽象类,它有海尔空调、格力空调、美的空调等一系列的子类,那么这个空调抽象类和他的子类就构成了一个产品等级结构。
    • 产品族:产品族是指由同一个工厂生产的,位于不同产品等级结构中的一组产品。比如,海尔工厂生产海尔空调、海尔冰箱,那么海尔空调则位于空调产品族中。

    产品等级结构和产品族结构示意图如下:

    1、什么是抽象工厂模式:

            抽象工厂模式主要用于创建相关对象的家族。当一个产品族中需要被设计在一起工作时,通过抽象工厂模式,能够保证客户端始终只使用同一个产品族中的对象;并且通过隔离具体类的生成,使得客户端不需要明确指定具体生成类;所有的具体工厂都实现了抽象工厂中定义的公共接口,因此只需要改变具体工厂的实例,就可以在某种程度上改变整个软件系统的行为。

            但该模式的缺点在于添加新的行为时比较麻烦,如果需要添加一个新产品族对象时,需要更改接口及其下所有子类,这必然会带来很大的麻烦。

    2、UML结构图:

    • 抽象工厂 AbstractFactory:定义了一个接口,这个接口包含了一组方法用来生产产品,所有的具体工厂都必须实现此接口。
    • 具体工厂 ConcreteFactory:用于生产不同产品族,要创建一个产品,用户只需使用其中一个工厂进行获取,完全不需要实例化任何产品对象。
    • 抽象产品 AbstractProduct:这是一个产品家族,每一个具体工厂都能够生产一整组产品。
    • 具体产品 Product

    3、代码实现:

            通过抽象工厂模式,我们可以实现以下的效果:比如宝马320系列使用空调型号A和发动机型号A,而宝马230系列使用空调型号B和发动机型号B,在为320系列生产相关配件时,就无需制定配件的型号,它会自动根据车型生产对应的配件型号A。

            也就是说,当每个抽象产品都有多于一个的具体子类的时候(空调有型号A和B两种,发动机也有型号A和B两种),工厂角色怎么知道实例化哪一个子类呢?抽象工厂模式提供两个具体工厂角色(宝马320系列工厂和宝马230系列工厂),分别对应于这两个具体产品角色,每一个具体工厂角色只负责某一个产品角色的实例化,每一个具体工厂类只负责创建抽象产品的某一个具体子类的实例。

    产品类:

    //发动机以及型号  
    public interface Engine {}  
    
    public class EngineA implements Engine{  
        public EngineA(){  
            System.out.println("制造-->EngineA");  
        }  
    }  
    public class EngineB implements Engine{  
        public EngineB(){  
            System.out.println("制造-->EngineB");  
        }  
    }  
     
    
    //空调以及型号  
    public interface Aircondition {} 
     
    public class AirconditionA implements Aircondition{  
        public AirconditionA(){  
            System.out.println("制造-->AirconditionA");  
        }  
    }  
    public class AirconditionB implements Aircondition{  
        public AirconditionB(){  
            System.out.println("制造-->AirconditionB");  
        }  
    } 
    

    创建工厂类:

    //创建工厂的接口  
    public interface AbstractFactory {  
        //制造发动机
        public Engine createEngine();
        //制造空调 
        public Aircondition createAircondition(); 
    }  
     
    //为宝马320系列生产配件  
    public class FactoryBMW320 implements AbstractFactory{     
        @Override  
        public Engine createEngine() {    
            return new EngineA();  
        }  
        @Override  
        public Aircondition createAircondition() {  
            return new AirconditionA();  
        }  
    }  
    //宝马523系列
    public class FactoryBMW523 implements AbstractFactory {  
         @Override  
        public Engine createEngine() {    
            return new EngineB();  
        }  
        @Override  
        public Aircondition createAircondition() {  
            return new AirconditionB();  
        }  
    } 
    

    客户:

    public class Customer {  
        public static void main(String[] args){  
            //生产宝马320系列配件
            FactoryBMW320 factoryBMW320 = new FactoryBMW320();  
            factoryBMW320.createEngine();
            factoryBMW320.createAircondition();
              
            //生产宝马523系列配件  
            FactoryBMW523 factoryBMW523 = new FactoryBMW523();  
            factoryBMW523.createEngine();
            factoryBMW523.createAircondition();
        }  
    }
    

    工厂模式小结:

    1、工厂方法模式与抽象工厂模式的区别在于:

    (1)工厂方法只有一个抽象产品类和一个抽象工厂类,但可以派生出多个具体产品类和具体工厂类,每个具体工厂类只能创建一个具体产品类的实例。

    (2)抽象工厂模式拥有多个抽象产品类(产品族)和一个抽象工厂类,每个抽象产品类可以派生出多个具体产品类;抽象工厂类也可以派生出多个具体工厂类,同时每个具体工厂类可以创建多个具体产品类的实例


    设计模式系列文章:

    Java设计模式之创建型:工厂模式详解(简单工厂+工厂方法+抽象工厂)

    Java设计模式之创建型:建造者模式

    Java设计模式之创建型:单例模式

    Java设计模式之创建型:原型模式

    Java设计模式之结构型:适配器模式

    Java设计模式之结构型:装饰器模式

    Java设计模式之结构型:代理模式

    Java设计模式之结构型:桥接模式

    Java设计模式之结构型:外观模式

    Java设计模式之结构型:组合模式

    Java设计模式之结构型:享元模式

    Java设计模式之行为型:策略模式

    Java设计模式之行为型:模板方法模式

    Java设计模式之行为型:责任链模式

    Java设计模式之行为型:观察者模式

    Java设计模式之行为型:访问者模式

    Java设计模式之行为型:中介者模式

    Java设计模式之行为型:命令模式

    Java设计模式之行为型:状态模式

    Java设计模式之行为型:备忘录模式

    Java设计模式之行为型:迭代器模式

    Java设计模式之行为型:解释器模式


    参考文章:

    设计模式读书笔记----简单工厂模式_chenssy 的技术博客-CSDN博客

    设计模式读书笔记----工厂方法模式_chenssy 的技术博客-CSDN博客

    设计模式读书笔记----抽象工厂模式_chenssy 的技术博客-CSDN博客

    JAVA设计模式之抽象工厂模式_一个本科小生的奋斗史-CSDN博客_java抽象工厂模式

    展开全文
  • 1 简单工厂(Simple Factory) 1.1 问题引出 假如有一个披萨店,Pizza的种类有很多,如CheesePizza、VeggiePizza、PepperPizza等。披萨店根据收到的订单制作Pizza,披萨的制作流程有材料的准备材料、烤、切、包装几步...

    1 简单工厂(Simple Factory)

    1.1 问题引出

    假如有一个披萨店,Pizza的种类有很多,如CheesePizza、VeggiePizza、PepperPizza等。披萨店根据收到的订单制作Pizza,披萨的制作流程有材料的准备材料、烤、切、包装几步。如何设计Pizza的订购呢?按照一般的设计思路:

    那么当用户订购时:

        Pizza OrderPizza(String orderType) {
            Pizza pizza;
    
            if (orderType.equals("veggie")) {
                pizza = new VeggiePizza();
            } else if (orderType.equals("cheese")) {
                pizza = new CheesePizza();
            } else if (orderType.equals("pepper")) {
                pizza = new PepperPizza();
            }
            
            // pizza制作过程
            pizza.prepare();
            pizza.bake();
            pizza.cut();
            pizza.box();
            return pizza;
        }
    

    然而当披萨店增加或者删除披萨类型时,必须修改OrderPizza的代码。例如想要添加一个“中国披萨”,那么就要添加:

            else if (orderType.equals("china")) {
                pizza = new ChinaPizza();
            }
    

    也就是说,只要披萨菜单存在改动,这段代码就得一改再改,这种设计明显违反了“开放-关闭原则” ,并没有做到对修改“关闭”。同时,如果有多个订单,那么每个订单也必须依赖每个子类,这样就显得冗杂。如何优化呢?这里得引出“简单工厂模式”了。

    1.2 定义与结构

    简单工厂模式(Simple Factory Pattern):又称为静态工厂方法(Static Factory Method)模式,简单工厂模式中专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。

    直白地讲,简单工厂把实例化的操作单独放到一个类中,这个类就成为简单工厂类,让简单工厂类来决定应该用哪个具体子类来实例化,这样做能把客户类和具体子类的实现解耦,客户类不再需要知道有哪些子类以及应当实例化哪个子类。

    简单工厂模式并不在 GoF 23 种设计模式之列,与其说其是设计模式,不如说是一种编程习惯

    简单工厂模式中包含如下角色:

    • Factory:工厂角色

      工厂角色负责实现创建所有实例的内部逻辑。

    • Product:抽象产品角色

      抽象产品角色是所创建的所有对象的父类,负责描述所有实例所共有的公共接口。

    • ConcreteProduct:具体产品角色

      具体产品角色是创建目标,所有创建的对象都充当这个角色的某个具体类的实例。

    类图

    时序图

    1.3 实现

    将简单工厂模式运用到上面的披萨店中,那么就得建造一个SimpleFactory工厂类,它被所有需要进行实例化的客户类调用。

    public class SimpleFactory {
        public Pizza createPizza(String orderType) {
            Pizza pizza = null;
    
            if (orderType.equals("veggie")) {
                pizza = new VeggiePizza();
            } else if (orderType.equals("cheese")) {
                pizza = new CheesePizza();
            } else if (orderType.equals("pepper")) {
                pizza = new PepperPizza();
            }
            return pizza;
        }
    }
    

    客户代码为:

    public PizzaStore{
        SimpleFactory simpleFactory;
        
        public OrderPizza(SimpleFactory simpleFactory) {
            this.simpleFactory = simpleFactory;
        }
        
    	public Pizza orderPizza(String orderType) {
            Pizza pizza;
            
            pizza = simpleFactory.createPizza(orderType);
            
            pizza.prepare();
            pizza.bake();
            pizza.cut();
            pizza.box();
            return pizza;
        }
        
        // 其他方法
    }
    

    1.4 小结

    优点

    • 工厂类含有必要的判断逻辑,可决定创建产品类的实例的实际时刻。工厂和产品的职责区分明确,客户端仅仅“消费”产品。
    • 客户端只需要知道具体产品类所对应的参数即可。
    • 通过引入配置文件,可在不修改任何客户端代码的情况下更换和增加新的具体产品类,提高了系统的灵活性。

    缺点

    • 工厂类集中了所有产品创建逻辑,职责过重,一旦发生异常,整个系统将受影响。
    • 使用简单工厂模式将会增加系统中类的个数,在一定程序上增加了系统的复杂度和理解难度。
    • 系统扩展困难,一旦增加新产品不得不修改工厂逻辑,在产品类型较多时,可能造成逻辑过于复杂。
    • 简单工厂模式由于使用了静态工厂方法,造成工厂角色无法形成基于继承的等级结构。

    适用场景

    对于产品种类相对较少的情况,考虑使用简单工厂模式。使用简单工厂模式的客户端只需要传入工厂类的参数,不需要关心如何创建对象的逻辑,可以很方便地创建所需产品。

    • 如JDK类库中工具类java.text.DateFormat,它用于格式化一个本地日期或者时间。
    public final static DateFormat getDateInstance();
    public final static DateFormat getDateInstance(int style);
    public final static DateFormat getDateInstance(int style,Locale locale);
    

    2 工厂方法(Factory Method)

    2.1 问题引出

    假如披萨店在各个地儿都有,比如Beijing,Shanghai…他们都保有他们城市的风味。要吃到不同城市风味的披萨,如果运用简单工厂模式:

    // 这里创建的工厂,全是在北京地区的工厂
    BeijingFactory beijingFactory = new BeijingFactory();
    // 创建一个披萨店,将北京工厂的引用作为参数
    PizzaStore pizzaStore = new PizzaStore(beijingFactory);
    // 制作披萨时,就会得到在北京地区的奶酪披萨
    pizzaStore.orderPizza("CheesePizza");
    

    同理,上海的披萨店也类似:

    ShanghaiFactory shanghaiFactory = new ShanghaiFactory();
    PizzaStore pizzaStore = new PizzaStore(shanghaiFactory);
    pizzaStore.orderPizza("CheesePizza");
    

    然而,这样使得代码缺乏弹性。如何弹性地制作出具有一定规范但又不失本地特色的披萨呢?这里就得引出工厂方法模式了。

    2.2 定义与结构

    工厂方法模式(Factory Method Pattern)又称为工厂模式,也叫虚拟构造器(Virtual Constructor)模式或者多态工厂(Polymorphic Factory)模式,它属于类创建型模式。在工厂方法模式中,工厂父类负责定义创建产品对象的公共接口,而工厂子类则负责生成具体的产品对象,这样做的目的是将产品类的实例化操作延迟到工厂子类中完成,即通过工厂子类来确定究竟应该实例化哪一个具体产品类。

    直白地讲,“工厂方法模式”是对简单工厂模式的进一步抽象化,只是工厂方法把产品的实例化操作推迟到子类

    工厂方法模式由4个要素构成。

    • 抽象工厂(Abstract Factory):提供了创建产品的接口,调用者通过它访问具体工厂的工厂方法 createProduct() 来创建产品。
    • 具体工厂(ConcreteFactory):主要是实现抽象工厂中的抽象方法,完成具体产品的创建。
    • 抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能。
    • 具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间一一对应。

    类图

    时序图

    2.3 实现

    还是以上面披萨制作为例,那么就可以把createPizza(style)放回PizzaStore中,不过设置为“抽象方法”,然后每个区域设置自己的PizzaStore子类。

    public abstract class PizzaStore {
    	public Pizza orderPizza(String orderType) {
            Pizza pizza;
            
            pizza = createPizza(orderType);
            
            pizza.prepare();
            pizza.bake();
            pizza.cut();
            pizza.box();
            return pizza;
        }
        
        abstract Pizza createPizza(String orderType);
    }
    

    那么创造怎么样口味的披萨由子类工厂决定:

    public class MyStyleStore extends PizzaStore {
        Pizza createPizza(String type) {
            if (type.equals("veggie")) {
                pizza = new MyStyleVeggiePizza();
            } else if (type.equals("cheese")) {
                pizza = new MyStyleCheesePizza();
            } else if (type.equals("pepper")) {
                pizza = new MyStylePepperPizza();
            }
        }
    }
    
    public class BeijingStore extends PizzaStore {
        Pizza createPizza(String type) {
            if (type.equals("veggie")) {
                pizza = new BeijingVeggiePizza();
            } else if (type.equals("cheese")) {
                pizza = new BeijingCheesePizza();
            } else if (type.equals("pepper")) {
                pizza = new BeijingPepperPizza();
            }
        }
    }
    

    2.4 小结

    优点

    • 用户只需要关心所需产品对应的工厂,无须关心创建细节,甚至无须知道具体产品类的类名。
    • 灵活性增强,对于新产品的创建,只需多写一个相应的工厂类。
    • 典型的解耦框架。高层模块只需要知道产品的抽象类,无须关心其他实现类,满足迪米特法则、依赖倒置原则和里氏替换原则。

    缺点

    • 类的个数容易过多,增加复杂度。
    • 考虑到系统的可扩展性,需要引入抽象层,在客户端代码中均使用抽象层进行定义,增加了系统的抽象性和理解难度。
    • 抽象产品只能生产一种产品。

    适用场景

    在工厂方法模式中,客户端不需知道具体产品类的类名,只需知道创建具体产品的工厂类;对于抽象工厂类,只需要提供一个创建产品的接口,而由其子类来确定具体要创建的对象。

    工厂方法模式在JDK类库中运用比较多,例如:

    3 抽象工厂(Abstract Factory)

    3.1 问题引出

    为了更清晰地理解工厂方法模式,先理解两个概念:

    • 产品等级 :产品等级结构即产品的继承结构,如一个抽象类是电视机,其子类有海尔电视机、海信电视机、TCL电视机,则抽象电视机与具体品牌的电视机之间构成了一个产品等级结构,抽象电视机是父类,而具体品牌的电视机是其子类。
    • 产品族 :在抽象工厂模式中,产品族是指由同一个工厂生产的,位于不同产品等级结构中的一组产品,如海尔电器工厂生产的海尔电视机、海尔电冰箱,海尔电视机位于电视机产品等级结构中,海尔电冰箱位于电冰箱产品等级结构中。

    电器工厂的产品等级与产品族

    3.2 定义与结构

    抽象工厂模式(Abstract Factory Pattern):提供一个接口,用于创建创建一系列相关或相互依赖对象的家族,而无须指定它们具体的类。抽象工厂模式又称为Kit模式,属于对象创建型模式。

    抽象工厂模式与工厂方法模式区别在于,工厂方法模式针对的是一个产品等级结构,而抽象工厂模式则需要面对多个产品等级结构,一个工厂等级结构可以负责多个不同产品等级结构中的产品对象的创建 。

    抽象工厂模式同工厂方法模式一样,也是由4 个要素构成,但抽象工厂中方法个数不同,抽象产品的个数也不同。

    • AbstractFactory:抽象工厂
    • ConcreteFactory:具体工厂
    • AbstractProduct:抽象产品
    • Product:具体产品

    类图

    时序图

    3.3 实现

    public class AbstractProductX {
    }
    
    public class AbstractProductY {
    }
    
    public class ConcreteProductAX extends AbstractProductX {
    }
    
    public class ConcreteProductBX extends AbstractProductX {
    }
    
    public class ConcreteProductAY extends AbstractProductY {
    }
    
    public class ConcreteProductBY extends AbstractProductY {
    }
    
    public abstract class AbstractFactory {
        abstract AbstractProductX createProductX();
        abstract AbstractProductY createProductY();
    }
    
    public class ConcreteFactoryA extends AbstractFactory {
        AbstractProductX createProductX() {
            return new ProductAX();
        }
    
        AbstractProductY createProductY() {
            return new ProductAY();
        }
    }
    
    public class ConcreteFactoryB extends AbstractFactory {
        AbstractProductX createProductX() {
            return new ProductBX();
        }
    
        AbstractProductY createProductY() {
            return new ProductBY();
        }
    }
    
    public class Client {
        public static void main(String[] args) {
            AbstractFactory abstractFactory = new ConcreteFactoryA();
            AbstractProductX productX = abstractFactory.createProductX();
            AbstractProductY productY = abstractFactory.createProductY();
            // do something with productX and productY
        }
    }
    

    3.4 小结

    优点

    • 抽象工厂模式隔离了具体类的生成,使得客户并不需要知道什么被创建,从具体的产品解耦出来。
    • 当一个产品族中的多个对象被设计成一起工作时,它能够保证客户端始终只使用同一个产品族中的对象。
    • 增加新的具体工厂和产品族很方便,无须修改已有系统,符合“开闭原则”。

    缺点

    • 开闭原则的倾斜性(增加新的工厂和产品族容易,增加新的产品等级结构麻烦)

    工厂方法模式在JDK类库中的运用:

    4 总结

    严格地讲,简单工厂模式并不在GoF23种设计模式之列,更像是一种编程习惯,也可以理解为工厂方法模式的特殊情况之一。

    • 简单工厂方法实现了客户类与其子类的解耦。

    • 工厂方法模式属于类创建型模式,它把产品的实例化操作也推迟到子类,实现了产品类与其子类的解耦。

    • 抽象工厂模式属于对象创建型模式,相对工厂方法模式针对一个产品等级结构,抽象工厂模式则需要面对多个产品等级结构,一个抽象工厂等级结构可以负责多个不同产品等级结构中的产品对象的创建 。

    三种设计模式都各有优缺点,在实际开发中,我们应该根据实际业务需求来选择。

    参考

    展开全文
  • 工厂方法模式

    万次阅读 多人点赞 2019-05-31 20:40:44
    本章将通过如何克服简单工厂模式的不足来引出工厂方法模式,并通过实例来学习工厂方法模式,理解工厂方法模式的结构及特点,学会如何在实际软件项目开发合理地使用工厂方法模式。 本章知识点 工厂方法模式的定义 ...
  • 快速理解工厂方法模式,及其在源码中的应用
  • 区分三种工厂模式,简单工厂模式,工厂方法模式和抽象工厂模式。
  • 工厂方法模式:Factory Method 在我们的日常开发中,很多地方都可以用上工厂方法模式(事实是基础开发中,大部分人从来都不会去考虑使用)。 工厂方法模式英文定义: Define an interface for creating an object...
  • 简单工厂模式 看一个具体的需求 看一个披萨的项目:要便于披萨种类的扩展,要便于维护 (1)披萨的种类很多(比如GreekPizz、CheesePizz等) (2)披萨的制作有prepare,bake, cut, box (3)完成披萨店订购功能。 ...
  • java 三种工厂模式(简单工厂+工厂方法+抽象工厂)

    万次阅读 多人点赞 2019-06-04 10:51:15
    因为在简单工厂模式中用于创建实例的方法是静态(static)方法,因此简单工厂模式又被称为静态工厂方法模式,它属于类创建型模式。 工厂模式结构图 简单工厂模式角色   在简单工厂模式结构图中包含如下几个角色: ...
  • 简单工厂模式是属于创建型模式,在简单工厂模式中用于被创建实例的方法通常为静态(static)方法,因此又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象...
  • 1.什么是工厂方法模式 工厂方法模式是一种创建型设计模式, 其在父类中提供一个创建对象的方法, 允许子类决定实例化对象的类型。 2. 工厂方法模式优/缺点和使用场景 2.1 工厂方法模式优点 工厂方法模式是为了克服...
  • 工厂方法(Factory Method)

    千次阅读 2022-03-30 15:59:59
    (1) Product(抽象产品):它是定义产品的接口,是工厂方法模式所创建对象的超类型,也就是产品对象的公共父类 (2) ConcreteProduct(具体产品):它实现了抽象产品接口,某种类型的具体产品由专门的具体工厂创建,具体工厂和...
  • 简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单...
  • 工厂方法

    千次阅读 2018-09-08 15:22:37
    工厂方法 示例 使用典范 工厂方法 定义 :定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类,工厂方法让类的实例化推迟到子类中进行 创建型 :创建型 适用场景: 创建对象需要大量重复的...
  • 简单工厂/工厂方法/抽象工厂

    万次阅读 2020-10-25 22:56:14
    * 缺点:新增实现类时,需要修改代码,不好动态扩展(可参考工厂方法) */ public class SimpleFactoryDP { public final class Const { static final int PRODUCT_A = 0; static final int PRODUCT_B = 1; }...
  • 简单工厂模式 工厂方法模式 抽象工厂模式
  • 简单工厂、工厂方法、抽象工厂区别

    万次阅读 多人点赞 2018-08-17 11:38:19
    结合简单示例和UML图,讲解工厂模式简单原理。 一、引子 话说十年前,有一个爆发户,他家有三辆汽车(Benz(奔驰)、Bmw(宝马)、Audi(奥迪)),还雇了司机为他开车。不过,爆发户坐车时总是这样:上Benz车后跟...
  • 工厂模式一般分为简单工厂模式,工厂方法模式,抽象工厂模式。各有优缺点,今天这里还加入了简单工厂模式的另一种实现,添加反射实现简单工厂。 例子  一个很简单的例子:有个富豪想买奔驰,宝马,福特汽车,开...
  • 工厂方法模式:定义一个用于创建对象的接口,但是让子类决定将当一个类实例化。 /**抽象工厂可以是接口,也可以是抽象类或者具体类*/ public interface Factory{ public Product factoryMethod(); } /**具体...
  • 工厂方法和抽象工厂的区别

    千次阅读 2021-03-01 20:05:56
    工厂方法: 抽象工厂方法: 图示: 区别: 联系:
  • Java 使用静态工厂方法替代构造方法

    千次阅读 2020-04-13 09:35:06
    1. 考虑使用静态工厂方法替代构造方法 一个类允许客户端获取其实例的传统方式是提供一个公共构造方法。 其实还有另一种技术应该成为每个程序员工具箱的一部分。 一个类可以提供一个公共静态工厂方法,它只是一个返回...
  • 文章目录前言一、举例说明工厂方法模式1、程序代码二、使用步骤1.引入库2.读入数据总结 前言 在之前单例模式的学习中,愈发的感觉到设计模式的精妙,设计模式就像是一种思想,能够很好的嵌入到自己的代码当中,本文...
  • 一、简单工厂模式 例如:一个动物基类(抽象基类):...二、工厂方法模式 例如:一个动物基类(抽象基类):描述什么是动物 N个动物类(继承抽象类):具体是什么动物,狗猫兔 一个抽象工厂接口(接口) 创建生产动物的工厂实现类(实
  • 关于简单工厂模式,工厂方法模式,抽象工厂模式的一次总结 模式 定义 简单工厂模式 定义一个工厂类,它可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类。 工厂方法模式 定义一个...
  • 抽象工厂模式的区别及优缺点及使用场景简单工厂普通简单工厂多方法简单工厂静态方法简单工厂工厂方法模式抽象工厂模式 工厂模式是java设计模式中比较简单的一个设计模式,但很多地方都用到了工厂模式,(如解析xml...
  • 工厂方法模式 工厂模式的本质 实例化对象不使用new,用工厂方法代替 将选择实现类,创建对象统一管理和控制。从而将调用者跟我们的实现解耦 - oop七大原则 开闭原则:一个软件的实体应当对扩展开放,对修改关闭 ...
  • 工厂方法模式 工厂方法模式(Factory Method Pattern):定义一个用于创建对象的接口,让子类决定将哪一个类实例化。工厂方法模式让一个类的实例化延迟到其子类。 工厂方法模式又简称为工厂模式(Factory Pattern),...
  • Java 静态工厂方法详解

    千次阅读 多人点赞 2019-04-08 19:09:54
    Java 静态工厂方法详解 本文章主要是对《Effective Java》对静态工厂方法的理解 第一次使用静态工厂方法是在HIT《Software Construction》课程的Lab2-P1的Graph.java中,对静态工厂方法的理解也相当有限,因此撰写...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 559,277
精华内容 223,710
关键字:

工厂方法