浅尝设计模式——如何使用工厂模式

本文为阅读《Head First 设计模式》一书的摘要总结

工厂模式

简单工厂

定义

简单工厂并不是一个设计模式,反而比较像一种编程习惯。该习惯将代码中,实例化对象的部分封装起来,独立于客户。使得客户代码满足 关闭-开放原则

示例

Pizza orderPizza(String type){
	Pizza pizza;
	if (type.equals("cheese")){
		pizza = new CheesePizza();
	}else if (type.equals("greek")){
		pizza = new GreekPizza();
	}else if (type.equals("pepperoni")){
		pizza = new PepperoniPizza();
	}
	pizza.prepare();
	pizza.bake();
	pizza.cut();
	pizza.box();
	return pizza();
}

上面的代码中,实例化Pizza的部分复杂且很可能会改变,而实例化之后对Pizza方法的调用相对固定。所以我们可以将实例化Pizza的部分封装起来,形成一个简单工厂:

public class SimplePizzaFactory(){
	public Pizaa createPizza(String type){
		if (type.equals("cheese")){
			pizza = new CheesePizza();
		}else if (type.equals("greek")){
			pizza = new GreekPizza();
		}else if (type.equals("pepperoni")){
			pizza = new PepperoniPizza();
		}
	}
}
public class PizzaStroe{
	private SimplePizzaFactory simplePizzaFactory;
	public PizzaStroe(SimplePizzaFactory simplePizzaFactory){
		this.simplePizzaFactory = simplePizzaFactory;
	}
	Pizza orderPizza(String type){
		Pizza pizza = simplePizzaFactory.createPizza(type);
		pizza.prepare();
		pizza.bake();
		pizza.cut();
		pizza.box();
		return pizza();
	}
}

将对象实例化的过程封装起来,SimplePizzaFactory就可以有多个客户,不仅仅是现在的PizzaStroe,同时,以后实现改变时,只需要修改SimplePizzaFactory类即可。

有时候我们也可以利用静态方法创建一个简单工厂,这样我们就不需要实例化工厂类。但是这样而有一个弊端,我们不能通过继承来覆盖来改变创建方法的行为(静态方法不能被覆盖)。

工厂方法模式

定义

工厂方法模式定义了一个创建对象的接口,但由子类来决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。

示例

Product超类:

public class Pizza {
    String name;
    void prepare(){
        System.out.println("Preparing "+ name);
        System.out.println("Tossing dough...");
        System.out.println("Adding sauce...");
        System.out.println("Adding toppings:");
    }
    void back(){
        System.out.println("Bake for 25 minites at 350");
    }
    void cut(){
        System.out.println("Cutting the pizza into diagonal slices");
    }
    void box(){
        System.out.println("Place pizza in official PizzaStore box");
    }
    public String getName(){
        return name;
    }

}

具体Product:

public class NYStyleClamPizza extends Pizza{
    public NYStyleClamPizza() {
        this.name = "NYStyleClamPizza";
    }
	//覆盖父类的方法,使用自己的切片方式
	public void cut(){
		System.out.println("Cutting the pizza into square slices");
	}
}
public class NYStyleVeggiePizza extends Pizza{
    public NYStyleVeggiePizza() {
        this.name = "NYStyleVeggiePizza";
    }
}

工厂超类:

public abstract class PizzaStory {
    public Pizza orderPizza(String type){
		//创建这通常会包含依赖于抽象产品的代码
        Pizza pizza = createPizza(type);
        pizza.prepare();
        pizza.back();
        pizza.cut();
        pizza.box();
        return pizza;
    }

    protected abstract Pizza createPizza(String type);
}

为了保证制作Pizza的流程一致,所以在超类中实现orderPizza方法。还定义了一个抽象的 工厂方法 createPizza,该方法由子类来负责实现,使得不同的子类可以实例化不同类型的Pizza

具体的工厂类:

public class NYPizzaStory extends PizzaStory{

    @Override
    protected Pizza createPizza(String type) {
        if (type.equals("NYStyleVeggiePizza")){
            return new NYStyleVeggiePizza();
        }else if (type.equals("NYStyleClamPizza")){
            return new NYStyleClamPizza();
        }
        return null;
    }
}

抽象工厂模式

定义

抽象工厂模式提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。

抽象工厂为产品家族提供工厂,产品家族就是形成产品的一且组件。

示例

现在,我们要在上面的例子上做一些改变,我们希望可以通过工厂来提供组成Pizza的原料。

抽象工厂:

