透过静态四个字就能够知晓须要有三个静态的厂子方法,        工厂情势首如果为创设对象提供过渡接口

定义

粗略工厂情势并不属于GoF(Gang of
Four四人组)第23中学设计情势,有些地点的诠释说因为简单工厂形式太简单,所以第23中学设计方式就从不独自列出。
唯独不难工厂形式在实际的应用中却很常用,因而在Liu Wei的《设计方式》一书中就照旧列了出去。
不难易行工厂形式引用书中的定义如下:

简不难单工厂方式(Simple Factory
Pattern):定义叁个工厂类,它能够依据参数的分歧重回差别类的实例,被创建的实例通常都独具共同的父类。因为在简约工厂方式中用于成立实例的章程是静态(static)方法,由此不难工厂方式又被誉为静态工厂方法(Static
Factory Method)格局,它属于类创制型方式

定义

工厂情势其实有广义和狭义的各自,广义的工厂情势指的是简约工厂格局、工厂方法方式、抽象工厂情势四个,而狭义的工厂格局正是此处的厂子方法形式,一般景况下一旦有人直接说工厂方式,多半指的正是工厂方法方式。工厂方法形式引用书中的定义如下:

工厂方法方式(Factory Method
Pattern):定义二个用来创设对象的接口,让子类决定将哪二个
类实例化。工厂方法方式让2个类的实例化延迟到其子类。工厂方法形式又简称为工厂形式
(Factory Pattern),又可称作虚拟构造器格局(Virtual Constructor
帕特tern)或多态工厂方式
(Polymorphic Factory 帕特tern)。工厂方法方式是一系列创制型方式

定义

理解

对此这几个形式,小编认为说静态工厂情势比说简单工厂格局更能令人记忆犹新。静态工厂形式,通过静态四个字就足以清楚需求有叁个静态的工厂方法,然后假若再明白一下叫作工厂,基本上就记住了那一个形式。
那就是说何谓工厂呢,深入人心,生产产品的地点正是工厂。
对于工厂而言,须求有能健康运作的生产线,那个生产线恐怕是全自动化的,也大概是人造操作的,除此之外,还索要有被生产的出品。
根据上面的思绪,大家便足以转移为代码,首先写出大家的产品类:

package patterntest.simplefactorypattern;

/**
 * 产品类
 * 
 * @author tzx
 *
 */
public class MyProduct {
    /**
     * 产品名称
     */
    private String productName;
    /**
     * 产品规格
     */
    private String productSize;

    public String getProductName() {
        return productName;
    }

    public void setProductName(String productName) {
        this.productName = productName;
    }

    public String getProductSize() {
        return productSize;
    }

    public void setProductSize(String productSize) {
        this.productSize = productSize;
    }

    @Override
    public String toString() {
        return "MyProduct [productName=" + productName + ", productSize=" + productSize + "]";
    }

}

有了这么贰个产品类,便能够创设该类的具体产品实例,学习java的肯定知道最基本的创设对象实例的法子正是应用new关键字,比如new MyProduct()。仿佛下面的代码:

package patterntest.simplefactorypattern;

/**
 * 消费者
 * 
 * @author tzx
 *
 */
public class Consumer {

    public static void main(String[] args) {
        System.out.println("我需要一个产品,于是我愉快的制造了一个");
        MyProduct product = new MyProduct();
        System.out.println("我制造的产品是这样的:" + product.getProductSize());
    }

}

那种艺术实际上一定于现实生活中有个别人供给二个如何事物,然后本身制作三个出去。
那种景色现实生活中毫无疑问是存在的,可是也自然有必然的限量,不恐怕各个人都能制作每一种东西,所以还有众多事物个人创造不出去,恐怕说个人创造的本钱太高,因而便有了越发制作某类东西的工厂,也正是我们的厂子类:

package patterntest.simplefactorypattern;

/**
 * 简单工厂
 * 
 * @author tzx
 *
 */
public class MySimpleFactory {

