设计模式学习笔记(3)工厂方法

工厂方法模式(Factory Method Pattern)又叫虚拟构造函数模式或是多态性工厂模式,工厂模式的用意是定义一个创建产品对象的工厂接口,将实际创建性工作推迟到子类中。

简单工厂模式:一个工厂类处于对产品类实例化的中心位置上,它知道每一个产品,它决定拿一个产品类应当被实例化。这个模式的有点事允许客户端相对独于产品创建的过程,并且在系统引入新产品的时候无须修改客户端,即在某种程度上支持开-闭原则。这个模式的缺点是对开-闭原则的支持不够,因为如果有心的产品加入到系统中需要修改工厂类,将必要的逻辑加入到工厂类中。

工厂方法模式:是对简单工厂模式的进一步抽象和推广,由于使用了多态性,工厂模式保持了简单工厂模式的优点,且客户了它的缺点。首先,在工厂方法模式中,核心的工厂类不再负责所有产品的创建,而是将具体的创建工作交给子类去做,这个核心类则成为一个抽象工厂角色,仅负责给出具体工厂子类必须实现的接口,而不接触哪个产品类应被实例化的细节。此种进一步抽象画的结果,使这种工厂方法模式可以用来允许在系统不修改具体工厂角色的情况下引进新的产品,这一个特点使得工厂模式具有超过简单工厂的优越性。

抽象工厂模式:是所有形态的工厂模式中最为抽象和具有一般性的一种形态,抽象工厂模式与工厂方法模式的最大区别就在于,工厂方法模式针对的是一个产品等级结构:而抽象工厂模式则需要面对多个产品等级结构。

工厂方法模式的定义

Define an interface for creating an object, but let subclasses decide which chlass to instantitate. Factory Method lets a class defer instantiation to sub class.

定义一组创建对象的接口,让子类决定实例化哪个类,工厂方法使一个类的实例化延迟到其子类。

在工厂方法模式中,至少涉及以下四个角色。

抽象工厂(Creator)角色:该角色是工厂方法模式的核心,与应用系统无关,任何在创建对象的工厂类必须实现这个借口。

具体工厂(Concrete Creator)角色:该角色实现了抽象工厂接口,含有与应用密切相关的逻辑,并且受到应用程序的调用以创建对象产品。

抽象产品(product)角色:该角色负责定义产品的共性,实现对产品最抽象的定义。

具体产品(Concrete Product)角色,该角色实现抽象产品角色所声明的接口,工厂方法模式所创建的每一个对象都是具体产品角色的实例。

抽象工厂Creator.java

public interface Creator{

/**

*创建一个产品对象,其输入参数类型可以自行设置

*/

 public <T extends Product> T factory(Class<T>);

}

Product.java

public interface Product{

public void method1();

public void method2();

}

ConcreteCreator.java

public class concreteCreator implements Creator{

public <T extends Product> T factory(Class<T> c){

Product product=null;

try{

 product=(Product)Class.forName(c.getName()).newInstace();

}catch(Exception e){

}

return (T) product;

}

}

ConcreteProduct.java

public class ConcreteProduct implements Product{

public void method1(){

}

public class method2(){

}

}

public class FactoryMethodDemo{

public static void main(String args[]){

Creator creator=new ConcreteCreator();

Product product=creator.factory(Concreteproduct.class);

}

}

工厂方法模式的应用

1工厂方法模式的优点

良好的封装性。代码结构清晰。一个对象创建是有条件约束的,如果一个调用者需要一个具体的产品对象,只要知道这个产品的类名或是约束字符串即可,不用知道创建对象的过程如何,降低了模块间的耦合。

优秀的可扩展性:在增加产品类的情况下。只要适当地修改具体的工厂类或是扩展一个工厂类,就可以适应变化。

屏蔽产品类。产品类的实现如何变化,调用者都不需要关心,而只需要关心产品的接口,只要接口保持不变,系统的上层模块就不需要发生变化。因为产品的实例化是由工厂类负责的,具体生产何种产品对象是由不同的工厂类决定的。

工厂方法模式是典型的解耦框架。高层模块只需要知道产品的抽象类,其他的实现类都不用关心。工厂方法模式符合迪米特法则,也符合依赖倒置原则,只依赖产品类的抽象,另外还符合里氏替换原则,可以使用产品子类替代产品父类。

工厂方法模式的使用场景

工厂方法模式在项目中使用的非常频繁,在很多框架的代码中都可以发现工厂方法模式的应用,

工厂方法模式是new一个对象的替代品,因此在所有需要生成对象的地方都可以使用,但是需要慎重考虑是否需要增加一个工厂类进行管理,增加代码的复杂度。

需要灵活的、可扩展的框架时,可以考虑采用工厂方法模式。

工厂方法模式可以用在异构项目中,例如,通过WebService与一个非java的项目交互,虽然WebService号称可以做到异构系统的同构化,但是在实际开发项目中,还是会碰到很多问题。例如类型问题,WSDL文件的支持问题。从WSDL中产生的对象都认为是一个产品,然后由一个具体的工厂类进行管理,减少与外围的耦合。

工厂方法模式可以使用在测试驱动开发的框架下。例如吗,测试一个类A,就需要将于类A关联的类B也同时产生出来,使用工厂方法模式可以将类B虚拟出来,便面类A与类B的耦合。

public interface FruitGardener {
public Fruit factory();
}

public interface Fruit {
    //生长
public void grow();
//收获
public void harvest();
//栽种
public void plant();
}

public class AppleGardener implements FruitGardener {


@Override
public Fruit factory() {
// TODO Auto-generated method stub
return new Apple();
}


}

public class GrapeGardener implements FruitGardener {


@Override
public Fruit factory() {
// TODO Auto-generated method stub
return new Grape();
}


}

public class Apple implements Fruit {


private int treeAge;
@Override
public void grow() {
System.out.println("苹果正在生长");
      
}


public int getTreeAge() {
return treeAge;
}


public void setTreeAge(int treeAge) {
this.treeAge = treeAge;
}


@Override
public void harvest() {
// TODO Auto-generated method stub
         System.out.println("收获苹果");
}


@Override
public void plant() {
// TODO Auto-generated method stub
        System.out.println("栽种苹果");
}


}

public class Grape implements Fruit {


private boolean seedless;
public boolean isSeedless() {
return seedless;
}


public void setSeedless(boolean seedless) {
this.seedless = seedless;
}


@Override
public void grow() {
// TODO Auto-generated method stub
     System.out.println("葡萄正在生长");
}


@Override
public void harvest() {
// TODO Auto-generated method stub
   System.out.println("收获葡萄");
}


@Override
public void plant() {
// TODO Auto-generated method stub
   System.out.println("栽种葡萄");
}


}

public class ClientDemo {


/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
      //苹果园丁工厂
FruitGardener fruitGardener=new AppleGardener();
//通过工厂生产苹果
Fruit apple=fruitGardener.factory();
apple.plant();
apple.grow();
apple.harvest();

//葡萄工厂生产葡萄
fruitGardener=new GrapeGardener();
Fruit grape=fruitGardener.factory();
grape.plant();
grape.grow();
grape.harvest();

}


}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值