当前位置: 代码迷 >> 综合 >> Head First 设计模式 Design Pattern 3-4 Decorator, Factory
  详细解决方案

Head First 设计模式 Design Pattern 3-4 Decorator, Factory

热度:30   发布时间:2023-12-20 11:25:56.0

Section 3 装饰者模式 Decorator 

开放-关闭原则, 只在必须的地方使用开放-关闭原则, 否则增加复杂度, 代码阅读性变差

设计原则 类应该对扩展开放, 对修改关闭

>装饰者和被装饰者对象有相同的超类型 >可以用一个或者多个装饰者包装一个对象 >可以用被装饰过的对象代替原始对象

>装饰者可以在所委托被装饰者的行为之前/后加上自己的行为 >运行时可装饰

装饰者模式 动态地将责任附加到对象上. 对于扩展功能, 提供了比继承更有弹性的方案.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
//***********Decorator***********
class Beverage
{
public:
    Beverage();
    virtual string getDescription();
    virtual void setDescription(string des);
    virtual double cost() = 0;
                                                                                                             
private:
    string msDes;   
};
                                                                                                         
class CondimentDecorator : public Beverage
{
public:
    virtual string getDescription() = 0;   
};
                                                                                                         
class Espresso : public Beverage
{
public:
    Espresso() { setDescription("Espresso");}
    double cost() { return 1.99;}
};
                                                                                                         
class HouseBeld : public Beverage
{
public:
    HouseBeld() { setDescription("HouseBeld");}
    double cost() { return .89;}
};
                                                                                                         
