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

本文深入解析工厂模式、工厂方法模式及抽象工厂模式,通过实例详细阐述各模式的应用场景与实现方式,帮助读者理解并掌握面向对象设计原则。

本文为阅读《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;
    }
}
基于遗传算法的新的异构分布式系统任务调度算法研究(Matlab代码实现)内容概要:本文档围绕基于遗传算法的异构分布式系统任务调度算法展开研究,重点介绍了一种结合遗传算法的新颖优化方法,并通过Matlab代码实现验证其在复杂调度问题中的有效性。文中还涵盖了多种智能优化算法在生产调度、经济调度、车间调度、无人机路径规划、微电网优化等领域的应用案例,展示了从理论建模到仿真实现的完整流程。此外,文档系统梳理了智能优化、机器学习、路径规划、电力系统管理等多个科研方向的技术体系与实际应用场景,强调“借力”工具与创新思维在科研中的重要性。; 适合人群:具备一定Matlab编程基础,从事智能优化、自动化、电力系统、控制工程等相关领域研究的研究生及科研人员,尤其适合正在开展调度优化、路径规划或算法改进类课题的研究者; 使用场景及目标:①学习遗传算法及其他智能优化算法(如粒子群、蜣螂优化、NSGA等)在任务调度中的设计与实现;②掌握Matlab/Simulink在科研仿真中的综合应用;③获取多领域(如微电网、无人机、车间调度)的算法复现与创新思路; 阅读建议:建议按目录顺序系统浏览,重点关注算法原理与代码实现的对应关系,结合提供的网盘资源下载完整代码进行调试与复现,同时注重从已有案例中提炼可迁移的科研方法与创新路径。
【微电网】【创新点】基于非支配排序的蜣螂优化算法NSDBO求解微电网多目标优化调度研究(Matlab代码实现)内容概要:本文提出了一种基于非支配排序的蜣螂优化算法(NSDBO),用于求解微电网多目标优化调度问题。该方法结合非支配排序机制,提升了传统蜣螂优化算法在处理多目标问题时的收敛性和分布性,有效解决了微电网调度中经济成本、碳排放、能源利用率等多个相互冲突目标的优化难题。研究构建了包含风、光、储能等多种分布式能源的微电网模型,并通过Matlab代码实现算法仿真,验证了NSDBO在寻找帕累托最优解集方面的优越性能,相较于其他多目标优化算法表现出更强的搜索能力和稳定性。; 适合人群:具备一定电力系统或优化算法基础,从事新能源、微电网、智能优化等相关领域研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①应用于微电网能量管理系统的多目标优化调度设计;②作为新型智能优化算法的研究与改进基础,用于解决复杂的多目标工程优化问题;③帮助理解非支配排序机制在进化算法中的集成方法及其在实际系统中的仿真实现。; 阅读建议:建议读者结合Matlab代码深入理解算法实现细节,重点关注非支配排序、拥挤度计算和蜣螂行为模拟的结合方式,并可通过替换目标函数或系统参数进行扩展实验,以掌握算法的适应性与调参技巧。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值