    /**
     * 外部获取产品的工厂方法
     */
    public MyProduct getProduct() {

        return new MyProduct();
    }
}

那正是说这么些时候,大家供给用有个别东西的人,简称为消费者,就不须要本人再制作那类东西,也不供给怎么样制作那类东西,能够进一步便利的运用:

package patterntest.simplefactorypattern;

/**
 * 消费者
 * 
 * @author tzx
 *
 */
public class Consumer {

    public static void main(String[] args) {
        System.out.println("我需要一个产品,于是我向工厂买了一个");
        MyProduct product = new MySimpleFactory().getProduct();
        System.out.println("我买的产品是这样的:" + product.getProductSize());
    }

}

那样一来,大家必要的事物只供给调用工厂的购置格局,大概说工厂提须求各地的获得产品的方法,然后就能赢获得想要的出品了。
不过,有一个很非常慢活的标题应运而生了,上边的代码中,产品确实不须求本人创办,不须求协调new了,可是工厂却是被我们new出来的。
如此难题就大了,也便是自笔者独自要求有个别产品,然后为了那么些产品,作者不可能不本人创建了一个工厂,而且各类要求以此产品的人都要制造四个该产品的工厂,那肯定是不创造也不只怕的。
咱俩需求的唯有是那样而已:

MyProduct product = MySimpleFactory.getProduct();

那便是说工厂方法也就要求改成静态的,使大家只要用类名就足以调用获取产品的艺术:

/**
 * 外部获取产品的工厂方法
 */
public static MyProduct getProduct() {

    return new MyProduct();
}

好了,以后对此某些产品,工厂就制造的提供了三个给各州获取产品的法子,而异乡的消费者也能由此一声MySimpleFactory.getProduct()的呼叫欢快的收获到供给的成品了。
唯独,如若后边这几个工厂扩张了,开端运转的制品不再单一了,例如牙膏,一开始只是大人用的牙膏,前边又扩张了幼儿牙膏,那么很通晓这时候大家工厂提供的获得产品的无参方法就麻烦继续担当重任了。
因为只通过一声我要买牙膏的呼唤,工厂根本不能知道消费者必要的是哪一种,所以大家的工厂方法要求有参数,并且依据不相同的参数给予不一致的成品:

public static MyProduct getProduct(int type) {
    return new MyProduct();
}

如今,基本缓解了上边不亮堂消费者具体要什么样的题材,不过,工厂内部却难于了,因为依照原本产品创造表达说(产品类的概念),工厂能创设出来的产品唯有一种啊。
于是,原本的成品也亟需提高,也等于自己的暗中认可无参构造器不能够满意现有的急需了,我们或者供给增加有参数的构造方法,需求升级原本的出品创设表明书,并透过参数来规定具体的成品。

public MyProduct(int type) {
    if (0 == type) {
        // 提供成年人牙膏
    } else if (1 == type) {
        // 提供儿童牙膏
    }
}

那正是说以上的一些标题也权且缓解了,不管是内需孩子牙膏依然普通牙膏,工厂都能科学的提供,消费者也都能正确的收获。

public static MyProduct getProduct(int type) {
    return new MyProduct(type);
}

只是,借使前边工厂又扩充了,还要投入环境保护牙膏、特效美白牙膏呢?那么大家就需求持续的改动原本的出品构造方法,就像是一本产品创制表明书要持续加厚。
很醒目,那将造成那些有参数的构造方法越来越臃肿,假如每个产品的制作方法都格外复杂的话,大家的一本产品创设表达书也将大概达到必要人抬的境界。
为此,那样不是艺术,大家供给把各自实际产品的炮制表达书分开,也正是大家的产品类须求由3个改成多少个:

/**
 * 普通牙膏
 * 
 * @author tzx
 *
 */
public class MyProduct1 {
    /**
     * 产品名称
     */
    private String productName;
    /**
     * 产品规格
     */
    private String productSize;

    public MyProduct1() {
        addIngredient();
    }

    /**
     * 添加必要成分
     */
    public void addIngredient() {

    }

