创建型设计模式一共6种,Simple Factory(简单工厂模式),Factory Method(工厂方法模式),Abstract Factory(抽象工厂模式),Singletion(单例模式),Builder(建造模式),Prototy(原型模式)。
一、Simple Factory(简单工厂模式)
思想:根据输入的参数,由工厂类的对象生成需要的类的对象。
例子:有三种水果:苹果(Apple)、草莓(Strawberry)、葡萄(Grape);但它们都有相同的特征,它们都是水果(Fruit),我们的工厂类为水果管理员(FruitGardener).
代码:
//水果类
public interface Fruit{
void grow(); //生长
void harvest(); //收货
void plant(); //种植
}
//苹果类
public class Apple implements Fruit{
public void grow(){
System.out.println("Apple is growing ...");
}
public void harvest(){
System.out.println("Apple has been harvested.");
}
public void plant(){
System.out.println("Apple has been planted.");
}
private int treeAge; //苹果树的年龄
public int getTreeAge(){
return treeAge;
}
public void setTreeAge(int treeAge){
this.treeAge = treeAge;
}
}
//葡萄类
public class Grape implements Fruit{
public void grow(){
System.out.println("Grape is growing ...");
}
public void harvest(){
System.out.println("Grape has been harvested.");
}
public void plant(){
System.out.println("Grape has been planted.");
}
private boolean seedless; //无籽葡萄和有籽葡萄
public void setSeedless(boolean seedless){
this.seedless=seedless;
}
public boolean getSeedless(){
return seedless;
}
}
//草莓类
public class Strawberry implements Fruit{
public void grow(){
System.out.println("Strawberry is growing ...");
}
public void harvest(){
System.out.println("Strawberry has been harvested.");
}
public void plant(){
System.out.println("Strawberry has been planted.");
}
}
//水果管理员类
public class FruitGardener{
//静态方法factory,用来生成不同类的对象,因为不同的水果都实现了Fruit接口,所以静态方法直接用Fruit作为返回。
public static Fruit factory(String which) throws BadFruitException{
if(which.equalsIgnoreCase("apple")){
return new Apple();
}
else if(which.equalsIgnoreCase("grape")){
return new Grape();
}
else if(which.equalsIgnoreCase("strawberry")){
return new Strawberry();
}
else{
throw new BadFruitException("Bad fruit request");
}
}
public class BadFruitException extends Exception{
public BadFruitException(String msg){
super(msg);
}
优点: 简单工厂模式,一定程度上对类的创建进行了封装,可以在不知道创建细节的情况下,直接输入相应类的参数,即可得到相应的类的对象。
缺点: 额外增加了类的个数,并且当需要增加新的类时,必须要对工厂类进行改动,当类较多时,修改工厂类将会变得很复杂。
二、Factory Method(工厂方法模式)
思想: 对于简单工厂模式,当要新增加产品时,必须要修改工厂类(FruitGardener),当在实际编程中,会比较麻烦,所以引入工厂方法模式,当新增加产品时,只需要增加新的代码即可。
* 例子:* 还以上面苹果,草莓,葡萄为例,我们只是改动工厂类,使一个工厂类产生一种产品,这样在即使要增加“香蕉”这种产品,不至于去修改原来的工厂类。
* 代码:*
//苹果,葡萄,草莓的类不变,我们这里只修改工厂类
public interface FruitGardener //工厂类接口
{
public Fruit factory();
}
//AppleGardener类
public class AppleGardener implements FruitGardener
{
public Fruit factory()
{
return new Apple();
}
//GrapeGardener类
public class GrapeGardener implements FruitGardener
{
public Fruit factory()
{
return new Grape();
}
}
//StrawberryGardener类
public class StrawberryGardener implements FruitGardener
{
public Fruit factory()
{
return new Strawberry();
}
}
//简单工厂模式,一个工厂对象可以生产所有的产品,当要增加新的产品时,必须要改动工厂类的代码。
//工厂方法模式,将简单工厂模式的工厂类拆分,一个工厂类只生产一种产品,当要增加产品种类时,只需再增加相应的工厂类即可。
优点: 当产品种类产生变化时,符合“开-闭”原则,不需要修改原来的工厂类。可以很好的应对需求变化,有良好的封装性,代码清晰。
缺点: 简单工厂模式的工厂类只有一层, 而工厂方法模式,将工厂类拆分为两层,一层为借口,一层为具体工厂类,增加了类的层次。
三、Abstract Factory(抽象工厂模式)
思想: 某系统的产品有多于一个的产品族,而系统只消费起哄某一族的产品。
举个例子来理解产品族和产品等级结构。例如,有非洲和美洲两大洲,每个洲都有食肉动物和食草动物,则,非洲的食草动物和食肉动物是一个产品族,美洲的食草动物和食肉动物是一个产品族,所有的美洲和非洲的食草动物是一个产品等级结构,所有美洲和非洲的食肉动物是一个产品等级结构。
例子: 就以非洲和美洲的食肉动物和食草动物为例。
代码:
//食草动物接口
public interface Herbivore
{
}
//食肉动物接口
public interface Carnivore
{
public void chase(Herbivore);
}
//抽象工厂类
public interface AbstarctFactory
{
public Herbivore CreateHerbivore(); //生成食草动物
public Carnivore CreateCarnivore(); //生成食肉动物
}
//美洲虎
public class AmericanTiger implements Carnivore
{
public void chase(Herbivore)
{
System.out.println("AmericanTiger");
}
}
//美洲羊
public class AmericanSheep implements Herbivore
{
}
//非洲虎
public class AfricanTiger implements Carnivore
{
public void chase(Herbivore)
{
System.out.println("AfricanTiger");
}
}
//非洲羊
public class AfricanSheep implements Herbivore
{
}
//美洲工厂类(只生产美洲虎和美洲羊)
public class AmericanFactory implements AbstarctFactory
{
public Herbivore CreateHerbivore() //生成食草动物
{
return new AmericanSheep();
}
public Carnivore CreateCarnivore() //生成食肉动物
{
return new AmericanTiger();
}
}
//非洲工厂类(只生产非洲虎和非洲羊)
public class AfricanFactory implements AbstarctFactory
{
public Herbivore CreateHerbivore() //生成食草动物
{
return new AfricanSheep();
}
public Carnivore CreateCarnivore() //生成食肉动物
{
return new AfricanTiger();
}
}
优点: 当更换场景时,我们只需要更换工厂类即可,就可以生产所有产品,易于更换产品系列。而且比较有利于产品的一致性。
缺点: 例子中只有虎和羊,但当增加了狮子时,所有的工厂类和接口都需要产生更改。所以当产品等级结构发生变化时,比较麻烦。