一、工厂模式
工厂方法模式(别名:虚拟构造):定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使一个类的实例化延迟到其子类。
工厂方法模式的关键是在一个接口或抽象类中定义一个抽象方法,该方法返回某个类的子类的实例,该抽象类或接口让其子类或实现该接口的类通过重写这个抽象方法返回某个子类的实例。
模式的结构中包括四种角色:
抽象产品(Product)
具体产品(ConcreteProduct)
构造者(Creator)
具体构造者(ConcreteCreator)
1、抽象产品(Product) : PenCore.java
public
abstract class PenCore{
String color;
public abstract void writeWord(String s);
}
2、具体产品(ConcreteProduct)_1 : RedPenCore.java
public class RedPenCore extends PenCore{
RedPenCore(){
color="红色";
}
public void writeWord(String s){
System.out.println("写出"+color+"的字:"+s);
}
}
2、具体产品(ConcreteProduct)_2 : BluePenCore.java
public class BluePenCore extends PenCore{
BluePenCore(){
color="蓝色";
}
public void writeWord(String s){
System.out.println("写出"+color+"的字:"+s);
}
}
2、具体产品(ConcreteProduct)_3: BlackPenCore.java
public class BlackPenCore extends PenCore{
BlackPenCore(){
color="黑色";
}
public void writeWord(String s){
System.out.println("写出"+color+"的字:"+s);
}
}
3、构造者(Creator):BallPen.java
public abstract class BallPen{
BallPen(){
System.out.println("生产了一只装有"+getPenCore().color+"笔芯的圆珠笔");
}
public abstract PenCore getPenCore(); //工厂方法
}
4、具体构造者(ConcreteCreator)
RedBallPen.java
public class RedBallPen extends BallPen{
public PenCore getPenCore(){
return new RedPenCore();
}
}
BlueBallPen.java
public class BlueBallPen extends BallPen{
public PenCore getPenCore(){
return new BluePenCore();
}
}
BlackBallPen.java
public class BlackBallPen extends BallPen{
public PenCore getPenCore(){
return new BlackPenCore();
}
}
5、应用 Application.java
public class Application{
public static void main(String args[]){
PenCore penCore;
BallPen ballPen=new BlueBallPen();
penCore=ballPen.getPenCore();
penCore.writeWord("你好,很高兴认识你");
ballPen=new RedBallPen();
penCore=ballPen.getPenCore();
penCore.writeWord("How are you");
ballPen=new BlackBallPen();
penCore=ballPen.getPenCore();
penCore.writeWord("nice to meet you");
}
}
6、工厂方法模式的优点
使用工厂方法可以让用户的代码和某个特定类的子类的代码解耦。
工厂方法使用户不必知道它所使用的对象是怎样被创建的,只需知道该对象有哪些方法即可。
7、一个实例
创建药品对象:系统设计了一个抽象类Drug,该抽象类特别规定了所创建的药品必须给出药品的成分及其含量。Drug目前有两个子类:Paracetamol和Amorolfine。 Paracetamol子类负责创建氨加黄敏一类的药品, Amorolfine子类负责创建盐酸阿莫罗分一类的药品。
一个为某药店开发的应用程序需要使用Drug类的某个子类的实例为用户提供药品。但是药店的应用程序不能使用Drug的子类的构造方法直接创建对象,因为药店没有能力给出药品的各个成分的含量,只有药厂才有这样的能力。
二、抽象工厂模式
抽象工厂模式(别名:配套):提供一个创建一系列(相互依赖)对象的接口,而无需指定它们具体的类。
抽象工厂模式的关键是在一个抽象类或接口中定义若干个抽象方法,这些抽象方法分别返回某个类的实例,该抽象类或接口让其子类或实现该接口的类重写这些抽象方法,为用户提供一系列相关的对象。
模式的结构中包括四种角色:
抽象产品(Prodcut)
具体产品(ConcreteProduct)
抽象工厂(AbstractFactory)
具体工厂(ConcreteFactory)
1、抽象产品(Product)
UpperClothes.java
public abstract class UpperClothes{
public abstract int getChestSize();
public abstract int getHeight();
public abstract String getName();
}
Trousers.java
public abstract class Trousers{
public abstract int getWaistSize();
public abstract int getHeight();
public abstract String getName();
}
2、具体产品(ConcreteProduct)_1: WesternUpperClothes.java
public class WesternUpperClothes extends UpperClothes{
private int chestSize;
private int height;
private String name;
WesternUpperClothes(String name,int chestSize,int height){
this.name=name;
this.chestSize=chestSize;
this.height=height;
}
public int getChestSize(){
return chestSize;
}
public int getHeight(){
return height;
}
public String getName(){
return name;
}
}
2、具体产品(ConcreteProduct)_2: CowboyUpperClothes.java
public class CowboyUpperClothes extends UpperClothes{
private int chestSize;
private int height;
private String name;
CowboyUpperClothes(String name,int chestSize,int height){
this.name=name;
this.chestSize=chestSize;
this.height=height;
}
public int getChestSize(){
return chestSize;
}
public int getHeight(){
return height;
}
public String getName(){
return name;
}
}
2、具体产品(ConcreteProduct)_3: WesternTrousers.java
public class WesternTrousers extends Trousers{
private int waistSize;
private int height;
private String name;
WesternTrousers(String name,int waistSize,int height){
this.name=name;
this.waistSize=waistSize;
this.height=height;
}
public int getWaistSize(){
return waistSize;
}
public int getHeight(){
return height;
}
public String getName(){
return name;
}
}
2、具体产品(ConcreteProduct)_4: CowboyTrousers.java
public class CowboyTrousers extends Trousers{
private int waistSize;
private int height;
private String name;
CowboyTrousers(String name,int waistSize,int height){
this.name=name;
this.waistSize=waistSize;
this.height=height;
}
public int getWaistSize(){
return waistSize;
}
public int getHeight(){
return height;
}
public String getName(){
return name;
}
}
3、抽象工厂(AbstractFactory):ClothesFactory.java
public abstract class ClothesFactory{
public abstract UpperClothes createUpperClothes(int chestSize,int height);
public abstract Trousers createTrousers(int waistSize,int height);
}
4、具体工厂(ConcreteFactory)
BeijingClothesFactory.java
public class BeijingClothesFactory extends ClothesFactory {
public UpperClothes createUpperClothes(int chestSize,int height){
return new WesternUpperClothes("北京牌西服上衣",chestSize,height);
}
public Trousers createTrousers(int waistSize,int height){
return new WesternTrousers("北京牌西服裤子",waistSize,height);
}
}
ShanghaiClothesFactory.java
public class ShanghaiClothesFactory extends ClothesFactory {
public UpperClothes createUpperClothes(int chestSize,int height){
return new WesternUpperClothes("上海牌牛仔上衣",chestSize,height);
}
public Trousers createTrousers(int waistSize,int height){
return new WesternTrousers("上海牌牛仔裤",waistSize,height);
}
}
5、应用_1: Shop.java
public class Shop{
UpperClothes cloth;
Trousers trouser;
public void giveSuit(ClothesFactory factory,int chestSize,int waistSize,int height){
cloth=factory.createUpperClothes(chestSize,height);
trouser=factory.createTrousers(waistSize,height);
showMess();
}
private void showMess(){
System.out.println("<套装信息>");
System.out.println(cloth.getName()+":");
System.out.print("胸围:"+cloth.getChestSize());
System.out.println("身高:"+cloth.getHeight());
System.out.println(trouser.getName()+":");
System.out.print("腰围:"+trouser.getWaistSize());
System.out.println("身高:"+trouser.getHeight());
}
}
5、应用_2: Application.java
public class Application{
public static void main(String args[]){
Shop shop=new Shop();
ClothesFactory factory=new BeijingClothesFactory();
shop.giveSuit(factory,110,82,170);
factory=new ShanghaiClothesFactory();
shop.giveSuit(factory,120,88,180);
}
}
6、抽象工厂模式的优点
抽象工厂模式可以为用户创建一系列相关的对象,使得用户和创建这些对象的类脱耦。
使用抽象工厂模式可以方便的为用户配置一系列对象。用户使用不同的具体工厂就能得到一组相关的对象,同时也能避免用户混用不同系列中的对象。
在抽象工厂模式中,可以随时增加“具体工厂”为用户提供一组相关的对象。
7、一个实例
军队要为士兵提供机关枪、手枪以及相应的子弹,但军队系统不希望由士兵(用户)来生产机关枪、手枪及相应的子弹,而是应当有专门的的工厂负责配套生产,即有一个专门负责生产机关枪、机关枪子弹的工厂和一个专门负责生产手枪、手枪子弹的工厂。