    public String getProductName() {
        return productName;
    }

    public void setProductName(String productName) {
        this.productName = productName;
    }

    public String getProductSize() {
        return productSize;
    }

    public void setProductSize(String productSize) {
        this.productSize = productSize;
    }

    @Override
    public String toString() {
        return "MyProduct [productName=" + productName + ", productSize=" + productSize + "]";
    }
}

/**
 * 儿童牙膏
 * 
 * @author tzx
 *
 */
public class MyProduct2 {
    /**
     * 产品名称
     */
    private String productName;
    /**
     * 产品规格
     */
    private String productSize;

    public MyProduct2() {
        addIngredient();
        delead();
    }

    /**
     * 去铅
     */
    public void delead() {

    }

    /**
     * 添加必要成分
     */
    public void addIngredient() {

    }

    public String getProductName() {
        return productName;
    }

    public void setProductName(String productName) {
        this.productName = productName;
    }

    public String getProductSize() {
        return productSize;
    }

    public void setProductSize(String productSize) {
        this.productSize = productSize;
    }

    @Override
    public String toString() {
        return "MyProduct [productName=" + productName + ", productSize=" + productSize + "]";
    }
}

明眼人应该一眼就看出了上述代码的标题,那多个类差不多同样,唯独不相同的就是少儿牙膏扩充了一个去铅的艺术。
很明朗,那样的代码是严重重复,不被看好的代码,十足的浪费能源。所以大家须要把这几个共同的事物给提取出来,形成二个父类,而以此父类不是切实可行的产品类,就供给声明为抽象类,然后大家的产品类就活该是这么了:

/**
 * 产品类父类
 * 
 * @author tzx
 *
 */
public abstract class MyProduct {
    /**
     * 产品名称
     */
    protected String productName;
    /**
     * 产品规格
     */
    protected String productSize;

    /**
     * 添加必要成分
     */
    public void addIngredient() {

    }

    public String getProductName() {
        return productName;
    }

    public void setProductName(String productName) {
        this.productName = productName;
    }

    public String getProductSize() {
        return productSize;
    }

    public void setProductSize(String productSize) {
        this.productSize = productSize;
    }

    @Override
    public String toString() {
        return "MyProduct [productName=" + productName + ", productSize=" + productSize + "]";
    }

}

/**
 * 普通牙膏
 * 
 * @author tzx
 *
 */
public class MyProduct1 extends MyProduct {
    public MyProduct1() {
        addIngredient();
    }
}

/**
 * 儿童牙膏
 * 
 * @author tzx
 *
 */
public class MyProduct2 extends MyProduct {
    public MyProduct2() {
        addIngredient();
        delead();
    }

    /**
     * 去铅
     */
    public void delead() {

    }
}

这就是说工厂类中现实产品的精选,就能够改成下面那样:

/**
 * 外部获取产品的工厂方法
 */
public static MyProduct getProduct(int type) {
    MyProduct product = null;
    if (0 == type) {
        product = new MyProduct1();
    } else if (1 == type) {
        product = new MyProduct2();
    }
    return product;
}

理解

