天天看点

工厂模式及其变种工厂模式及其变种

工厂模式及其变种

工厂模式,即将变量的创建封装到工厂对象中的设计模式,

一般而言,可以将工厂模式分为三种

1.简单工厂模式
2.工厂方法模式
3.抽象工厂模式

1.简单工厂模式

即创建工厂对象,更具传入的参数,创建需要的对象,然后将对象返回,例:

/**
 * 
 * @author ASUS
 * 具体产品类椅子
 */
public class Chair {
	
	public void setDown() {
		System.out.println("坐在椅子上");
	}

}

           
/**
 * 
 * @author ASUS
 * 具体产品类,沙发
 */
public class Sofa {
	public void LayOn() {
		System.out.println("躺在沙发上------------");
	}

}
           

工厂对象:

/**
 * 
 * @author ASUS
 *	简单工厂模式,更具传入的参数,生成具体的对象
 */
public class Factory {
	
	public Object getProduct(String productName) throws ClassNotFoundException {
		if(productName.equals("Chair")) {
			return new Chair();
		}else if(productName.equals("Sofa")) {
			return new Sofa();
		}else {
			throw new ClassNotFoundException("没有该产品!");
		}
	}
	
	public static void main(String[] args) throws ClassNotFoundException {
		Factory factory = new Factory();
		//----------------客户需要椅子,直接向工厂要即可
		Chair chair = (Chair) factory.getProduct("Chair");
		chair.setDown();
		
	}

}
           

在具体产品不多的情况下,简单工厂模式很清晰,实用。

但是在产品很多的情况下,生成实例的方法就需要修改,增加更多的判断,显然这不符合开闭原则(“软件中的对象(类**,模块,函数等等)应该对于扩展是开放的,但是对于修改是封闭的”)

2.工厂方法模式

工厂方法模式将工厂进行了抽象,将具体产品的创建下移到其子类的创建方法中去,这样使每一个子类都能创建对应的不同类型的产品,(增加不同系列的产品)

同时为了符合开闭原则,

产品必须实现某种统一的接口,在抽象工厂的创建方法中必须返回该接口的对象,

而在具体的子类工厂之中则可以返回某种实现了标注的具体产品

例:

/**
 * 
 * @author ASUS
 * 产品标准接口沙发
 */
public interface Sofa {

	void LayOn();
	
}
           
/**
 * 
 * @author ASUS
 * 古典风格的沙发
 */
public class ClassicSofa implements Sofa {

	@Override
	public void LayOn() {
		System.out.println("坐在古典风格的沙发上-------------------------");
		
	}

}
           
/**
 * 具体产品类
 * @author ASUS
 * 现代风格的沙发
 */
public class MordenSofa implements Sofa{

	@Override
	public void LayOn() {
		System.out.println("躺在现代风格的沙发上-----------------");
	}

}
           
/**
 * 
 * @author ASUS
 * 抽象家具工厂
 */
public abstract class FurnitureFactory {
	
	
	/**
	 * 抽象方法,生成沙发
	 * @return 沙发接口的实现类
	 */
	public abstract Sofa  productSofa();
	
	// 请注意,创建者的主要职责并非是创建产品。其中通常会包含一些核心业务
    // 逻辑,这些逻辑依赖于由工厂方法返回的产品对象。子类可通过重写工厂方
    // 法并使其返回不同类型的产品来间接修改业务逻辑。
	public void ReUseSofa(Sofa sofa) {
		System.out.println("重新利用了一个沙发!");
	}
	

}
           
/**
 * 具体工厂子类
 * @author ASUS
 * 现代风格家具工厂
 */
public class MordenFactory extends FurnitureFactory{

	@Override
	public Sofa productSofa() {
		//现代风格的工厂,生成现代风格的沙发
		return new MordenSofa();
	}

	
}
           
/**
 * 具体工厂子类
 * @author ASUS
 * 古典风格家具工厂
 */
public class ClassicFactory extends FurnitureFactory{

	@Override
	public Sofa productSofa() {
		//古典风格工厂,生成古典风格的沙发
		return new ClassicSofa();
	}
	

}
           

main:

