[设计模式]4. Abstract Factory

Abstract Factory说明

image

图: UML类图和时序图【wiki

在上述UML类图中,Client需要的类ProductA和ProductB对象不直接实例化ProductA1和ProductB1类。而是Client指AbstractFactory用于创建对象的接口,这使得Client独立于如何创建对象(哪些具体类被实例化)。本Factory1类实现了AbstractFactory通过实例的接口ProductA1和ProductB1类。

UML时序图显示了运行时的相互作用:在Client对象调用createProductA()的上Factory1对象,该对象创建并返回一个ProductA1对象。此后,Client电话createProductB()上Factory1,它创建并返回一个ProductB1对象。

Observer

image

图1: 垂直面互换

Observer 模式创造了垂直面的互换性,也就
是框架与应用类别的分合自如 ( 或称为 PnP) ,其依赖于 Observer 模式里的抽象
类别 ( 即接口 ) ,而达到「不知而亦能用」之效果。

Abstract Factory

而Abstract Factory是创造水平方向的互换性:
就是 Client 类别与 Server 类别之间的独立性。例如下图2 里,如果我们抽换掉 Server 应用类别时, Client 类别并不受影响,因为 Client 类别呼叫 Factory 抽象类别的函数去诞生Server 之对象。诞生完毕后, Client 类别呼叫 Server 抽象类别的函数去反向呼叫到 Server 应用类别之函数,就完成了 Client 与 Server 两个类别间之沟通了。由于我们抽换掉 Server 应用类别时,不会影响到 Client 类别,所以 Server 应用类别具有高度的抽换性

image

图2: 水平方向互换

抽象工厂模式基础(Factory method + Template method):

image

图3:Template Method与 Factory Metrhod 模式的组合

降低 Cleint 与 Server 之相依性

在上图里, ConcreteClient 类别的 FactoryMethod() 函数内:
obj = new ConcreteProduct();
它使用了 “ConcreteProduct” 字眼,这造成 ConcreteClient 与 ConcreteProduct
两个类别之间的高度相依性 (Dependency) 。此时,可以增添一个 ConcreteFactory
类别,将 ConcreteClient 与 ConcreteProduct 两类别分隔开来。如下图所示:

image

图4:AP端增加 ConcreteFactory

需要明确一个设计原则:针对接口(what)写程序,而不是实际内涵(how to).
从上图看出Client与 ConcreteFactory是有关联的,而后我们需要将Framework与AP的【变】与【不变】分离。

【变】与【不变】分离

image

图5:AF端增加Factory达到分离原则

package cn.pw.java.dp.absfactory;

public class AbsFactoryMain {

    public static void main(String[] args) {
        Client c = new ConcreteClient();
        c.AnOperation();
    }

}
//***** Framework *****
// Product
abstract class Product {
    public void template_method() {
        hook_method();
    }

    protected abstract void hook_method();
}

//Factory
abstract class Factory {
    public abstract Product createProduct();
}

// Client
abstract class Client {
    protected Factory fa;
    private Product obj;

    public void AnOperation() { 
        FactoryMethod();
        obj = fa.createProduct();
        obj.template_method();
    }
    //factory method为Factory赋值
    public abstract void FactoryMethod();
}

//也可以返回Factory写法
abstract class Client2 {
    protected Factory fa;
    private Product obj;

    public void AnOperation() {
        fa = FactoryMethod();
        obj = fa.createProduct();
        obj.template_method();
    }

    public abstract Factory FactoryMethod();
}

//***** APP *****
class ConcreteProduct extends Product {
    protected void hook_method() {
        System.out.println("ConcreteProduct...");
    }
}

class ConcreteFactory extends Factory {
    public ConcreteProduct createProduct() {
        return new ConcreteProduct();
    }
}

class ConcreteClient extends Client {
    public void FactoryMethod() {
        fa = new ConcreteFactory();
    }
}

Android中类似代码

image

Logger.java 【文件
package com.android.camera.debug;

import com.android.camera.debug.Log.Tag;

import javax.annotation.ParametersAreNonnullByDefault;