对于工厂方法格局的定义,作者以为首先须求留意的是多少个概念上的事物,也便是这一个情势的多少个别称,如虚拟构造器情势、多态工厂方式,依照过去面试的阅历,假如观察知识面,有个别公司是极有或然用这个别称来代表大家熟谙的工厂方式的。
那么要领会工厂方法格局,结合在此以前的简短工厂形式应该就很简单了。
在事先的简要工厂方式中,有2个虚无产品类、若干个具体产品类、三个工厂类和三个静态工厂方法、还有二个消费者类。
事先说到工厂类的工厂方法是提须求外部获得产品的方法,而事实上那几个办法内部也承担了出品的始建,所以也有一对地点说这么些工厂方法是成立产品对象的法门。
而自笔者以为那一个都不重庆大学,首要的是本人的目标只是想要产品的创建和消费者分离,实现松耦合。所以无论是对那二个工厂方法的叙述和精通是何等,只要领悟这几个法子的效率是不再必要消费者自个儿创立产品对象就够了。
不过,简单工厂方式中的那个工厂却有这必然的瑕疵存在,并不适用于具有的地方。
此前的例子中以二个生育儿童牙膏和常见牙膏的厂子作为例子,以后本人的完毕依旧要停留在那个制作牙膏的厂子中。
纵然这么些工厂的经纪一贯依样葫芦,永远都只生育这二种牙膏,那么在此以前的简便工厂完全没有失水准,足以胜任,不过那只是3个即使,现实中的工厂总是要发展壮大的。
乘胜时间的延迟和创收的狠抓,工厂又引进了各个产品,例如特效美白牙膏、一级环保牙膏,不止是牙膏,还有小孩子牙刷、成年人牙刷、普通刷牙杯、创新意识刷牙杯等等,那么从前的厂子方法将变为那样:

    /**
     * 外部获取产品的工厂方法
     */
    public static MyProduct getProduct(int type) {
        MyProduct product = null;
        if (0 == type) {
            // 普通牙膏
            product = new MyProduct1();
        } else if (1 == type) {
            // 儿童牙膏
            product = new MyProduct2();
        } else if (2 == type) {
            // 特效美白牙膏
        } else if (3 == type) {
            // 超级环保牙膏
        } else if (4 == type) {
            // 儿童牙刷
        } else if (5 == type) {
            // 成年人牙刷
        } else if (6 == type) {
            // 普通刷牙杯
        } else if (7 == type) {
            // 创意刷牙杯
        }
        return product;
    }

上边的代码基本没有太现实的处理,已经有个别令人雾里看花,要是再加上更有血有肉的拍卖,或然每一个if里边都会占满三个荧屏,那么如此的代码查找问题以及早先时期维护将会是一场恶梦。
倘诺把这几个类回归实际生育工厂,每二个产品是一条生产线,那么这么多的if和else就会是如此多的生产线。
那般多的生产线放在一个工厂车间中,且不说空间的界定是还是不是容得下,单说管理方面,就会是一种剪不断理还乱。
只要上边包车型地铁厂子遭遇那样的题材,势必会扩大分厂,扩充车间。然后会有一个管制全数分厂的总厂,不担当实际的生育。
而考虑到事先的成品发展时间长,必要量太大,因而只是单个的产品或许就必要1个单身的厂子来生产,由此分厂的安插就是多个分厂只承担一个出品。
代码的逻辑自个儿就源于现实中,那么上边的厂子就必要改变,供给充实工厂类和工厂方法,犹如分厂。
还索要有多个浮泛的工厂类和架空工厂方法作为总厂,正是所谓的虚幻父类。
那么优化后的厂子方法就要求改成如下,首先须求有多少个架空的工厂父类,能够使抽象类,能够使普通类,也能够是接口,不过普通大概就宣称为接口或抽象类,作者那里就扬言为二个接口:

package patterntest.factorypattern;
import patterntest.product.MyProduct;
public interface MyFactory {
    /**
     * 外部获取产品的工厂方法,父类工厂接口
     */
    public MyProduct getProduct(int type);
}

此地定义了3个提须求外部获得产品的联合接口,基本和总结工厂方法里的概念一样,分化的是以此点子不再是静态方法,也从未了措施实体。
有关缘何一直不主意实体,这一个很好通晓,是因为那些接口中这些办法并不要求具体的生产成品,具体的生产工作亟待分厂来做,所以她就应有是空泛的从未有超过实际体的点子。
而为什么不难工厂形式里的工厂方法是static静态的,这里却去掉了static呢?那是因为即便static的不二法门也得以被再三再四,然则却“无法被遮盖”。
对于非static的点子,假如子类重写了那一个法子,当大家用父类调用这么些办法的时候,会调用实际子类的这些点子。
然则若是是static的格局,子类也“重写”了这几个方法,那么再利用父类调用那些方法的时候,调用的要么父类的这些法子,约等于并无法落到实处多态性。
怎么下面的重写要打引号?是因为那几个“重写”,不是大家平时掌握的百般重写,看起来是和父类一模一样的不二法门,不过不可能使用@Override诠释,相当于正是相互独立没有关联的办法。
有了接口和架空方法,作者然后就须要有实际工厂类和措施,可是为了演示,首先还索要提供抽象产品类和骨子里产品类,那里只演示八个:

