抽象工厂 设计模式

抽象⼯⼚模式,所要解决是⼀个产品族问题。这种场景在业务开发中也是⾮常多⻅的,只不过可能有时候没有将它们抽象出来。

可能代码被 if else埋上了,当我们知道在什么场景下可以用抽象工厂优化的时候,那么代码的层级结构可以被很好的完善,应对业务需求变化也提供良好的扩展性和优雅度。

抽象工厂模式:提供一个创建一系列相关或者相互依赖的接口,而无需指定它们具体的类。

(1)AbstractFactory(抽象工厂):它声明了一组用于创建一族产品的方法,每一个方法对应一种产品。

(2)ConcreateFactory(具体工厂):它实现了在抽象工厂中声明的创建产品的方法,生成一组具体产品,这些产品构成了一个产品族,每一个产品都位于某个产品等级结构中。

(3)AbstractProduct(抽象产品):它为每种产品声明接口,在抽象产品中声明了产品所具有的的业务方法。

(4)ConcreteProduct(具体产品):它定义了具体工厂生产的具体产品对象,实现了抽象产品接口中声明的业务方法。

 具体应用举例:

抽象工厂:

/**
 * 字体颜色工厂接口,充当 抽象工厂
 */
public interface ColourFactory {

    /**
     * 创建数字产品
     * @return
     */
    Digit createDigit();

    /**
     * 创建字母产品
     * @return
     */
    Letter createLetter();

    /**
     * 创建标记产品
     * @return
     */
    Mark createMark();

    /**
     * 通过子类class获取当前类的子类
     * @param clazz
     * @param <T>
     * @return
     * @throws Exception
     */
    static <T extends ColourFactory> T getSubClass(Class<T> clazz) throws Exception {
        ColourFactory product = (ColourFactory) Class.forName(clazz.getName()).newInstance();
        return (T) product;
    }
}

具体工厂:

/**
 * 黑色工厂,充当具体工厂
 */
public class BlackColourFactory implements ColourFactory {

    @Override
    public Digit createDigit(){
        return new BlackDigit();
    }

    @Override
    public Letter createLetter(){
        return new BlackLetter();
    }

    @Override
    public Mark createMark(){
        return new BlackMark();
    }

}

/**
 * 黑色工厂,充当具体工厂
 */
public class RedColourFactory implements ColourFactory {

    @Override
    public Digit createDigit(){
        return new RedDigit();
    }

    @Override
    public Letter createLetter(){
        return new RedLetter();
    }

    @Override
    public Mark createMark(){
        return new RedMark();
    }
    
}

抽象产品:

/**
 * 数字接口,充当抽象产品
 */
public interface Digit {
    void display();
}

/**
 * 字母抽象产品
 */
public interface Letter {
    void display();
}

/**
 * 符号接口,充当抽象产品
 */
public interface Mark {
    void display();
}

具体产品:

/**
 * 黑色数字类,充当具体产品
 */
public class BlackDigit implements Digit {

    @Override
    public void display(){
        System.out.println("显示黑色数字");
    }
}

/**
 * 黑色字母,充当具体产品
 */
public class BlackLetter implements Letter {
    @Override
    public void display(){
        System.out.println("显示黑色字母");
    }
}

/**
 * 黑色符号类,充当具体产品
 */
public class BlackMark implements Mark {
    @Override
    public void display(){
        System.out.println("显示黑色符号");
    }
}

/**
 * 红色数字,充当具体产品
 */
public class RedDigit implements Digit {
    @Override
    public void display(){
        System.out.println("显示红色数字");
    }
}

/**
 * 红色字母,充当具体产品
 */
public class RedLetter implements Letter {
    @Override
    public void display(){
        System.out.println("显示红色字母");
    }
}

/**
 * 红色符号类,充当具体产品
 */
public class RedMark implements Mark {
    @Override
    public void display(){
        System.out.println("显示红色符号");
    }
}

调用测试:

@Slf4j
public class AbstractFactoryTest {


    @SneakyThrows
    public static void main(String args[]){
        /* 使用抽象层定义 */
        //抽象工厂
        ColourFactory factory;
        //抽象数字产品
        Digit dt;
        //抽象字母产品
        Letter lt;
        //抽象符号产品
        Mark mk;

        /* 指定具体工厂,生成具体产品 */
        //指定具体工厂:黑色工厂
        factory = ColourFactory.getSubClass(BlackColourFactory.class);
        //用指定工厂生产具体产品
        dt = factory.createDigit();
        lt = factory.createLetter();
        mk = factory.createMark();

        /* 使用具体产品*/
        dt.display();
        lt.display();
        mk.display();

        /*假如说,以后再想增加其他颜色产品,比如说绿色,只需要增加一个GreenColourFactory和三个产品类:GreenDit, GreenLetter, GreenMark
          不会影响现有其他产品类和工厂,使用时直接在这里进行如下调用即可
        factory = ColourFactory.getSubClass(GreenColourFactory.class);
        dt = factory.createDigit();
        lt = factory.createLetter();
        mk = factory.createMark();
        dt.display();
        lt.display();
        mk.display();*/
    }
}

运行结果显示:

程序中封装一下,其他地方直接调用  dealBusiness () 方法即可:

 

/**
 * 抽象工厂 处理客户端
 * @author wg
 */
@Component
@Data @Slf4j
public class XxxAbstractFactoryClient { /** * 抽象工厂 */ ColourFactory factory; /** * 抽象数字产品 */ Digit digit; /** * 抽象字母产品 */ Letter letter; /** * 抽象符号产品 */ Mark mark; @PostConstruct public void init() { try { /* 指定产品具体工厂,进而初始化产品 */ initFactory (BlackColourFactory.class); } catch (Exception e) { log.error(e.getMessage(), e); } } public void dealBusiness () { /* 使用具体产品*/ digit.display(); letter.display(); mark.display(); } private void initFactory (Class clazz) throws Exception { // 指定具体工厂 factory = ColourFactory.getSubClass(clazz); digit = factory.createDigit(); letter = factory.createLetter(); mark = factory.createMark(); } }

 

 

 

 

 

 
 
 
posted on 2023-02-09 19:38  蔻德盈  阅读(35)  评论(0)    收藏  举报