工厂与观察者模式

工厂模式介绍

通过一个加工厂,在这个工厂中添加对应材料,我们就可以得到想要的东西,在程序设计中,这种模式就叫做工厂模式,工厂生成出的产品就是某个类的实例,也就是对象。

关于工厂模式一共有三种,分别是:简单工厂模式、工厂模式、抽象工厂模式。

简单工厂模式

比如说你要生产一些物品,生产的方法都是一样的只是原材料不同。你可以设计一个基类,提供生产方法。然后将要生产的对象材料加入到生产类中即可。后面可以再定义一个对象工厂类,用来创建对应材料。

创建一个新的类, 可以将这个类称之为工厂类。对于简单工厂模式来说,需要的工厂类只有一个。工厂类中添加一个公共的成员函数,通过这个函数来创建我们需要的对象,通过这个对象调用工厂函数,这样就可以生产出一个指定类型的实例对象了。这里可以使用c++中的多态来完成。

例如:先定义一个基类,将其方法定义为虚函数。

class Product
{
public:
	Product()
	{
	  ;
	}
	virtual void produce()
	{
		cout << "进行生产" << endl;
	}
	 virtual ~Product()
	{
		 cout << "资源释放" << endl;
	}
};

定义要实例化的对象

class Milk :public Product
{
public:
	void produce()
	{
		cout << "生产了牛奶" << endl;
	}
	~Milk()
	{
		cout << "delete Milk" << endl;
	}
};

class Apple :public Product
{
public:
	void product()
	{
		cout << "生产了apple" << endl;
	}
	~Apple()
	{
		cout << "delete apple" << endl;
	}
};

定义物品工厂类,用来生产对应材料

enum class Type :char { milk,apple };
class Factory
{
public:
	Product* p = nullptr;
	Product* create(Type T)
	{
		switch (T)
		{
		case Type::milk:
			p = new Milk;
			break;
		case Type::apple:
			p = new Apple;
			break;
		default:
			break;
		}
		return p;
	}
};
int main()
{

	Factory* f = new Factory;
	Product* p = f->create(Type::milk);//需要生产材料,就对其参数进行修改
	p->produce();
	delete p;
	return 0;
}

caf69a45a766483da2fc2a1fe83f8b3c.png

 工厂类模式

如果要可以生成更多种类的物品,需要添加更多的物品对象,同时还要在工厂函数的switch语句中添加更多的case,很明显这违背了封闭原则。

简单工厂模式是只有一个工厂类,而工厂模式是有很多的工厂类。

 

  1. 一个基类,包含一个虚工厂函数,用于实现多态。
  2. 多个子类,重写父类的工厂函数。每个子工厂类负责生产某种物品,这相当于再次解耦,如果要生产新物品,那么只需要添加对应的工厂类,无需修改原有的代码。

代码:

class Product
{
public:
	
	virtual void produce()
	{
		cout << "进行生产" << endl;
	}
	virtual ~Product()
	{
		cout << "资源释放" << endl;
	}
};

class Milkpro :public Product
{
public:

	void produce()
	{
		cout << "生产了牛奶" << endl;
	}
	~Milkpro()
	{
		cout << "delete Milk" << endl;
	}
};

class Applepro :public Product
{
public:
	
	void product()
	{
		cout << "生产了apple" << endl;
	}
	~Applepro()
	{
		cout << "delete apple" << endl;
	}
};

class Factory//并没有在这个类中直接生产材料,而是定义为抽象类
{
public:
	virtual Product* creat() = 0;
	virtual ~Factory()
	{
		;
	}
};

class Milk :public Factory
{
public:
	
	Product* creat()
	{
		return new Milkpro;
	}
	~Milk()
	{
		cout << "delete Milk" << endl;
	}
};
class Apple :public Factory
{
public:
	Product* creat()
	{
		return new Applepro;
	}
	~Apple()
	{
		cout << "delete Apple" << endl;
	}
};
int main()
{
	Factory* f = new Milk;
	Product* p= f->creat();
	p->produce();
	delete p;
	return 0;	
}

27ba17f099df42d884bec8c171e88f8f.png

 抽象工厂类

假如要生产一艘船,该的组成为:

船体,船的动力系统,船中配备的武器。

船体的选择:木材 合金

动力系统的选择:人力驱动,核反应驱动

武器的选择:枪,自动机关炮

这样一共就有8种选则。

船体,因为船体材料的这个属性是可变的,所以还需要给它提供一个抽象类,在这个抽象类的子类中就可以去更换不同的船体材料。

class ShipBody
{
public:
    virtual string getShipBody() = 0;
    virtual ~ShipBody() {}
};

class WoodBody : public ShipBody
{
public:
    string getShipBody() override
    {
        return string("用<木材>制作轮船船体...");
    }
};

class MetalBody : public ShipBody
{
public:
    string getShipBody() override
    {
        return string("用<合金>制作轮船船体...");
    }
};

动力系统与武器也是一样:

// 动力
class Engine
{
public:
    virtual string getEngine() = 0;
    virtual ~Engine() {}
};

class Human : public Engine
{
public:
    string getEngine() override
    {
        return string("使用<人力驱动>...");
    }
};
class Nuclear : public Engine
{
public:
    string getEngine() override
    {
        return string("使用<核能驱动>...");
    }
};

// 武器
class Weapon
{
public:
    virtual string getWeapon() = 0;
    virtual ~Weapon() {}
};