public interface PizzaIngredientFactory{
	public Dough createDough();
	public Sauce createSauce();
	public Cheese createCheese();
	public Veggies[] createVeggies();
	public Pepperoni createPepperoni();
	public Clams createClam();
}

具体工厂类:

public class NYPizzaIngredientFactory implements PizzaIngredientFactory {
    public Dough createDough() {
        return new ThinCrustDough();
    }
    public Sauce createSauce() {
        return new MarinaraSauce();
    }
    public Cheese createCheese() {
        return new ReggianoCheese();
    }
    public Veggies[] createVeggies() {
        Veggies veggies[] = { new Garlic(), new Onion(), new Mushroom(), new RedPepper() };
        return veggies;
    }
    public Pepperoni createPepperoni() {
        return new SlicedPepperoni();
    }
    public Clams createClam() {
        return new FreshClams();
    }
}

抽象工厂的方法经常以工厂方法的方式实现。

Pizza超类

public abstract class Pizza {
	//每种pizza都由一组原料构成,这些原料在prepare方法中被用到
    String name;
    Dough dough;
    Sauce sauce;
    Veggies veggies[];
    Cheese cheese;
    Pepperoni pepperoni;
    Clams clam;
	//这里把prepare方法定义为抽象方法,这是因为不同的Pizza类型可能由不同的成分组成,这需要有子类来实现
    abstract void prepare();
    void bake() {
        System.out.println(“Bake for 25 minutes at 350);
    }
    void cut() {
        System.out.println(“Cutting the pizza into diagonal slices”);
    }
    void box() {
        System.out.println(“Place pizza in official PizzaStore box”);
    }
    void setName(String name) {
        this.name = name;
    }
    String getName() {
        return name;
    }
}

具体的Pizza类型:

public class CheesePizza extends Pizza {
    PizzaIngredientFactory ingredientFactory;
	//我们需要工厂来为CheesePizza提供原料,所以每个Pizza类都通过构造器获得一个工厂
    public CheesePizza(PizzaIngredientFactory ingredientFactory) {
        this.ingredientFactory = ingredientFactory;
    }
	//prepare方法一步步的制作出CheesePizza,每一步所需要的原料都由原料工厂提供。而工厂具体提供的是哪种原料取决于我们提供的工厂类型。
    void prepare() {
        System.out.println(“Preparing “ + name);
        dough = ingredientFactory.createDough();
        sauce = ingredientFactory.createSauce();
        cheese = ingredientFactory.createCheese();
    }
}

PizzaStore:

public class NYPizzaStore extends PizzaStore {
    protected Pizza createPizza(String item) {
        Pizza pizza = null;
        PizzaIngredientFactory ingredientFactory =
                new NYPizzaIngredientFactory();
        if (item.equals(“cheese”)) {
            pizza = new CheesePizza(ingredientFactory);
            pizza.setName(“New York Style Cheese Pizza”);
        } else if (item.equals(“veggie”)) {
            pizza = new VeggiePizza(ingredientFactory);
            pizza.setName(“New York Style Veggie Pizza”);
        } else if (item.equals(“clam”)) {
            pizza = new ClamPizza(ingredientFactory);
            pizza.setName(“New York Style Clam Pizza”);
        } else if (item.equals(“pepperoni”)) {
            pizza = new PepperoniPizza(ingredientFactory);
            pizza.setName(“New York Style Pepperoni Pizza”);
        }
        return pizza;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
多头跨模态注意力机制是指在多模态处理使用的一种注意力机制,它可以捕捉和整合不同模态之间的相关信息。在模块设计,首先将不同模态的表示纳入自注意力模块,以捕捉每个模态内部的互动。然后将输出状态输入交叉注意力模块,以捕捉不同模态之间的互动。在这个机制使用了多头自注意力操作(ATTself)来处理同一模态内部的信息,使用了跨模态多头注意力(ATTcross)来处理不同模态之间的信息。具体来说,跨模态多头注意力会使用一个模态的Q(查询)矩阵和另一个模态的K(键)和V(值)矩阵进行注意力计算。这种跨模态注意力机制可以帮助模型更好地理解和整合多种模态的信息,从而提高多模态任务的性能。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [研读Joint Multi-modal Aspect-Sentiment Analysis with Auxiliary Cross-modal](https://blog.csdn.net/weixin_42776344/article/details/127867468)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [论文浅尝 - EMNLP2020 | 跨媒体关键词预测: 多模态多头注意力和图像文本的统一框架...](https://blog.csdn.net/TgqDT3gGaMdkHasLZv/article/details/111713643)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值