前言:设计模式已经发展了很长时间,它们为软件开发过程中面临的常见问题提供了最佳解决方案。学习这些模式可以帮助经验不足的开发人员快速轻松地学习软件设计。一般来说,我们会说有23种设计模式。总的来说,设计模式分为三类:创建型模式,一共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。共有七种结构模式:Adapter模式、Decorator模式、Proxy模式、Appearance模式、Bridge模式、Composition模式、Flyweight模式。行为模式有十一种类型:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式和解释器模式。今天主要是分析简单工厂模式、工厂模式和抽象工厂模式的区别,所以这里简单介绍一下设计模式的概念。网上很多资料都在阐述:工厂模式的好处就是解耦。解耦这个词相信大家都不陌生,那么解耦有什么好处呢?1、为了提高内聚和松耦合,我们常常将一些类的公共接口抽象出来,形成抽象基。类或接口。这样,我们就可以通过声明一个基类指针指向实际的子类实现来达到多态的目的。这里容易出现的一个问题是很多子类继承自抽象基类,我们不得不写new×××;每次使用子类。这里有两个问题:客户端程序员必须知道实际子类的名称(当系统复杂时,命名将是一个非常难处理的问题,为了处理可能的名称冲突,有些命名可能不是很良好的可读性和可记忆性,无论不同程序员的个人喜好如何)。程序的可扩展性和维护性变得越来越困难。2.另一种情况是父类不知道要具体实例化哪个子类。这里的意思是:假设我们要在A类中使用B类,B是一个抽象父类。在A中,我们不知道要实例化B的哪个子类,但是在A类的子类D中是可以知道的。在A中,我们没有办法直接使用类似new×××的语句,因为我们根本不知道×××是什么。以上两个问题也引出了工厂模式最重要的两个功能:定义创建对象的接口,封装对象的创建;将具体类的工作延迟到子类。对于工厂模式,为了更好的解决各种情况下的问题,分为三类:简单工厂模式(SimpleFactory)、工厂方法模式(FactoryMethod)、抽象工厂模式(AbstractFactory)。GOAT经常会遇到一些设计模式的使用,却很少去研究里面的差异。把我知道的三种工厂模式分享给大家。简单工厂模式我们称创建的对象为“产品”,创建产品的对象为“工厂”。如果要创建的产品不多,可以只完成一个工厂类。这种模式被称为“简单工厂模式”。结构定义:工厂对象确定要创建产品类的哪个实例。简单工厂模式包含的角色及相应职责如下:工厂角色(Creator):这是简单工厂模式的核心,负责创建所有类的内部逻辑。当然,工厂类必须能够被外界调用来创建需要的产品对象。抽象(Product)产品作用:简单工厂模式创建的所有对象的父类。注意这里的父类可以是接口也可以是抽象类,它负责描述所有实例共享的公共接口。具体产品角色:由简单工厂创建的具体实例对象,这些具体产品通常有一个共同的父类。定义用于创建产品对象的工厂接口,并将产品对象的实际创建推迟到特定的子工厂类。这满足了创建模式所要求的“创建与使用分离”的特性。结构图如下范例如下:C++实现#includeusingnamespacestd;enumProduct_Type{Product1_,Product2_,};classAbstractProduct//抽像(Product)产品角度{public:AbstractProduct(){}virtual~AbstractProduct(){}virtualvoidShow()=0;};classProduct1:publicAbstractProduct//具体产品(ConcreteProduct)角色{private:/*data*/public:Product1(/*args*/);~Product1();voidShow(){std::cout<<"product1"<CreateProduct(Product1_);new_product1->Show();AbstractProduct*new_product2=new_factory->CreateProduct(Product2_);new_product2->Show();deletenew_factory,new_product1,new_product2;new_factory=NULL;new_product1=NULL;new_product2=NULL;}python实现#!/usr/bin/python3fromenumimportEnumProductType=Enum(('ProductType'),('product1_','product2_','product_3'))classAbstractProduct(object):defshow(self):passclassProduct1(AbstractProduct):defshow(self):print("Product1")classProduct2(AbstractProduct):defshow(self):print("Product2")classAbcFactory(object):defcrete_product(self):passclassFactory(AbcFactory):defcrete_product(self,type):product_type={ProductType.product1_:Product1(),ProductType.product2_:Product2()}returnproduct_type.get(type,None)if__name__=="__main__":new_factory=Factory()product1=new_factory.crete_product(ProductType.product1_)product1.show()product2=new_factory.crete_product(ProductType.product2_)product2.show()我们只需要调用不同的成员函数,工厂会帮我们实例化出想要的对象,并通过转换对象返回父类实现结果可以发现,简单工厂模式的代码虽然简单,但是不符合OCP(面向对象设计的基本原则之一OCP(OpenandClosedPrinciple):一个软件实体应该是对扩展开放,对修改关闭)。总结:1、简单工厂模式最大的优点是工厂类可以判断客户的选择动态实例化相关类。对于客户来说,消除了对特定产品的依赖。2、缺点是:很明显工厂类集中了创建所有实例的逻辑。如果我们要增加新的子类或者改变方法,每次都得修改工厂类中的代码,而工厂类中的代码会很复杂。臃肿,这就是说我们不开扩展,还要开修改,违反了开闭原则。您可能在不知情的情况下使用过这种模式,但是简单工厂模式并不是23种设计模式中的一种。这是它的改进版本:工厂方法模式。工厂模式工厂方法模式是一种创建型设计模式,它提供了在父类中创建对象的方法,并允许子类确定实例化对象的类型。工厂方法模式的结构组成:抽象工厂(AbstractFactory):工厂方法模式的核心类,提供创建具体产品的接口,由具体的工厂类实现。具体工厂类(Producer):继承于抽象工厂,实现创建相应具体产品对象的方式。抽象产品类(Factory):是具体产品继承的父类(基类)。具体产品类别(Factory1):具体工厂创建的对象就是这个类别。C++实现#includeusingnamespacestd;classAbstractProduct{public:AbstractProduct(){}virtual~AbstractProduct(){}virtualvoidShow()=0;};classProduct1:publicAbstractProduct{private:/*data*/public:Product1(/*args*/);~Product1();voidShow(){std::cout<<"product1"<CreateProduct();new_product1->Show();deletenew_factory;new_factory=NULL;Factory2*new_factory2=newFactory2();AbstractProduct*new_product2=new_factory2->CreateProduct();new_product2->Show();deletenew_factory2;new_factory2=NULL;}python实现#!/usr/bin/python3classAbstractProduct(object):defshow(self):passclassProduct1(AbstractProduct):defshow(self):print("Product1")classProduct2(AbstractProduct):defshow(self):print("Product2")classFactory(object):defcreate_product(self):passclassFactory1(Factory):defcreate_product(self):returnProduct1()产品classFactory2(Factory):defcreate_product(self):returnProduct2()if__name__=="__main__":new_product1=Factory1().create_product()new_product1.show()new_product2=Factory2().create_product()new_product2.show()工厂方法模式的优点和缺点1.可以避免创建者和具体产品之间的紧耦合2.单一职责原则。您可以将产品创建代码放在程序中的单个位置,使代码更易于维护。3、开闭原则。您可以在不更改现有客户端代码的情况下将新产品类型引入您的程序中。4、应用工厂方法模式需要引入很多新的子类,代码可能会变得更复杂。最好的情况是将模式引入现有的创建者类层次结构中。抽象工厂模式抽象工厂模式是一种创建型设计模式,它创建一系列相关对象而不指定它们的具体类。更多的是重工厂模式。结构定义(类似于工厂模式):抽象工厂(AbstractFactory):工厂方法模式的核心类,提供创建具体产品的接口,由具体的工厂类实现。具体工厂类(Producer):继承于抽象工厂,实现创建相应具体产品对象的方式。抽象产品类(Factory):是具体产品继承的父类(基类)。具体产品类别(Factory1):具体工厂创建的对象就是这个类别。结构图如下C++实现#includeusingnamespacestd;classAbstractProductA{public:AbstractProductA(){}virtual~AbstractProductA(){}virtualvoidShow()=0;virtualvoidDisp()=0;};classProductA1:publicAbstractProductA{private:/*数据*/public:ProductA1(){}~ProductA1(){}voidShow(){std::cout<<"productA1show"<CreateProductA();new_productA2->Show();Factory1*new_factory1=newFactory1();AbstractProductB*new_productB1=new_factory1->CreateProductB();new_productB1->Show();}python现实python现实#!/usr/bin/python3classAbstractProductA(object):defshow(self):passdefdisp(self):passclassProductA1(AbstractProductA):defshow(self):print("ProductA1show")defdisp(self):print("productA1disp")classProductA2(AbstractProductA):defshow(self):print("ProductA2show")defdisp(self):print("productA2disp")classAbstractProductB(object):defshow(self):passdefdisp(self):passclassProductB1(AbstractProductB):defshow(self):print("ProductB1show")defdisp(self)):打印(“productB1disp”)classProductB2(AbstractProductB):defshow(self):打印(“ProductB2show”)defdisp(self):print(“productB2disp”)classFactory(对象):defcrete_product1(self):passdefcrete_product2(self):passclassFactoryA(object):defcrete_product1(self):returnProductA1()defcrete_product2(self):returnProductA2()classFactoryB(object):defcrete_product1(self):returnProductB1()defcrete_product2(self):returnProductB:"__new__2=="f__=FactoryA()new_product1=new_factory.crete_product1()new_product1.show()new_product2=new_factory.crete_product2()new_product2.disp()抽象工厂模式的优缺点1.可以保证同一个工厂生成的产品相互匹配,避免clients和特定产品代码的耦合。2.单一责任原则。你可以将产品生成的代码提取到同一位置,使代码易于维护。3、开闭原则。在将新产品变体引入您的应用程序时,您无需修改??客户端代码。4.因为采用这种模式需要在应用中引入很多接口和类,所以代码可能会比以前更复杂。本文转载自微信公众号“羽林君”,可通过以下二维码关注。转载本文请联系羽林君公众号。