package patterntest.product;

/**
 * 产品类父类
 * 
 * @author tzx
 *
 */
public abstract class MyProduct {
    /**
     * 产品名称
     */
    protected String productName;
    /**
     * 产品规格
     */
    protected String productSize;

    /**
     * 添加必要成分
     */
    public void addIngredient() {

    }

    public String getProductName() {
        return productName;
    }

    public void setProductName(String productName) {
        this.productName = productName;
    }

    public String getProductSize() {
        return productSize;
    }

    public void setProductSize(String productSize) {
        this.productSize = productSize;
    }

    @Override
    public String toString() {
        return "MyProduct [productName=" + productName + ", productSize=" + productSize + "]";
    }

}

package patterntest.product;

/**
 * 普通牙膏
 * 
 * @author tzx
 *
 */
public class MyProduct1 extends MyProduct {
    public MyProduct1() {
        addIngredient();
    }
}

package patterntest.product;

/**
 * 儿童牙膏
 * 
 * @author tzx
 *
 */
public class MyProduct2 extends MyProduct {
    public MyProduct2() {
        addIngredient();
        delead();
    }

    /**
     * 去铅
     */
    public void delead() {

    }
}

package patterntest.product;

/**
 * 特效美白牙膏
 * 
 * @author tzx
 *
 */
public class MyProduct3 extends MyProduct {

    public MyProduct3() {
        addIngredient();
        addWhitening();
    }

    /**
     * 增加特效美白成分
     */
    public void addWhitening() {

    }
}

有了现实的四个产品,依照下面的见识,各种工厂生产一种产品,也正是各样产品要对应二个实际工厂,所以大家需求有八个照应的厂子,那个工厂均贯彻工厂接口的抽象方法:

package patterntest.factorypattern;

import patterntest.product.MyProduct;
import patterntest.product.MyProduct1;

/**
 * 生产普通牙膏的分厂
 * 
 * @author tzx
 *
 */
public class MyFactory1 implements MyFactory {

    @Override
    public MyProduct getProduct() {
        return new MyProduct1();

    }

}

package patterntest.factorypattern;

import patterntest.product.MyProduct;
import patterntest.product.MyProduct2;

/**
 * 生产儿童牙膏的分厂
 * 
 * @author tzx
 *
 */
public class MyFactory2 implements MyFactory {

    @Override
    public MyProduct getProduct() {
        return new MyProduct2();
    }

}

package patterntest.factorypattern;

import patterntest.product.MyProduct;
import patterntest.product.MyProduct3;

/*
 * 生产特效美白牙膏的分厂
 */
public class MyFactory3 implements MyFactory {

    @Override
    public MyProduct getProduct() {
        return new MyProduct3();
    }

}

那样一来,工厂就可以寻常初步运转了,接下去是主顾找工厂购买商品,只供给基于实际必要创制时间的厂子,然后调用生产措施,就足以赢得想要的产品:

package patterntest.consumer;

import patterntest.factorypattern.MyFactory;
import patterntest.factorypattern.MyFactory1;
import patterntest.factorypattern.MyFactory2;
import patterntest.factorypattern.MyFactory3;

/**
 * 消费者
 * 
 * @author tzx
 *
 */
public class Consumer {

    public static void main(String[] args) {
        MyFactory factory = null;
        // 我需要普通牙膏
        factory = new MyFactory1();
        factory.getProduct();
        System.out.println(factory.getProduct().getClass());
        // 我需要儿童牙膏
        factory = new MyFactory2();
        factory.getProduct();
        System.out.println(factory.getProduct().getClass());
        // 我需要特效美白牙膏
        factory = new MyFactory3();
        factory.getProduct();
        System.out.println(factory.getProduct().getClass());
    }

}

        工厂形式是 Java