class Mocha : public CondimentDecorator
{
public:
    Mocha(Beverage* beverage);
    string getDescription();
    double cost();
private:
    Beverage* mBeverage;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
//***********Decorator***********
Beverage::Beverage()
:msDes("UnKnow")
{}
                                                                                                         
string Beverage::getDescription()
{
    return msDes;
}
                                                                                                         
void Beverage::setDescription(string des)
{
    msDes = des;
}
                                                                                                         
Mocha::Mocha(Beverage *b)
: mBeverage(b)
{}
                                                                                                         
string Mocha::getDescription()
{
    return mBeverage->getDescription() + ", Mocha";
}
                                                                                                         
double Mocha::cost()
{
    return .20 + mBeverage->cost();
}
1
2
3
4
5
6
7
//Decorator
Beverage* beverageE = new Espresso();
cout << beverageE->getDescription() << beverageE->cost() << endl;
Beverage* beverage1 = new HouseBeld();
beverage1 = new Mocha(beverage1);
beverage1 = new Mocha(beverage1);
cout << beverage1->getDescription() << beverage1->cost() << endl;

Summary

>OO原则 对扩展开放, 对修改关闭 >OO模式 动态地将责任附加到对象上, 扩展功能, 有别于继承

>要点 继承属于扩展之一, 不一定是弹性设计最佳方案; 允许行为被扩展, 但无需修改现有代码; 组合和委托可用于在运行时动态加载; 扩展行为, 装饰者和继承; 

一群装饰类, 用来包装具体组件; 装饰者类反映出被装饰的组件类型(相同类型); 装饰者可以在被装饰者的行为前面或后面加上自己的行为, 甚至取代被装饰者的行为;

可以用无数装饰者包装一个组件; 装饰者一般对组件的客户是透明的; 装饰者会导致设计中出现很多小对象, 过度使用会使程序复杂化;

---Section 3 End---


Section 4 工厂方法和抽象工厂 Factory

封装创建对象的代码, 工厂Factory负责处理创建对象的细节

>静态工厂不需要使用创建对象的方法来实例化对象, 但是不能通过继承来改变创建方法的行为

>定义简单工厂 -解耦 Decouple -允许子类做决定
>声明一个工厂方法 处理对象的创建, 将这类行为封装在子类中 ex: abstract Product factoryMethod(String type);

>封装对象的创建, 让子类决定创建的对象是什么.

平行的类层次  产品类 Pizza 创建者类 PizzaStore

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

>封装具体类型的实例化    

设计原则 要依赖抽象, 不要依赖具体类
>PizzaStore 和 Pizza 都依赖了 IPizza抽象

>依赖倒置原则 Dependency Inversion Principle: 

变量不可以持有具体类的引用; 不要让类派生自具体类; 不要覆盖基类中已实现的方法; 

>原料工厂 通过抽象工厂所提供的接口, 创建产品的家族, 利用接口实现代码, 从实际的工厂解耦, 可实现多种工厂制造不同产品

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

> 抽象工厂允许客户使用抽象的接口来创建一组产品, 不需要知道实际生产出来的产品是什么, 实现解耦


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
class IPizza
{
public:
    virtual void prepare() = 0;
protected:
    string mName;
    ICheese* mCheese;
};
       
class SimplePizzaFactory // simple factory
{
public:
    IPizza* createPizza(string type);
};
       
class CheesePizza : public IPizza
{
public:
    CheesePizza(IPizzaIngredientFactory* pIngredientFactory);
    void prepare();
           
private:
    IPizzaIngredientFactory* mpIngredientFactory;
};
       
class NYCheesePizza : public IPizza
{
public:
    NYCheesePizza(IPizzaIngredientFactory* pIngredientFactory);
    void prepare();
       
private:
    IPizzaIngredientFactory* mpIngredientFactory;
};
       
class PizzaStore
{
public:
    PizzaStore(SimplePizzaFactory* pSPFactory);
    IPizza* orderPizza(string type);
           
protected:
    virtual IPizza* createPizza(string type) = 0;
           
private:
    SimplePizzaFactory* mpSPFactory;
};
       
class NYStylePizzaStore : public PizzaStore // Have dependency on Pizza
{
public:
    NYStylePizzaStore(SimplePizzaFactory* pSPFactory = NULL);
    IPizza* createPizza(string type);
};
       
class ICheese
{
public:
    string getName() const;
protected:
    string mName;
};
       
class Cheese : public ICheese
{
public:
    Cheese() { mName = "cheese"; }
};
       
class NYCheese : public ICheese
{
public:
    NYCheese() { mName = "NY cheese";}
};
       
class IPizzaIngredientFactory // abstract factory
{
public:
    virtual ICheese* createCheese() = 0;
};
       
class PizzaIngredientFactory : public IPizzaIngredientFactory
{
public:
    virtual ICheese* createCheese();
};
       
class NYPizzaIngredientFactory : public IPizzaIngredientFactory
{
public:
    virtual ICheese* createCheese();
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
IPizza* SimplePizzaFactory::createPizza(string type)
{
    cout << "SimplePizzaFactory createPizza" << endl;
    IPizza* pPizza = NULL;
    if (type.compare("cheese") == 0)
        pPizza = new CheesePizza(new PizzaIngredientFactory());
       
    return pPizza;
}
       
CheesePizza::CheesePizza(IPizzaIngredientFactory* pIngredientFactory)
: mpIngredientFactory(pIngredientFactory)
{
    mName = "Cheese Pizza";
}
       
void CheesePizza::prepare()
{
    mCheese = mpIngredientFactory->createCheese();
    cout << mName << " prepare" << endl;
    cout << mCheese->getName() << " ready" << endl;
}
       
NYCheesePizza::NYCheesePizza(IPizzaIngredientFactory* pIngredientFactory)
: mpIngredientFactory(pIngredientFactory)
{
    mName = "NY CheesePizza";
}
       
void NYCheesePizza::prepare()
{
    mCheese = mpIngredientFactory->createCheese();
    cout << mName << " prepare" << endl;
    cout << mCheese->getName() << " ready" << endl;
}
       
PizzaStore::PizzaStore(SimplePizzaFactory* pSPFactory)
: mpSPFactory(pSPFactory)
{
}
       
IPizza* PizzaStore::orderPizza(string type)
{
    IPizza *pPizza = NULL;
    if(mpSPFactory != NULL)
        pPizza = mpSPFactory->createPizza(type);
    else
        pPizza = createPizza(type);
    pPizza->prepare();
}
       
NYStylePizzaStore::NYStylePizzaStore(SimplePizzaFactory* pSPFactory)
: PizzaStore(pSPFactory)
{
}
       
IPizza* NYStylePizzaStore::createPizza(string type)
{
    cout << "NYStylePizzaStore createPizza" << endl;
    IPizza* pPizza = NULL;
    if (type.compare("cheese") == 0)
        pPizza = new CheesePizza(new NYPizzaIngredientFactory());
        //pPizza = new NYCheesePizza(new NYPizzaIngredientFactory());
           
    return pPizza;
}
       
string ICheese::getName() const
{
    return mName;
}
       
ICheese* PizzaIngredientFactory::createCheese()
{
    return new Cheese();
}
       
ICheese* NYPizzaIngredientFactory::createCheese()
{
    return new NYCheese();
}
1
2
3
4
PizzaStore *pNYSPStore = new NYStylePizzaStore();
pNYSPStore->orderPizza("cheese");
pNYSPStore = new NYStylePizzaStore(new SimplePizzaFactory());
pNYSPStore->orderPizza("cheese");

Summary

>OO原则 依赖抽象, 不要依赖具体类 

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

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

>要点 所有的工厂都是用来封装对象的创建; 简单工厂, 不是真正的设计模式, 但可以作为一个简单方法把客户程序从具体类解耦; 工厂方法用继承: 把对象的创建委托给子类, 

子类实现工厂方法来创建对象; 抽象工厂使用对象组合: 对象的创建被实现在工厂接口所暴露出来的方法中; 所有的工厂模式都通过减少应用程序和具体类之间的依赖促进松耦合;

工厂方法允许类将实例化延迟到子类进行; 抽象工厂创建相关的对象家族, 不需要依赖他们的具体类; 依赖倒置原则, 指导我们避免依赖具体类型, 尽量依赖抽象; 

工厂帮助我们针对抽象编程, 不要针对具体类编程;

ConcreteCreator, SubClass, ConceteFactory, Implementation, FactoryMethod, Dependent, Encapsulate, ObjectComposition, SimpleFactory

---Section 4 End---

  相关解决方案