1.场景问题解决
1.1 场景描述
披萨商店,可以生产各种披萨.
2.用设计模式改进
2.1 简单工厂
2.1.1 概述思路
将变化的会有if else判断的相关模块,单独提到一个专门处理的类中(简单工厂).
简单工厂模式: 定义了一个创建对象的类,由这个类来封装实例化对象的行为
2.1.2 代码示例
- abstract class Pizza (Pizza抽象类)
public abstract class Pizza {
protected String name;
public abstract void prepare();
public void bake()
{
System.out.println(name+" baking;");
}
public void cut()
{
System.out.println(name+" cutting;");
}
public void box()
{
System.out.println(name+" boxing;");
}
public void setname(String name)
{
this.name=name;
}
}
- APizza,BPizza,CPizza (pizza实体类)
public class APizza extends Pizza {
@Override
public void prepare() {
super.setname("APizza");
System.out.println(name+" preparing;");
}
}
public class BPizza extends Pizza {
@Override
public void prepare() {
super.setname("BPizza");
System.out.println(name+" preparing;");
}
}
public class CPizza extends Pizza {
@Override
public void prepare() {
super.setname("CPizza");
System.out.println(name+" preparing;");
}
}
- SimplePizzaFactory
public class SimplePizzaFactory {
public Pizza CreatePizza(String ordertype) {
Pizza pizza = null;
if (ordertype.equals("A")) {
pizza = new APizza();
} else if (ordertype.equals("B")) {
pizza = new BPizza();
} else if (ordertype.equals("C")) {
pizza = new CPizza();
}
return pizza;
}
}
- TestOrderPizza测试类
public class TestOrderPizza {
public static void main(String[] args) {
SimplePizzaFactory mSimplePizzaFactory = new SimplePizzaFactory();
Pizza pizza = mSimplePizzaFactory.CreatePizza("A");
if (pizza != null) {
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
}
System.out.println(pizza);
}
}
- 运行结果
APizza preparing;
APizza baking;
APizza cutting;
APizza boxing;
*.pizza.APizza@6b884d57
2.2 工厂方法模式
2.2.1 需求变动带来问题
pizza生意好,将在各地开分店.
每个分店的工厂不一样了.
2.2.2 概述和思路
工厂方法模式:定义了一个创建对象的抽象方法,由子类决定要实例化的类。 工厂方法模式将对象的实例化推迟到子类
2.2.3 示例
- Pizza,LDAPizza,LDBPizza,NYAPizza,NYBPizza
public abstract class Pizza {
protected String name;
public abstract void prepare();
public void bake()
{
System.out.println(name+" baking;");
}
public void cut()
{
System.out.println(name+" cutting;");
}
public void box()
{
System.out.println(name+" boxing;");
}
public void setname(String name)
{
this.name=name;
}
}
public class LDAPizza extends Pizza {
@Override
public void prepare() {
super.setname("LDAPizza");
System.out.println(name+" preparing;");
}
}
public class LDBPizza extends Pizza {
@Override
public void prepare() {
super.setname("LDBPizza");
System.out.println(name+" preparing;");
}
}
public class NYAPizza extends Pizza {
@Override
public void prepare() {
super.setname("NYAPizza");
System.out.println(name+" preparing;");
}
}
public class NYBPizza extends Pizza {
@Override
public void prepare() {
super.setname("NYBPizza");
System.out.println(name+" preparing;");
}
}
- OrderPizza,LDOrderPizza,NYOrderPizza
public abstract class OrderPizza {
public OrderPizza(){};
public OrderPizza(String ordertype) {
Pizza pizza = null;
do {
pizza = createPizza(ordertype);
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
} while (true);
}
abstract Pizza createPizza(String ordertype);
}
public class LDOrderPizza extends OrderPizza {
@Override
Pizza createPizza(String ordertype) {
Pizza pizza = null;
if (ordertype.equals("A")) {
pizza = new LDAPizza();
} else if (ordertype.equals("B")) {
pizza = new LDBPizza();
}
return pizza;
}
}
public class NYOrderPizza extends OrderPizza {
@Override
Pizza createPizza(String ordertype) {
Pizza pizza = null;
if (ordertype.equals("A")) {
pizza = new NYAPizza();
} else if (ordertype.equals("B")) {
pizza = new NYBPizza();
}
return pizza;
}
}
- 测试类TestPizzaStroe
public class TestPizzaStroe {
public static void main(String[] args) {
OrderPizza mOrderPizza = new NYOrderPizza();
Pizza p1 = mOrderPizza.createPizza("A");
System.out.println("p1->"+p1);
OrderPizza mOrderPizza2 = new LDOrderPizza();
Pizza p2 = mOrderPizza2.createPizza("B");
System.out.println("p2->"+p2);
}
}
- 运行结果
p1->*.pizza.NYAPizza@6b884d57
p2->*.pizza.LDBPizza@38af3868
2.3.4 注意点
- Pizza为抽象类,固定的为非抽象,可变的为抽象
-
- LDA,LDB,NYA,NYB都继承抽象类Pizza
- OrderPizza 为抽象类,抽象类OrderPizza中的createPizza为抽象方法. 真正的创建Pizza交给具体的实现类来处理.
-
- LDOrderPizza和NYOrderPizza继承(extends) OrderPizza,实现createPizza,来生成各自的Pizza.
2.3 抽象工厂模式
2.4 抽象工程
2.4.1 分析
在工厂方法中,是将方法相关的抽象出来,那可以更深入点将工厂抽象出来.
2.4.2 示例
- AbsFactory,LDFactory,NYFactory
public interface AbsFactory {
public Pizza CreatePizza(String ordertype) ;
}
public class LDFactory implements AbsFactory {
@Override
public Pizza CreatePizza(String ordertype) {
Pizza pizza = null;
if (ordertype.equals("A")) {
pizza = new LDAPizza();
} else if (ordertype.equals("B")) {
pizza = new LDBPizza();
}
return pizza;
}
}
public class NYFactory implements AbsFactory {
@Override
public Pizza CreatePizza(String ordertype) {
Pizza pizza = null;
if (ordertype.equals("A")) {
pizza = new NYAPizza();
} else if (ordertype.equals("B")) {
pizza = new NYBPizza();
}
return pizza;
}
}
- TestOrderPizza
public class TestOrderPizza {
AbsFactory mFactory;
Pizza pizza ;
public TestOrderPizza(AbsFactory mFactory, String ordertype) {
this.pizza = setFactoryAndOrder(mFactory,ordertype);
}
public Pizza setFactoryAndOrder(AbsFactory mFactory,String ordertype) {
Pizza pizza = null;
this.mFactory = mFactory;
pizza = mFactory.CreatePizza(ordertype);
if (pizza != null) {
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
}
return pizza;
}
public static void main(String[] args) {
TestOrderPizza mOrderPizza=new TestOrderPizza(new LDFactory(),"A");
System.out.println("mOrderPizza.getPizza()->"+mOrderPizza.getPizza());
}
public Pizza getPizza() {
return pizza;
}
public void setPizza(Pizza pizza) {
this.pizza = pizza;
}
}
- 运行结果
LDAPizza preparing;
LDAPizza baking;
LDAPizza cutting;
LDAPizza boxing;
mOrderPizza.getPizza()->*.pizza.LDAPizza@6b884d57
2.4.3 注意点
工厂都是抽象的,可以设置工厂
3.设计模式总结
3.1 定义
简单工厂模式:定义了一个创建对象的类,由这个类来封装实例化对象的行为.
- 依赖抽象原则
-
- 变量不要持有具体类的引用
-
- 不要让类继承自具体类,要继承自抽象类或接口
-
- 不要覆盖基类中已实现的方法
3.2 分析思路
3.2.1 引出工厂模式
分析项目中的变化部分和不变化部分,发现方法和执行不怎么变,而实例化部分改变,依赖性太强,那么就引出了对实例化部分进行改造,引出工厂模式.
--> 把项目中的实例化过程提取出来,将依赖关系进行解耦. 更好的扩展性,维护性.
3.2.2 工厂模式渐进
三种工程模式有一个循序渐进的过程:
对产生产品时直接判断(if else)[独立成工厂封装起来] (简单工厂)
---->对产生产品的方法进行抽象[接口类和实现类] (工厂方法)
---->对工厂进行抽象(抽象工厂)
4. 设计模式使用场景及注意
5.参考文章
内容总计于HeadFirst设计模式及相关视频