中最常用的设计形式之一。这种类型的设计情势属于创制型形式,它提供了一种成立对象的最佳艺术。

要点

好了,二个相比专业的简便工厂形式就出来了,由上边包车型客车解析能够领略不难工厂形式的多少个要点:
1.
索要有1个生产成品的产品类(工厂)和静态的输出产品的艺术,那么些措施包蕴部分必不可少判断逻辑;

  1. 内需有三个抽象的出品父类,定义产品的集体属性和章程;
  2. 急需有具体的产品类;
  3. 假定提供正确的参数,就能由此静态工厂方法赢获得具体的产品。

要点

那么,依据上边包车型客车实例能够综合出工厂方法的要点基本如下:

  1. 急需有3个抽象产品类
  2. 需求有若干个具体的产品类
  3. 急需有三个架空工厂和虚幻工厂方法
  4. 必要各种具体产品对应二个具体的工厂和工厂方法
  5. 空洞工厂中的抽象工厂方法需倘诺非static的
  6. 顾客要求团结遵照实际须求创立实际的厂子

        工厂方式首借使为创造对象提供对接接口,以便将创制对象的切实经过屏蔽隔开起来,达到增长灵活性的指标。

总结

经过上边的一名目繁多分析和实例,可以知道简单工厂形式的一些优点,他能够使顾客不必关心具体产品的创始,只必要3个参数就能获得需求的成品,完毕了肯定水准的松耦合。
再者,分歧的制品分歧的子类,也使得后续更易于举办。
可是出于具备产品都经过工厂创建,分裂出品赢得的逻辑判断都在工厂方法中,因而实际的成品和工厂的耦合度就一定增大,同时在成品类的底子上也优良的增多了工厂类。
从而,假使产品居多的话,那种简单工厂格局便会变得臃肿而科学维护。

demo源码可在github下载:https://github.com/tuzongxun/mypattern

总结

厂子方法方式相对于简单工厂形式,便是减轻了工厂类和工厂方法的行事,把差不离工厂情势中的三个厂子类依据实际产品拆分成分歧的工厂,并提供二个父类接口。
如此做不仅完结了产品和顾客的分开,也促成了切实可行工厂的轻负荷,使用面向对象的多态性在运营期采取具体的厂子。
只是那种格局中,缺点也是醒目标,每1个出品都急需有三个出品工厂,就一定于每扩展多个成品,都至少要增添四个类,大大扩大了类的个数。
其余,依据粗略工厂形式那里的通晓,自身new一个工厂,相当于为了3个牙膏创立1个厂子,那犹如也是不创造的。
可是供给领会的是,未来的情景不雷同了,每一个工厂创设的是一批牙膏而不是一支,所以那边new一个厂子,其实可以精晓成自己索要一批牙膏,于是小编找了个厂子代理生产了一批。

注:书中实际还涉及了对工厂方法方式的优化,那就是在运用的时候使用xml配置文件和反光来获得切实的厂子类,而不是直接new,是不是要如此优化能够依据各种人的实际上要求选用。

demo源码可在github下载:https://github.com/tuzongxun/mypattern

 

工厂形式依照抽象程度的两样分为二种:

粗略工厂情势(也叫静态工厂情势)

厂子方法形式(也叫多形性工厂)

泛泛工厂形式(也叫工具箱)

 

简言之工厂格局

        实质是由三个厂子类依据传入的参数,动态控制应该创设哪多个产品类(那一个产品类继承自二个父类或接口)的实例。简单工厂方式的创制目的,全体创设的目的都以充当那几个剧中人物的有个别具体类的实例。

 

工厂方法情势

        工厂方法是粒度相当小的设计格局,因为形式的显现只是3个空洞的法子。