public static void main(String[] args) {
		FurnitureFactory factory = new MordenFactory();
    //客户端根据环境选择一种工厂,并不用知道是那种风格的家具
		MordenSofa sofa = (MordenSofa) factory.productSofa();
		sofa.LayOn();
		factory.ReUseSofa(sofa);
	}
           

3.抽象工厂模式

抽象工厂模式和工厂方法模式非常像

在上述的工厂方法模式中,如果需要新增具体产品需要新增一个具体子工厂(当然你也可以直接在抽象工厂中增加生产其他对象的抽象方法,进而修改子类的代码生成新的产品,这样就和抽象工厂模式非常像了,但对抽象工厂类进行了修改,并不符合开闭原则),

抽象工厂模式直接把抽象工厂变成抽象的接口,

这样需要增加新产品就可以直接在工厂接口中扩展方法

​ 需要增加新的系列就可以新增一个工厂接口的实现类

例:

/**
 * 
 * @author ASUS
 * 抽象工厂接口,定义生成产品的方法
 */
public interface AbstractFactory {
	
	/**
	 * 
	 * @return 返回椅子接口实例
	 */
	Chair ProductChair();
	
	/**
	 * 
	 * @return 返回沙发的接口实例
	 */
	Sofa ProductSofa();

}
           
/**
 * 古典风格工厂
 * @author ASUS
 * 生成古典风格家具
 */
public class ClassicFactory implements AbstractFactory{

	@Override
	public Chair ProductChair() {
		//古典工厂生产古典椅子
		return new ClassicChair();
	}

	@Override
	public Sofa ProductSofa() {
		//古典工厂生产古典沙发
		return new ClassicSofa();
	}
}
           
/**
 * 现代风格工厂,生成现代风格产品
 * @author ASUS
 * 实现抽象工厂接口,可以让抽象工厂的产品的增加,增加到生成中
 */
public class ModernFactory implements AbstractFactory{

	@Override
	public Chair ProductChair() {
		//现代风格工厂,生成现代风格椅子
		return new MordenChair();
	}

	@Override
	public Sofa ProductSofa() {
		// 现代风格工厂,生成现代风格沙发
		return new MordenSofa();
	}

}
           
/**
 * 
 * @author ASUS
 *椅子接口,具体的椅子产品要实现该接口
 */
public interface Chair {
	
	void setdown();

}
/**
 * 
 * @author ASUS
 * 沙发产品接口
 */
public interface Sofa {
	
	void layOn();

}
           
/**
 * 
 * @author ASUS
 * 具体参评类,实现椅子接口
 */
public class ClassicChair implements Chair{

	@Override
	public void setdown() {
		
		System.out.println("在古典风格的椅子上坐下-----");
	}

}
/**
 * 具体产品类,古典风格沙发
 * @author ASUS
 * 实现沙发接口
 */
public class ClassicSofa implements Sofa{

	@Override
	public void layOn() {
		System.out.println("在古典风格沙发上躺下----------------");
		
	}

}
/**
 * 具体产品类,现代风格椅子
 * @author ASUS
 * 实现椅子接口
 */
public class MordenChair implements Chair{

	@Override
	public void setdown() {
		System.out.println("在现代风格的椅子上坐下--------------------");
	}

	
}
/**
 * 具体产品类,现代风格沙发
 * @author ASUS
 * 实现沙发接口
 */
public class MordenSofa implements Sofa {

	@Override
	public void layOn() {
		System.out.println("在现代风格的沙发上躺下----------");
	}

}
           
public class AppMain {
	public static void main(String[] args) {
		AbstractFactory factory = new ClassicFactory();
		
		System.out.println("根据使用场景选择不同的实现工厂,这里以古典风格家具工厂为例");
		
		//顾客在古典风格工厂中说,我要一把椅子,那么就由古典风格工厂生成一把椅子
		
		Chair chair = factory.ProductChair();
		
		System.out.println("顾客坐上了椅子");
		
		chair.setdown();
	}

}

           
根据使用场景选择不同的实现工厂,这里以古典风格家具工厂为例
顾客坐上了椅子
在古典风格的椅子上坐下-----