在面向对象编程中,创建对象实例最常用的方式就是通过 new *** 作符构造一个对象实例,但在某些情况下,new *** 作符直接生成对象会存在一些问题。举例来说,对象的创建需要一系列的步骤:可能需要计算或取得对象的初始位置、选择生成哪个子对象实例、或在生成之前必须先生成一些辅助对象。 在这些情况,新对象的建立就是一个 “过程”,而不仅仅是一个 *** 作,就像一部大机器中的一个齿轮传动。
针对上面这种情况,我们如何轻松方便地构造对象实例,而不必关心构造对象示例的细节和复杂过程?解决方案就是使用一个工厂类来创建对象。
工厂模式将目的将创建对象的具体过程屏蔽隔离起来,从而达到更高的灵活性
在23种设计模式中,工厂模式就占有两种设计模式:
简单工厂模式(属于创建性模式,但不属于设计模式)
工厂方法模式
抽象工厂模式。
简单工厂模式通常使用静态方法构建,使用静态方法时又叫做静态工厂模式,简单工厂模式更像是一种编程习惯。
简单工厂说白了就是一个超级工厂,他可以生产各种各样的产品,产品之间无关联,比如:
简单工厂主要包括以下角色:
1、抽象产品:定义了产品的规范,描述了产品的主要特性和功能
2、具体产品:实现或继承抽象产品的子类
3、具体工厂:提供了创建产品的方法,调用者通过该方法来获取产品
public class SimpleCoffeeFactory{
public Coffee createCoffee(String type){
Coffee coffee;
if(type.equlas("A")){
coffee = new AmericanCoffee();
}else{
coffee = new LatteCoffee();
}
return coffee;
}
}
从代码可以看到简单工厂模式缺点:
优点:
封装了创建对象的过程,可以通过参数直接获取对象。把对象的创建和业务逻辑分开,如果要实现新产品直接修改工厂类,更容易扩展。
缺点:增加新产品时还是需要修改工厂类,违反了开闭原则。
在开发中也有一部分人将工厂类中的创建对象的功能定义为静态的,这个就是静态工厂模式,它也不是23种设计模式中的。
public class StaticCoffeeFactory{
public static Coffee createCoffee(String type){
Coffee coffee;
if(type.equals("A")){
coffee = new AmericanCoffee();
}else{
coffee = new LatteCoffee();
}
return coffee;
}
}
3、工厂方法模式
工厂方法模式将工厂抽象化,并定义一个创建对象的接口。每增加新产品,只需增加该产品以及对应的具体实现工厂类,由具体工厂类决定要实例化的产品是哪个,将对象的创建与实例化延迟到子类,这样工厂的设计就符合“开闭原则”了,扩展时不必去修改原来的代码。在使用时,用于只需知道产品对应的具体工厂,关注具体的创建过程,甚至不需要知道具体产品类的类名,当我们选择哪个具体工厂时,就已经决定了实际创建的产品是哪个了。
但缺点在于,每增加一个产品都需要增加一个具体产品类和实现工厂类,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。
工厂方法模式主要包括以下角色:
1、抽象工厂 AbstractFactory: 工厂方法模式的核心,是具体工厂角色必须实现的接口或者必须继承的父类,在 Java 中它由抽象类或者接口来实现。
2、具体工厂 Factory:被应用程序调用以创建具体产品的对象,含有和具体业务逻辑有关的代码
3、抽象产品 AbstractProduct:是具体产品继承的父类或实现的接口,在 Java 4、 中一般有抽象类或者接口来实现。
具体产品 Product:具体工厂角色所创建的对象就是此角色的实例。
产品类:
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();
}
4、抽象工厂模式
在工厂方法模式中,我们使用一个工厂创建一个产品,一个具体工厂对应一个具体产品,但有时候我们需要一个工厂能够提供多个产品对象,而不是单一的对象,这个时候我们就需要使用抽象工厂模式。
在介绍抽象工厂模式前,我们先清楚两个概念:
产品等级结构:产品等级结构指的是产品的继承结构,例如一个空调抽象类,它有海尔空调、格力空调、美的空调等一系列的子类,那么这个空调抽象类和他的子类就构成了一个产品等级结构。
产品族:产品族是指由同一个工厂生产的,位于不同产品等级结构中的一组产品。比如,海尔工厂生产海尔空调、海尔冰箱,那么海尔空调则位于空调产品族中。
抽象工厂主要包括以下角色:
1、抽象工厂 AbstractFactory:定义了一个接口,这个接口包含了一组方法用来生产产品,所有的具体工厂都必须实现此接口。
2、具体工厂 ConcreteFactory:用于生产不同产品族,要创建一个产品,用户只需使用其中一个工厂进行获取,完全不需要实例化任何产品对象。
3、抽象产品 AbstractProduct:这是一个产品家族,每一个具体工厂都能够生产一整组产品。
4、具体产品 Product
工厂的抽象接口
public interface MethodFactory {
//生产一个冰箱
Refrigerator createRefiger();
//生产一个空调
AirConditioning createAirConditioning();
//生产一个 TV
TV createTV();
}
这里我们创建格力工厂、海尔工厂和海信工厂。
public class GeliFactory implements MethodFactory {
@Override
public Refrigerator createRefiger() {
return new GeliRefrigerator();
}
@Override
public AirConditioning createAirConditioning() {
return new GeliAirConditioning();
}
@Override
public TV createTV() {
return new GeliTV();
}
}
格力工厂返回的是格力的空调、格力的冰箱以及格力的电视机,海尔和海信也都会返回他们自己品牌的产品,这里就不贴他们的代码了,一样的代码,只是不一样的实现。
抽象工厂模式可能不如前两者常见,但是确是为了补充前两者的,有特定的场景。
想象这么一种情况,你使用了工厂方法模式,你的工厂提供的能力非常多,可以生产冰箱、电视、空调、洗衣机、电脑以及桌子等等,这样你就会产生很多的工厂。
抽象工厂的作用就是在一定前提下,帮你分类这些工厂,比如按品牌分类,或者按照价格等级分类,这样会大大缩减系统中的工厂数量。
这个前提就是你的这些工厂需要在两个维度上具备共性:
专业术语就是『产品等级』和『产品族』两个概念,说人话就是,这些工厂需要至少具有两个共性,比如都可以按照类型区分成三类,电视机、冰箱和空调,也可以按照品牌区分成海尔、海信和 TCL。
这样他们就具备抽象工厂的前提条件,你可以按照产品族合并工厂,正如我上面使用到的例子一样,工厂对外提供生产电视、冰箱和空调三种能力,而系统按品牌存在三个工厂。
抽象工厂其实就是帮助减少系统的工厂数量的,但前提条件就是这些工厂要具备两个及以上的共性。
5、总结看了网上各种对工厂模式的描述,内容很杂,自己大概整理一下。
**简单工厂模式:**就是在一个工厂里返回各种产品,违反了开闭原则,不属于设计模式,用静态方法构建时就是我们耳熟能详的静态工厂模式。
**工厂方法模式:**通过抽象工厂接口,为每个产品建立一个工厂类,比如空调工厂类,电视工厂类等等,符合设计原则,但是后期拓展有困难,我想加一个新的产品只能不断的拓展工厂类,还要考虑到空调有多种,如美的空调,格里空调等等。
**抽象工厂模式:**为了解决工厂方法的拓展,根据『产品等级』和『产品族』对产品进行分类,根据产品共性减少工厂的数量。比如从产品品牌上划分出格里工厂,美的工厂生产空调,电视,洗衣机等产品;从产品属性上抽象出电视工厂,空调工厂等。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)