提前定义用于创造对象的接口,让子类决定实例化具体的某一个类,即在工厂和成品中间扩展接口,工厂不再负责产品的创导,由接口针对不相同尺度重返具体的类实例,由具体类实例去贯彻。

 

空洞工厂情势

        当有多少个抽象剧中人物时使用的一种工厂形式。抽象工厂情势能够向客户端提供一个接口,使客户端在不必钦命产品的求实的情事下,创建多个产品对象。它有几个抽象产品类,每种抽象产品类能够派生出四个有血有肉产品类,三个华而不实工厂类,可以派生出四个实际工厂类,各类具体育工作厂类能够创建多少个有血有肉产品类的实例。

 

工厂方法格局应该在其实可行的较多,大家以工厂方法方式举例

(例子来源百度,支持了然)

 

 抽象的产品类:定义car  交通工具类

 

public interface Car {    
    void gotowork();
}

概念实际的产品类,总共定义多个,bike 和bus 分别代表分化的通畅工具类

 

public class Bike implements Car {
    @Override
    public void gotowork() {
        System.out.println("骑自行车去上班!");
    }
}

 

public class Bus implements Car {
    @Override
    public void gotowork() {
        System.out.println("坐公交车去上班!");
    }
}

 

概念抽象的厂子接口

 

public interface ICarFactory {
    Car getCar();
}

 

实际的厂子子类,分别为各类具体的产品类制造不一致的厂子子类

 

public class BikeFactory implements ICarFactory {
    @Override
    public Car getCar() {
        return new Bike();
    }
}

 

 

public class BusFactory implements ICarFactory {    
@Override
    public Car getCar() {        
        return new Bus();
    }
}

 

简言之的测试类,来证实不相同的厂子能够发生差异的成品对象

 

public class TestFactory {
    @Test
    public void test() {
        ICarFactory factory = null;
        // bike
        factory = new BikeFactory();
        Car bike = factory.getCar();
        bike.gotowork();

        // bus
        factory = new BusFactory();
        Car bus = factory.getCar();
        bus.gotowork();
    }
}

 

工厂方式的独到之处:

        壹 、一个调用者想成立七个指标,只要领会其名称就能够了,下降了耦合度。

        二 、扩大性高,若是想扩充一个出品,只要增添2个厂子类就足以。使得代码结构尤其显著。

        叁 、屏蔽产品的实际实现,调用者只关怀产品的接口。

 

工厂形式的症结:

        每便增添2个成品时,都急需扩展贰个具体类和指标完毕工厂(那里能够运用反射机制来幸免),使得系统中类的个数成倍扩张,在早晚水准上加码了系统的复杂度,同时也大增了系统具体类的信赖性。所以对于简易对象的话,使用工厂形式反而高居不下了复杂度。

 

厂子情势的适用场景:

        1,  四个对象拥有广大子类。

        2,  创立有些对象时需求开始展览过多附加的操作。

        3, 
系统早先时期须求平时扩大,它把目标实例化的任务交由完毕类成就,扩展性好。

 

至于Java中的工厂情势的一部分广阔难点:

        利用父类的向下转型(使用父类类型的引用指向子类的对象)是足以达到规定的标准近似于工厂格局的效益的,那为何还要用工厂格局吧?

        把针对子类对象的父类引用赋给子类引用叫做向下转型,如: 

 

Class Student extends Person     
Person s = new Student();    
s = (Student)person ;

 

        使用向下转型在客户端实例化子类的时候,严重依赖具体的子类的名字。当大家要求改变子类的构造方法的时候,比如扩充3个参数,可能转移了子类的类名,全数的new出来的子类都急需随着变动。    

        但一旦我们采用工厂形式,我们唯有要求在工厂中期维修改一下new的代码,其他项目中用到此实例的都会随之改,而不须要大家手动去操作。(???)

 

总结:

        无论是不难工厂情势、工厂形式大概抽象工厂方式,它们本质上都以将不变的有的提取出来,将可变的有的留作接口,以高达最大程度上的复用。究竟用哪类设计情势更符合,那要依据实际的作业要求来决定。

相关文章