class Gun : public Weapon
{
public:
    string getWeapon() override
    {
        return string("配备的武器是<枪>");
    }
};

class Cannon : public Weapon
{
public:
    string getWeapon() override
    {
        return string("配备的武器是<自动机关炮>");
    }
};

一首船需要3个组成部分,这里用3个变量来表示:

class Ship
{
public:
    Ship(ShipBody* body, Weapon* weapon, Engine* engine) :
        m_body(body), m_weapon(weapon), m_engine(engine)
    {
    }
    string getProperty()
    {
//      这也是多态实现,获取对应船组成部分的材料
        string info = m_body->getShipBody() + m_weapon->getWeapon() + m_engine->getEngine();
        return info;
    }
    ~Ship()
    {
        delete m_body;
        delete m_engine;
        delete m_weapon;
    }
private:
    ShipBody* m_body = nullptr;
    Weapon* m_weapon = nullptr;
    Engine* m_engine = nullptr;
};

工厂类与上面一样,不直接进行提供船部件,而是定义为抽象类,让子类去提供船的部件。

/ 工厂类
class AbstractFactory
{
public:
    virtual Ship* createShip() = 0;
    virtual ~AbstractFactory() {}
};

class BasicFactory : public AbstractFactory//定义木头,枪,人力的船
{
public:
    Ship* createShip() override
    {
        Ship* ship = new Ship(new WoodBody, new Gun, new Human);
        cout << "<基础型>战船生产完毕, 可以下水啦..." << endl;
        return ship;
    }
};

 结果:

int main()
{
    AbstractFactory* factroy = new BasicFactory;
    Ship* ship = factroy->createShip();
    cout << ship->getProperty();
    delete ship;
    delete factroy;
    return 0;
}

3a2868f99e6b4a99ba5b927555b4d37f.png

对比:

  • 简单工厂模式不能遵守开放-封闭原则,该工厂类没有设置为抽象类,要在该类中直接添加生产对象。
  • 工厂模式创建的对象  对应的类不需要提供抽象类,需要创建什么对象,直接提供对应的子类
  • 抽象工厂模式创建的对象  对应的类有抽象的基类,创建的对象有多种不同的组合方法。

观察者模式

一个简单的例子:交叉路口的红绿灯。过往的车辆就是观察者或则是订阅者,信号灯就是消息的发布者。当车辆到了该路口,车辆就会观测路灯,当路灯为红灯时,车辆即可通行。当车辆远离该路口时,车辆就不需要观察路灯的信号了。

其他例子:购买的商品被送到菜鸟驿站,会收到驿站发送的提示信息。

这里以报刊为例,报刊可以发布多种类型的消息给不同的人。

发布者,需要满足以下的需求:

  • 添加订阅者,将所有的订阅者存储起来
  • 删除订阅者,将其从订阅者列表中删除
  • 将消息发送给订阅者(发通知)

发布者

发布者未必是一种类型的,不同的发布者可以发布不同种类的消息。先创建出一个发布者的抽象类。

class Observer;//订阅者抽象类

class NewsAgency//发布者抽象类
{
public:
    void attach(Observer* ob)
    {
        m_list.push_back(ob);//增加订阅者
    }
    void deatch(Observer* ob)
    {
       m_list.remove(ob);//删除订阅者
    }
    virtual void notify(string msg) = 0;//通知
    virtual ~NewsAgency() {};
protected:
    list m_list;   // 订阅者列表
};

class News_A :public NewsAgency
{
public:
    void notify(string msg) override
    {
        cout << "这是NewA新闻报刊" << endl;
        for (auto ch : m_list)
        {
            ch->update(msg);
        }
    }
};
class News_B :public NewsAgency
{
public:
    void notify(string msg) override
    {
        cout << "这是NewB新闻报刊" << endl;
        for (auto ch : m_list)
        {
            ch->update(msg);
        }
    }
};

订阅者

观察者也未必只是一种对象,给所有的观察者定义一个抽象的基类。

// 抽象的订阅者类
class Observer
{
public:

  //通过构造函数给观察者类提供一个信息的发布者 
    Observer(string name, NewsAgency* news) :m_name(name), m_news(news) 
    {
        m_news->attach(this);//发布者对象将观察者对象存储了起来,可以收到发布的消息
    }
    void unsubscribe()
    {
        m_news->deatch(this);//订阅者取消订阅
    }
    virtual void update(string msg) = 0;
    virtual ~Observer() {}
protected:
    string m_name;
    NewsAgency* m_news;
};

class Observer_A : public Observer//订阅者A
{
public:
    using Observer::Observer;
    void update(string msg) override
    {
        cout << "订阅者A收到新消息: " << msg << endl;
    }
};

class Observer_B : public Observer//订阅者B
{
public:
    using Observer::Observer;
    void update(string msg) override
    {
        cout << "订阅者B收到新消息: " << msg << endl;
    }
};

过程

int main()
{

    News_A* New_a = new News_A;
    News_B* New_b = new News_B;
 
    Observer_A* obser_a = new Observer_A("observer_A",New_a);
    Observer_B* obser_b = new Observer_B("observer_B",New_b);


    New_a->notify("明天会下雨哦*************");
    New_b->notify("明天广场会进行发布会活动,请大家参加");

    return 0;
}

 

 

你可能感兴趣的:(C++入门学习,观察者模式)