简单工厂方法模式
简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例
简单工厂模式组成
- 工厂类角色:这是本模式的核心,含有一定的商业逻辑和判断逻辑。在java中它往往由一个具体类实现;
- 抽象产品角色:它一般是具体产品继承的父类或者实现的接口。在java中由接口或者抽象类来实现; 具体产品角色:工厂类所创建的对象就是此角色的实例。在java中由一个具体类实现。
package designmodel; public interface Fruit { //种植 public void plant(); //生长 public void grow(); //收获 public void harvest(); }
package designmodel; public class Apple implements Fruit { @Override public void plant() { // TODO Auto-generated method stub System.out.println("栽种苹果..."); } @Override public void grow() { // TODO Auto-generated method stub System.out.println("苹果生长中..."); } @Override public void harvest() { // TODO Auto-generated method stub System.out.println("收获苹果..."); } }
package designmodel; public class Pear implements Fruit { @Override public void plant() { // TODO Auto-generated method stub System.out.println("栽种梨..."); } @Override public void grow() { // TODO Auto-generated method stub System.out.println("梨生长中..."); } @Override public void harvest() { // TODO Auto-generated method stub System.out.println("收获梨..."); } }
package designmodel; /** * 简单工厂,工厂类 * @author 21409262 * */ public class ConcreteCreator { // public <T extends Fruit> Fruit creatFactory(Class<T> c) { Fruit fruit = null; try{ fruit = (Fruit) Class.forName(c.getName()).newInstance(); }catch(Exception e){ e.printStackTrace(); } return fruit; } }
package designmodel; public class TestCreator { public static void main(String args[]){ ConcreteCreator creator = new ConcreteCreator(); //从工厂类获取苹果产品 Fruit apple = creator.creatFactory(Apple.class); apple.plant(); apple.grow(); apple.harvest(); //从工厂类获取梨产品 Fruit pear = creator.creatFactory(Pear.class); pear.plant(); pear.grow(); pear.harvest(); } }
工厂方法模式
是定义一个创建产品对象的工厂接口,让子类决定实例化哪一个类,将实际创建工作推迟到子类当中。
工厂方法模式的优点
- 良好的封装性,代码结构清晰。一个对象创建是有条件约束的,如果一个调用者需要一个具体的产品对象,只要知道这个产品的类名或约束字符串即可,不用知道创建对象的过程如何,降低模块间的耦合;
- 优秀的扩展性。在增加产品类的情况下,只要适当地修改具体的工厂类或扩展一个类,就可以适应变化;
- 屏蔽产品类。产品类的实现如何变化,调用者不需要关心,只需要关心产品的接口,只要接口保持不变,系统的上层模块就不需要发生变化。因为产品的实例化是由工厂类负责的,具体生产何种产品对象是由不同的工厂类决定的。
- 工厂方法模式是典型的解耦框架。高层模块只需要知道产品的抽象类,其他的实现类都不用关心。工厂方法模式符合迪米特法则,也符合依赖倒置原则,只依赖产品的抽象类。另外还符合里氏替换原则,可以使用产品子类替换产品父类。
<span style="font-size:18px;">package designmodel; /** * 获得水果产品的接口 * */ public interface Creator { //提高获得水果产品的方法 public Fruit factory(); }</span>
<span style="font-size:18px;">package designmodel; /** * 实现水果产品生产接口Creator,是一个用于生产苹果的具体工厂 * */ public class AppleCreator implements Creator { <span style="white-space:pre"> </span>@Override <span style="white-space:pre"> </span>public Fruit factory() { <span style="white-space:pre"> </span>// TODO Auto-generated method stub <span style="white-space:pre"> </span>return new Apple(); <span style="white-space:pre"> </span>} }</span>
<span style="font-size:18px;">package designmodel; /** * 实现水果产品生产接口Creator,是一个用于生产梨的具体工厂 * */ public class PearCreator implements Creator { <span style="white-space:pre"> </span>@Override <span style="white-space:pre"> </span>public Fruit factory() { <span style="white-space:pre"> </span>// TODO Auto-generated method stub <span style="white-space:pre"> </span>return new Pear(); <span style="white-space:pre"> </span>} } </span>
<pre name="code" class="html"><span style="font-size:18px;">package designmodel; public class TestCreator { public static void main(String args[]){ //苹果工厂 Creator appleCreator = new AppleCreator(); Fruit _apple = appleCreator.factory(); _apple.plant(); _apple.grow(); _apple.harvest(); //梨工厂 Creator pearCreator = new AppleCreator(); Fruit _pear = pearCreator.factory(); _pear.plant(); _pear.grow(); _pear.harvest(); } } </span>
抽象工厂模式
为创建一组相关或互相依赖的对象提供一个接口,而且无需指定它们的具体类。抽象工厂模式是工厂方法模式的升级版本。在有多个业务品种、业务分类时,通过抽象工厂模式产生需要的对象是一种非常好的解决方式。
<pre name="code" class="html">package designmodel;
public interface ProductA {
//产品A方法
public void create();
}
package designmodel;
public interface ProductB {
//产品B方法
public void create();
}
package designmodel;
public class ConcreteProductA1 implements ProductA {
@Override
public void create() {
// TODO Auto-generated method stub
System.out.println("产品A1创建");
}
}
package designmodel;
public class ConcreteProductA2 implements ProductA {
@Override
public void create() {
// TODO Auto-generated method stub
System.out.println("产品A2创建");
}
}
package designmodel;
public class ConcreteProductB1 implements ProductB {
@Override
public void create() {
// TODO Auto-generated method stub
System.out.println("产品B1创建");
}
}
package designmodel;
public class ConcreteProductB2 implements ProductB {
@Override
public void create() {
// TODO Auto-generated method stub
System.out.println("产品B2创建");
}
}
package designmodel;
public interface AbstractFactory {
//创建产品A
public ProductA factoryA();
//创建产品B
public ProductB factoryB();
}
package designmodel;
public class ConcreteFactory1 implements AbstractFactory {
//创建等级为1的产品A
public ProductA factoryA() {
// TODO Auto-generated method stub
return new ConcreteProductA1();
}
//创建等级为1的产品B
public ProductB factoryB() {
// TODO Auto-generated method stub
return new ConcreteProductB1();
}
}
package designmodel;
public class ConcreteFactory2 implements AbstractFactory {
//创建等级为2的产品A
public ProductA factoryA() {
// TODO Auto-generated method stub
return new ConcreteProductA2();
}
//创建等级为2的产品B
public ProductB factoryB() {
// TODO Auto-generated method stub
return new ConcreteProductB2();
}
}
package designmodel;
public class TestCreator {
public static void main(String args[]){
//定义两个工厂
AbstractFactory factory1 = new ConcreteFactory1();
AbstractFactory factory2 = new ConcreteFactory2();
//生产等级为1的产品A1
ProductA a1 = factory1.factoryA();
//生产等级为2的产品A2
ProductA a2 = factory2.factoryA();
//生产等级为1的产品B1
ProductB b1 = factory1.factoryB();
//生产等级为2的产品B2
ProductB b2 = factory2.factoryB();
a1.create();
a2.create();
b1.create();
b2.create();
}
}
抽象工厂模式组成
- 抽象工厂角色,该角色是抽象工厂模式的核心,与应用系统无关,任何创建对象的工厂类必须实现这个接口;
- 具体工厂角色,该角色实现了抽象工厂接口,还有选择合适的产品对象的逻辑,并且受到应用程序的调用以创建产品对象;
- 抽象产品角色,该角色负责定义抽象产品的共性,实现对产品最抽象的定义;
- 具体产品角色,该角色实现抽象产品角色所声明的接口,抽象工厂模式所创建的任何产品对象都是某个具体产品角色的实例。
抽象工厂的优点
- 抽象工厂是工厂方法模式的进一步抽象,针对的是一族产品。如果产品族中只有一个产品,则抽象工厂模式就退化为工厂方法模式;
- 产品族内的约束为非公开状态,在不同的工厂中,各种产品可能具有不同的相互依赖关系,这些依赖关系由工厂封装在内部,对于工厂的使用者不可见;
- 生成线扩展非常容易,如果要针对一产品族建立新的生成线,只需要实现产品族中所有的接口并建立新的工厂类即可。
抽象工厂的缺点
抽象工厂模式的最大缺点就是产品族本身的扩展非常困难,如果需要在产品族中增加新的产品类型,则需要修改多个接口,并且会影响已有的工厂类。