/**
 * Like {@link android.util.Log}.
 */
@ParametersAreNonnullByDefault
public interface Logger {
    /**
     * See {@link Log#d}.
     */
    public void d(String msg);

    //.....

    /**
     * See {@link Log#w}.
     */
    public void w(String msg, Throwable tr);

    /**
     * Provides a Logger instance from a given Log tag.
     */
    public interface Factory {
        public Logger create(Tag tag);
    }
}
Loggers.java
package com.android.camera.debug;

import com.android.camera.debug.Log.Tag;
import com.google.common.annotations.VisibleForTesting;

import javax.annotation.ParametersAreNonnullByDefault;

/**
 * Set of commonly used loggers.
 */
@ParametersAreNonnullByDefault
public class Loggers {
    /**
     * This creates a factory that will eat all log input.
     */
    public static Logger.Factory noOpFactory() {
        return NoOpLoggerFactory.instance();
    }

    /**
     * This creates a factory that will use the standard android static log
     * methods.
     */
    public static Logger.Factory tagFactory() {
        return TagLoggerFactory.instance();
    }

    /**
     * Creates a logger factory which always returns the given logger.
     */
    public static Logger.Factory factoryFor(final Logger logger) {
        return new Logger.Factory() {
            @Override
            public Logger create(Tag tag) {
                return logger;
            }
        };
    }

    /**
     * Creates loggers that eat all input and does nothing.
     */
    private static class NoOpLoggerFactory implements Logger.Factory {
        private static class Singleton {
            private static final NoOpLoggerFactory INSTANCE = new NoOpLoggerFactory();
        }

        public static NoOpLoggerFactory instance() {
            return Singleton.INSTANCE;
        }

        private final NoOpLogger mNoOpLogger;

        public NoOpLoggerFactory() {
            mNoOpLogger = new NoOpLogger();
        }

        @Override
        public Logger create(Tag tag) {
            return mNoOpLogger;
        }
    }

    /**
     * Creates loggers that use tag objects to write to standard android log
     * output.
     */
    private static class TagLoggerFactory implements Logger.Factory {
        private static class Singleton {
            private static final TagLoggerFactory INSTANCE = new TagLoggerFactory();
        }

        public static TagLoggerFactory instance() {
            return Singleton.INSTANCE;
        }

        @Override
        public Logger create(Tag tag) {
            return new TagLogger(tag);
        }
    }

    /**
     * NoOp logger eats all input messages and does not display them.
     */
    private static class NoOpLogger implements Logger {
        @Override
        public void d(String msg) {
        }

        //......

        @Override
        public void w(String msg, Throwable tr) {
        }
    }

    /**
     * TagLogger logger writes to the standard static log output with the given
     * tag object.
     */
    private static class TagLogger implements Logger {
        private final Log.Tag mTag;

        public TagLogger(Log.Tag tag) {
            mTag = tag;
        }

        @Override
        public void d(String msg) {
            Log.d(mTag, msg);
        }

        @Override
        public void e(String msg) {
            Log.e(mTag, msg);
        }
        //.....

        @Override
        public void w(String msg, Throwable tr) {
            Log.w(mTag, msg, tr);
        }
    }
}
SingleDeviceActions 【文件
package com.android.camera.device;

import com.android.camera.async.Lifetime;

/**
 * Device specific actions for opening and closing a device.
 */
public interface SingleDeviceActions<TDevice> {

    /**
     * Open the device represented by this instance. This should only
     * be called if there is a reasonable expectation that the device is
     * available and openable.
     *
     * It is possible for this to throw if there is a problem with the
     * parameters or if the camera device determined to be un-openable.
     */
    public void executeOpen(SingleDeviceOpenListener<TDevice> openListener,
          Lifetime deviceLifetime) throws UnsupportedOperationException;
    /**
     * Close the device represented by this instance.
     *
     * It is possible for this to throw if there is a problem with the
     * parameters used to create these actions.
     */
    public void executeClose(SingleDeviceCloseListener closeListener, TDevice device)
          throws UnsupportedOperationException;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值