设计模式简单工厂
- 格式:docx
- 大小:68.36 KB
- 文档页数:13
简单工厂模式的使用场景与示例简单工厂模式是一种常见的设计模式,它是一种创建型模式,可以帮助我们根据客户端的需求动态地生成不同的对象。
本文将介绍简单工厂模式的使用场景与示例,以便读者更好地理解和应用该模式。
一、简单工厂模式的基本原理在介绍简单工厂模式的使用场景之前,我们先来了解一下它的基本原理。
简单工厂模式由三个角色组成:工厂类、抽象产品类和具体产品类。
工厂类根据客户端的需求,决定创建哪一种具体产品类的对象,并返回给客户端使用。
二、简单工厂模式的使用场景1. 创建对象时只需要知道其类别,而不需要知道具体的实现。
简单工厂模式可以隐藏具体产品类的创建细节,客户端只需要调用工厂类的方法即可获取所需的对象。
2. 客户端不关心对象的创建过程。
通过简单工厂模式,我们可以将对象的创建逻辑封装在工厂类中,使得客户端完全不需要关心对象的创建过程,只需要关心获取到所需对象即可。
3. 需要一组相关的对象被统一创建。
在某些场景下,我们可能需要一组相关的对象被统一创建,简单工厂模式可以灵活地满足这种需求。
三、简单工厂模式的示例下面通过一个示例来具体介绍简单工厂模式的应用。
假设我们有一个游戏场景中的角色类,包括玩家角色和敌人角色。
我们需要根据不同的角色类型创建对应的角色对象。
首先,我们定义一个抽象角色类(Role),用于表示玩家角色和敌人角色的共有属性和方法,包括姓名(name)和攻击力(attack)。
```javapublic abstract class Role {protected String name;protected int attack;public Role(String name, int attack) { = name;this.attack = attack;}public abstract void display();public abstract void attack();}```接下来,我们定义具体的玩家角色类(PlayerRole)和敌人角色类(EnemyRole),它们分别继承自抽象角色类(Role)。
23种设计模式(⼀)---简单⼯⼚设计模式简单⼯⼚设计模式---透彻讲解⼀. 什么是⼯⼚理解简单⼯⼚设计模式, ⾸先要理解什么是⼯⼚. 我们⾝边有很多⼯⼚. 酿酒的酒⼚, 制⾐的⾐⼚, 加⼯⾁类的⾁加⼯⼚等等. 这些⼯⼚他们到底是怎么酿酒的? 怎么制⾐的?怎么加⼯⾁的? 我们并不知道, 也不需要知道. 不知道并不影响我们喝酒, 穿⾐, 吃⾁. 这就是⼯⼚的特点之⼀: 客户不需要知道怎么做的, 但是不影响使⽤再来看看⼯⼚的第⼆个特点: ⽐如⾁加⼯⼚---双汇. ⽜⾁进去出来⽜⾁⽕腿肠, ⽺⾁进去出来⽺⾁⽕腿肠, 猪⾁进去出来猪⾁⽕腿肠. 我不需要知道怎么加⼯的, 我只需要把材料扔进去, 然后对应的⽕腿肠就出来了. 这就是第⼆个特点: 给你材料, 你去制造出我想要的东西, ⾄于怎么做,我并不关⼼.程序中的⼯⼚也是⼀样的思想. **⼯⼚的作⽤就是创造对象. **⼆. 简单⼯⼚设计模式2.1. 设计模式我们基本都知道设计模式有23种, 说到这, 我们先来说说设计模式。
设计模式不是语法, ⽽是⼀种巧妙的写法, 能够把程序变得更加灵活的写法.设计模式有三种: 创建型, ⾏为型, 结构型. 简单⼯⼚设计模式属于创建型. 但简单⼯⼚设计模式不属于23种设计模式范围内, 属于23种设计模式中⼯⼚设计模式⾥最简单的⼀种.2.2. 简单⼯⼚设计模式简单⼯⼚设计模式, ⼜叫做静态⼯⼚设计模式. 简单⼯⼚设计模式提供⼀个创建对象实例的功能,⽽⽆需关系其具体实现,被创建实例的类型可以是接⼝、抽象类,也可以是具体的类。
2.3. 简单⼯⼚设计模式的4要素这个很重要, 这也是创建⼀个简单⼯⼚的步骤1. API接⼝: 创建⼀个API接⼝或抽象类2. Impl实现类: ⼀个或多个实现API接⼝/抽象类的类3. ⼯⼚: 定义⼀个⼯⼚, ⽤来创建API接⼝类对象4. 客户端: ⽤来调⽤⼯⼚创建API接⼝或抽象类的客户端2.4 简单⼯⼚结构类型及说明以上类型就描述了⼀个简单⼯⼚创建的整个过程第⼀步: 定义API接⼝或抽象类, 并定义⼀个operate操作⽅法第⼆步: 定义API的实现类, 每个实现类单独实现operate⽅法第三步: 定义⼯⼚类. ⼯⼚类依赖API接⼝和API的实现类, 简单⼯⼚设计模式是创建型的, 通常是⽤来创建实体类. 因此我们定义⼀个create⽅法, 来创建实例对象,⼊参通常是⼀个指定的类型第四步: 定义客户端. 客户端传⼊⼀个指定的类型给⼯⼚, ⼯⼚就会创建出对应的实现类.2.5 简单⼯⼚模板代码第⼀步: 制⾐⼚API接⼝package com.lxl.www.designPatterns.simpleFactory.demo;public interface IClothes {void operate();}第⼆步: 制⾐⼚API实现类ManClothes: 制作男⼠⾐服package com.lxl.www.designPatterns.simpleFactory.demo;public class ManClothes implements IClothes{@Overridepublic void operate() {System.out.println("制作男⼈的⾐服");}}WomenClothes: 制作⼥⼠⾐服package com.lxl.www.designPatterns.simpleFactory.demo;public class WomenClothes implements IClothes{@Overridepublic void operate() {System.out.println("制作⼥⼈的⾐服");}}ChildClothes: 制作⼉童⾐服package com.lxl.www.designPatterns.simpleFactory.demo;public class ChildClothes implements IClothes{@Overridepublic void operate() {System.out.println("制作⼉童的⾐服");}}第三步: 定义⼯⼚, 并创建⾐服类接⼝package com.lxl.www.designPatterns.simpleFactory.demo;/*** 制⾐⼯⼚*/public class ClothesFactory {public static IClothes createClothes(String type) {if (type.equals("男⼈")) {return new ManClothes();} else if (type .equals("⼥⼈")) {return new WomenClothes();} else {return new ChildClothes();}}}第四步: 定义客户端, 指定制⾐类别, 制⾐.public static void main(String[] args) {IClothes manClothes = ClothesFactory.createClothes("男⼈");manClothes.operate();}2.6 简单⼯⼚命名建议类命名建议为“模块名称+Factory”,⽐如,⽤户模块的⼯⼚就称为UserFactory, 制⾐⼯⼚: ClothesFactory⽅法名称通常为“get+接⼝名称”或者是“create+接⼝名称”。
简单⼯⼚模式、⼯⼚模式和抽象⼯⼚模式区别及优缺点各位⼩伙伴好,今天给⼤家主要介绍⼀下简单⼯⼚模式、⼯⼚模式和抽象⼯⼚模式的区别及各⾃的优缺点。
(本⽂实现语⾔为Python3)【前⾔】众所周知今天所讲的内容是设计模式的⼀类;对于设计模式这个概念,我想⾸先请⼤家问问⾃⼰:1、什么是设计模式 2、我们为什么要了解并学习设计模式?从我上学的时候我相信⼤家跟我⼀样也接触过设计模式的课程,当时可能懵懵懂懂只是知其然,当时还会想明明可以直接写出来为什么要搞成这样的形式,我就算学会了它到底什么时候能⽤呢?⼀系列的问题...Emm算了到时候再想想(lazy)。
随着实践的不断增多,现在我想可以对这些问题有个初步的回答了: 1、在我看来,设计模式外在看是经过前⼈不断实践总结出的针对某些指定场景极其好⽤的⼀种代码结构设计模板;内在看其实是⼀种设计思想(即为什么他们会这么想,这样想较之其他⽅法有什么好处)。
当我们真正的理解设计思想的时候,就可能会在⾯对问题和场景时⾃然⽽然的灵活运⽤到多种设计模式,⽽不是单⼀的刻板结构。
2、在⼯程化的开发中,需求往往是会不断变化的,这也是让很多开发⼈员及其烦躁的地⽅,所以才会有开发与产品的亲密关系。
设计模式就是为了抵御外部需求变化产⽣的。
设计模式应符合开闭原则(类、模块和函数等应该对扩展开放,对修改关闭。
)⼀个好的设计在之后的开发中,包括发⽣重⼤需求变化的时候,往往代码只需要进⾏简单重构去进⾏适配,⽽不是通过打补丁的⽅式去堆砌,也很容易避免破窗效应,充分的发挥了灵活的扩展和适配,⼤⼤增强了维护性。
综上所述,我们了解并学习设计模式,可以使我们的代码变得更加健壮、结构清晰,可以从容、灵活的适配需求变更(可复⽤、可扩展、可维护、够灵活)【正⽂】⾸先,这三种模式解决的问题是实例化对象的问题;那么为什么不直接实例化⽽⽤这样的⼯⼚形式去实例化对象呢?因为【待实例化对象太多(⼦类多且变动、调⽤频繁)或者实例化对象的过程、准备⽐较复杂】,直接实例化意味着每次都⽤重复的去执⾏实例化这个操作,如果有很多待实例化的操作,那么就要重复执⾏很多次,更不要说万⼀在实例化之前还要执⾏⼀堆配置项的初始化。
设计模式之简单⼯⼚模式(SimpleFactoryPattern)⼀、简单⼯⼚模式的由来 所有设计模式都是为解决某类问题⽽产⽣的,那么简单⼯⼚模式是为解决什么问题呢?我们假设有以下业务场景: 在⼀个学⽣选课系统中,⽂科⽣⽤户选课时,我们要获得⽂科⽣的所有课程列表;理科⽣⽤户选课时,获得理科⽣的所有课程列表;体育⽣⽤户选课时,获得体育⽣的所有课程列表;那我们的逻辑怎么写呢?很简单,我们⽤伪代码实现如下:if(userType is ⽂科⽣){return ⽂科⽣课程;}else if(userType is 理科⽣){return 理科⽣课程;}else if(userType is 体育⽣){return 体育⽣课程;} 这时我们发现,不光在学⽣选课时需要这段逻辑,在学⽣查询课程时,也需要这段代码,于是我们理所应当的将这段代码复制到了查询课程的⽅法中,如果⽼师查询课程的⽅法中也要这段代码,那继续复制到⽼师查看课程的⽅法中。
这就造成了重复性代码,如何让这段代码只写⼀遍,多处可以复⽤呢?我们可以将这段代码抽取成公共⽅法,将学⽣类型定义成参数。
在调⽤的地⽅,通过传⼊不同的参数类型,返回不同的课程列表。
这样就实现了⼀次代码,多次复⽤的效果。
以上的这种优化过程,其实就是简单⼯⼚模式的⽣成过程。
⼆、什么是简单⼯⼚模式? 在简单⼯⼚模式中,程序员创建或者获得对象,不再⽤new Object()的⽅式进⾏,⽽是给⼯⼚类传⼊参数,⼯⼚类根据程序员传⼊参数的不同,返回不同的对象。
三、简单⼯⼚模式的⾓⾊ 简单⼯⼚模式中,有以下⼏种⾓⾊,这些⾓⾊撑起了简单⼯程模式的实现: 产品规范:提供规范,供其它产品⼦类来实现这些规范;可以是接⼝,抽象类或者⽗类; 产品实现:产品规范的具体实现类;实现或者继承产品规范的接⼝,抽象类或⽗类; 调度类(⼯⼚类):有了产品规范,也有了产品实现,那⽤哪个产品呢,由调度类来调度决定。
产品使⽤者:使⽤产品的地⽅,传⼊想使⽤的产品参数,通过调度类给产品使⽤者返回产品。
C#设计模式(1)——简单⼯⼚模式1.什么是简单⼯⼚ 现实中的⼯⼚负责⽣产产品,顾名思义,编程中的简单⼯⼚就是⼀个⽣产对象的类,它的主要作⽤是创建具体的产品类实例。
我们以⼀个⽣产⿏标为例来分析简单⼯⼚的作⽤,⿏标有两种:戴尔⿏标和惠普⿏标,代码如下://⿏标抽象类public abstract class Mouse{public abstract void Print();}//戴尔⿏标public class DellMouse : Mouse{public override void Print(){Console.WriteLine("⽣产了⼀个Dell⿏标!");}}//惠普⿏标public class HpMouse : Mouse{public override void Print(){Console.WriteLine("⽣产了⼀个惠普⿏标!");}}客户端代码:class Program{static void Main(string[] args){Mouse mouse1 = new DellMouse();Mouse mouse2 = new DellMouse();Mouse mouse3 = new DellMouse();Mouse mouse4 = new DellMouse();Mouse mouse5 = new DellMouse();mouse1.Print();}}程序运⾏如下: 我们可以看到程序运⾏没有问题,通过new⼀个DellMouse我们可以创建⼀个戴尔的⿏标,这时有⼀个问题,如果我们不想要戴尔⿏标了,要全部⽣产惠普⿏标怎么办呢?最简单直接的⽅法就是把new DellMouse全部替换成new HpMouse 。
如果我们的软件中new了100个DellMouse实例呢?⼀个⼀个地去替换会是⼀个巨⼤的⼯作量,同时通过new的⽅式来创建戴尔⿏标的实例,会让DellMouse类和客户端产⽣强耦合关系,这时候使⽤简单⼯⼚就可以帮助我们降低耦合,减少⼯作量了。
简单工厂工厂方法抽象工厂策略模式策略与工厂的区别简单工厂、工厂方法、抽象工厂以及策略模式在软件开发中都是常用的设计模式,它们都是为了解决不同对象的创建和使用问题。
下面将对它们进行详细的介绍,并比较它们之间的区别。
1. 简单工厂模式(Simple Factory Pattern):简单工厂模式是由一个工厂类根据传入的参数决定创建哪种产品的设计模式。
它包含三个角色:工厂类负责创建产品,产品类定义产品的具体实现,客户端通过工厂类获取产品对象。
简单工厂模式将对象的创建与使用进行了分离,增加了灵活性,但是违反了开闭原则,因为每次新增产品都需要修改工厂类。
2. 工厂方法模式(Factory Method Pattern):工厂方法模式是指定义一个创建产品对象的接口,但是由子类决定实例化哪个类。
这样可以将产品的实例化延迟到子类中进行,满足了开闭原则。
工厂方法模式由抽象工厂类、具体工厂类和抽象产品类、具体产品类组成。
具体工厂类负责创建具体产品类的实例,抽象产品类定义了产品的接口。
客户端通过抽象工厂类获取产品对象。
工厂方法模式解决了简单工厂模式的缺点,但是增加了类的个数。
3. 抽象工厂模式(Abstract Factory Pattern):抽象工厂模式是指提供一个创建一系列相关或互相依赖对象的接口,而无需指定具体的类。
抽象工厂模式由抽象工厂类、具体工厂类和抽象产品类、具体产品类组成。
抽象工厂类定义了创建产品的接口,具体工厂类负责创建具体产品。
抽象产品类定义了产品的接口,具体产品类实现了产品的具体实现。
客户端通过抽象工厂类获取产品对象。
抽象工厂模式提供了一种创建一系列产品对象的方法,但是增加新产品时需要修改所有的工厂类。
4. 策略模式(Strategy Pattern):策略模式是指定义了一系列的算法,并将每个算法封装起来,使得它们可以互相替换,使得算法的选择和使用可以独立于客户端。
策略模式由抽象策略类、具体策略类和环境类组成。
面向对象设计的23个设计模式详解面向对象设计是一种广泛应用于软件开发的思想,其核心在于将数据和操作封装在一起形成对象,并通过各种方式进行交互和组合,从而实现复杂的功能。
在这一过程中,设计模式起到了非常重要的作用,可以有效地提高代码的可读性、可维护性和可扩展性。
本文将对23种常见的设计模式进行详解。
一、创建型模式1.简单工厂模式简单工厂模式属于创建型模式,其目的是提供一个工厂类,使得创建对象的过程更加简单。
在这种模式中,使用者只需要提供所需对象的参数,而无需关心对象的具体实现细节。
简单工厂模式适合于对象创建过程较为简单的情况。
2.工厂方法模式工厂方法模式是简单工厂模式的进一步扩展,其核心在于将工厂类进行接口抽象化,使得不同的工厂类可以创建不同的对象实例。
工厂方法模式适合于对象创建过程较为复杂的情况。
它可以为工厂类添加新的产品类型,而不会影响原有的代码。
3.抽象工厂模式抽象工厂模式是工厂方法模式的进一步扩展,其目的是提供一个可以创建一系列相关或者独立的对象的接口。
在抽象工厂模式中,使用者只需要关心所需对象组合的类型,而无需关注对象的具体实现过程。
4.建造者模式建造者模式也是一种创建型模式,其目的在于将复杂对象分解为多个简单的部分,并将其组装起来形成复杂对象实例。
在建造者模式中,使用者只需要关注所需对象以及它们的组合方式,而无需关心对象的具体实现过程。
5.原型模式原型模式是一种基于克隆的创建型模式,其核心在于通过复制现有的对象实例来创建新的对象。
在原型模式中,对象实例的创建过程与对象所包含的状态密切相关。
原型模式适合于创建复杂对象实例,且这些对象实例之间是相对独立的情况。
二、结构型模式6.适配器模式适配器模式是一种结构型模式,其目的在于将一个类的接口转换为另一个类所能使用的接口。
在适配器模式中,使用者可以通过不同的适配器实现对象之间的互相调用。
7.桥接模式桥接模式是一种结构型模式,其目的在于将抽象部分与实现部分相互分离,从而使得两者可以独立变化。
c++设计模式:简单⼯⼚模式(SimpleFactoryPattern)定义:从设计模式的类型上来说,简单⼯⼚模式是属于创建型模式,⼜叫做静态⼯⼚⽅法(StaticFactory Method)模式,但不属于23种GOF设计模式之⼀。
简单⼯⼚模式是由⼀个⼯⼚对象决定创建出哪⼀种产品类的实例。
简单⼯⼚模式是⼯⼚模式家族中最简单实⽤的模式,可以理解为是不同⼯⼚模式的⼀个特殊实现。
场景:我们要开⼀家⽐萨商店,定义了⼀个简单的披萨⼯⼚,可以根据客户的需要制作芝⼠披萨、辣肠⽐萨、蛤蜊披萨、素⾷披萨。
根据传⼊的披萨类型从披萨⼯⼚⽣产出客户所需要的披萨。
类图:c++代码如下:#include <iostream>#include <string>#include <vector>using namespace std;class PizzaType{public:enum EPizzaType{cheese,pepperoni,clam,veggie};};class Pizza{public:virtual ~Pizza() {};string getName();void prepare();void bake();void cut();void box();protected:string name;string dough;string sauce;vector<string> toppings;};class CheesePizza : public Pizza{public:CheesePizza();};class PepperoniPizza : public Pizza{public:PepperoniPizza();};class ClamPizza : public Pizza{public:ClamPizza();};class VeggiePizza : public Pizza{public:VeggiePizza();};class SimplePizzaFactory{public:Pizza* createPizza(PizzaType::EPizzaType type);};class PizzaStore{private:SimplePizzaFactory factory;public:Pizza* orderPizza(PizzaType::EPizzaType type);};string Pizza::getName(){return name;}void Pizza::prepare(){printf("Preparing %s\n",name.c_str());}void Pizza::bake(){printf("Baking %s\n",name.c_str());}void Pizza::cut(){printf("Cutting %s\n",name.c_str());}void Pizza::box(){printf("Boxing %s\n",name.c_str());}CheesePizza::CheesePizza(){name = "Cheese Pizza";dough = "Regular Crust";sauce = "Marinara Pizza Sauce";toppings.push_back("Fresh Mozzarella");toppings.push_back("Parmesan");}PepperoniPizza::PepperoniPizza(){name = "Pepperoni Pizza";dough = "Crust";sauce = "Marinara sauce";toppings.push_back("Sliced Pepperoni");toppings.push_back("Sliced Onion");toppings.push_back("Grated parmesan cheese");}ClamPizza::ClamPizza(){name = "Clam Pizza";dough = "Thin crust";sauce = "White garlic sauce";toppings.push_back("Clams");toppings.push_back("Grated parmesan cheese");}VeggiePizza::VeggiePizza(){name = "Veggie Pizza";dough = "Crust";sauce = "Marinara sauce";toppings.push_back("Shredded mozzarella");toppings.push_back("Grated parmesan");toppings.push_back("Diced onion");toppings.push_back("Sliced mushrooms");toppings.push_back("Sliced red pepper");toppings.push_back("Sliced black olives");}Pizza* SimplePizzaFactory::createPizza(PizzaType::EPizzaType type) {Pizza* pizza = NULL;if (PizzaType::cheese == type){pizza = new CheesePizza();}else if (PizzaType::pepperoni == type){pizza = new PepperoniPizza();}else if (PizzaType::clam == type){pizza = new ClamPizza();}else if (PizzaType::veggie == type){pizza = new VeggiePizza();}return pizza;}Pizza* PizzaStore::orderPizza(PizzaType::EPizzaType type){Pizza* pizza = NULL;pizza = factory.createPizza(type);pizza->prepare();pizza->bake();pizza->cut();pizza->box();return pizza;}int main(){PizzaStore pizzaStore;Pizza* pCheesePizza = pizzaStore.orderPizza(PizzaType::cheese);Pizza* pPepperoniPizza = pizzaStore.orderPizza(PizzaType::pepperoni); Pizza* pClamPizza = pizzaStore.orderPizza(PizzaType::clam);Pizza* pVeggiePizza = pizzaStore.orderPizza(PizzaType::veggie);delete pCheesePizza;delete pPepperoniPizza;delete pClamPizza;delete pVeggiePizza;return0;}运⾏后结果如下:Preparing Cheese PizzaBaking Cheese PizzaCutting Cheese PizzaBoxing Cheese PizzaPreparing Pepperoni PizzaBaking Pepperoni PizzaCutting Pepperoni PizzaBoxing Pepperoni PizzaPreparing Clam PizzaBaking Clam PizzaCutting Clam PizzaBoxing Clam PizzaPreparing Veggie PizzaBaking Veggie PizzaCutting Veggie PizzaBoxing Veggie Pizza参考图书:《Head First 设计模式》。
简单工厂设计模式目录1.1摘要 (2)2.1关键字 (2)3.1开发工具 (2)4.1简单工厂模式动机与定义: (3)4.1.1模式动机 (3)4.1.2模式定义 (3)5.1简单工厂模式结构 (4)6.1简单工厂模式实例: (5)6.1.1代码分析 (6)6.1.1.1Product(Shape抽象类)代码: (6)6.1.1.2ConcreteProduct(Juxing,YuanXing,SanJiao具体产品类)代码:.. 7JuXing类: (7)YuanXing类: (8)SanJiao类: (8)6.1.1.3Factory(Factory类)代码: (9)6.1.1.4 (main类): (10)6.1.1.5运行结果: (12)7.1结论 (12)8.1参考文献: (13)1.1摘要本文从面向对象的角度对java接口的概念、作用以及使用它的好处做分析,讲解面向接口编程的方法,结合初步接触软件开发的人员习惯,从简单工厂设计模式的概念和其结构以及用途进行解析,重点讲解简单工厂设计模式在软件开发过程中的作用和好处,通过一些实例来说明简单工厂设计模式的特点。
2.1关键字面向对象;java接口;接口编程;简单工厂设计模式。
3.1开发工具Eclipse java语言开发4.1简单工厂模式动机与定义:在实际的软件开发过程中有时需要创建一些来自于相同父类的类的实例,为此可以专门定义一个类来负责创建这些类的实例,这些被创建的实例具有共同的父类。
在这种情况下,可以通过传入不同的参数从而获取不同的对象,理由Java语言的特征,习惯上将创建其他类实例的方法定义为static方法,外部不需要实例化这个类就可以直接调用该方法来获得需要的对象,该方法也成为静态工厂方法。
4.1.1模式动机考虑一个简单的软件应用场景,一个软件系统可以提供多个外观不同的按钮(如圆形按钮,矩形按钮等),这些按钮都源自同一个基类,不过在继承基类之后不同的子类修改了部分属性从而使得它们可以呈现不同的外观,如果我们希望在使用这些按钮时,不需要知道这些具体按钮类的名字,只需要知道表示该按钮的一个参数,并提供一个调用方便的方法,把该参数传入方法即可返回一个相应的按钮对象,此时,就可以使用简单工厂模式。
4.1.2模式定义简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常具有共同的父类。
5.1简单工厂模式结构a、Factory(工厂角色)是简单工厂模式的核心,它负责实现创建所有具体产品类的实例。
工厂类可以被外界直接调用,创建所需的产品对象。
b、Product(抽象产品角色)是所有具体产品角色的父类,它负责描述所有实例所共有的公共接口。
c、ConcreteProduct(具体产品角色)继承自抽象产品角色,一般为多个,是简单工厂模式的创建目标。
工厂类返回的都是该角色的某一具体产品。
6.1简单工厂模式实例:使用简单工厂模式设计一个可以创建不同几何形状(如圆形、方形和三角形等)的绘图工具,每个几何图形都要绘制draw()和擦除erase()两个方法,要求在绘制不支持的几何图形时,提示一个UnSupportedShapeException。
6.1.1代码分析6.1.1.1Product(Shape抽象类)代码:import java.awt.Graphics;import javax.swing.JPanel;publicabstractclass AbstractShape { static Graphics g;publicabstractvoid draw(JPanel p);publicabstract JPanel erase(JPanel p); }分析:创建draw()和erase()方法供子类继承调用;6.1.1.2ConcreteProduct(Juxing,YuanXing,SanJiao具体产品类)代码://各个产品类代码类似、需要添加产品类时只需要另外创建一个类然后再修改工厂类少量代码即可JuXing类:import javax.swing.JPanel;//绘制矩形publicclass JuXing extends AbstractShape {private JPanel p;@Overridepublicvoid draw(JPanel p) {// TODO Auto-generated method stubthis.p=p;//g.drawrect(50, 50, 100, 50);}@Overridepublic JPanel erase(JPanel p) {p.repaint();// TODO Auto-generated method stubreturn p;}}YuanXing类:import javax.swing.JPanel;//绘制圆形publicclass YuanXing extends AbstractShape { private JPanel p;@Overridepublicvoid draw(JPanel p) {// TODO Auto-generated method stubthis.p=p;//g.drawOval(50, 50, 50, 50);}@Overridepublic JPanel erase(JPanel p) {p.repaint();// TODO Auto-generated method stubreturn p;}}SanJiao类:import javax.swing.JPanel;//绘制三角形publicclass SanJiao extends AbstractShape { private JPanel p;@Overridepublicvoid draw(JPanel p) {// TODO Auto-generated method stubthis.p=p;//int x[]={130,100,200}int y[]={130,200,200};g.drawPolygon(x, y, 3); }@Overridepublic JPanel erase(JPanel p) {p.repaint();// TODO Auto-generated method stubreturn p;}}6.1.1.3Factory(Factory类)代码:publicclass Factory {publicstatic AbstractShapecreatShape(String s) throws Exception{ if(s.equalsIgnoreCase("矩形")){returnnew JuXing();}elseif(s.equalsIgnoreCase("圆形")){returnnew YuanXing();}elseif(s.equalsIgnoreCase("三角形")){returnnew SanJiao();}else {thrownew Exception("UnSupportedShapeException");}}}//注释:用于创建各个具体产品角色的对象;6.1.1.4 (main类):创建一个窗体,添加控件和监听代码如下:import javax.swing.*;import java.awt.*;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;publicclass ShapeFrame extends JFrame implements ActionListener { JPanel contentPane = new JPanel();JPanel upPane = new JPanel();JPanel centerPane = new JPanel();String shapeStr[] = {"圆形","矩形","三角形"};JComboBox cmb = new JComboBox(shapeStr);JLabel lab = new JLabel("选择目标图形:");JButton drawBtu = new JButton("绘制");JButton eraseBtu = new JButton("擦除");Shape shape;ShapeFrame(String title) {super(title);setSize(800,600);setLocationRelativeTo(null);addPane();setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);}void addPane() {setContentPane(contentPane);contentPane.setLayout(new BorderLayout());contentPane.setBackground(Color.white);upPane.setBackground(Color.white);centerPane.setBackground(Color.white);contentPane.add(upPane,BorderLayout.NORTH);contentPane.add(centerPane,BorderLayout.CENTER);initWidget();upPane.add(lab);upPane.add(cmb);upPane.add(drawBtu);upPane.add(eraseBtu);}void initWidget() {drawBtu.addActionListener(this);eraseBtu.addActionListener(this);}//关键代码@Overridepublicvoid actionPerformed(ActionEvent e) {Object object = e.getSource();if (object.equals(drawBtu)) {String shapeName = cmb.getSelectedItem().toString(); try{shape = ShapeFactory.creatShape(shapeName);shape.draw(centerPane);}catch (Exception error){error.printStackTrace();}} elseif (object.equals(eraseBtu)) {if (shape != null) {JPanel newPanel = shape.erase(centerPane);contentPane.add(newPanel, BorderLayout.CENTER);repaint();shape = null;}}}}6.1.1.5运行结果:7.1结论简单工厂模式的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类的实例。