工厂模式及其变种
工厂模式,即将变量的创建封装到工厂对象中的设计模式,
一般而言,可以将工厂模式分为三种
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();
}
}
根据使用场景选择不同的实现工厂,这里以古典风格家具工厂为例
顾客坐上了椅子
在古典风格的椅子上坐下-----