⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ood.txt

📁 ears-0.32, linux下有用的语音信号处理工具包
💻 TXT
📖 第 1 页 / 共 3 页
字号:
    -----------------furnace.c-------------    #include "furnace.h"    #define THERMOMETER 0x86    #define FURNACE     0x87    #define FURNACE_ON  0x01    #define FURNACE_OFF 0x00    double ReadTemp()     {return in(THERMOMETER);}    void   StartFurnace() {out(FURNACE, FURNACE_ON);}    void   StopFurnace()  {out(FURNACE, FURNACE_OFF);}However, while this does break the direct dependency of the Furnacefunction upon the details, there is still a one to one binding fromthe name 'StartFurnace' to the function implemented in "furnace.h".Thus, although we can some reusability by recoding "furnace.c", wecannot gain reusability in the same program or application.However, consider the following object oriented design.    -----------furnace.h-------------    class Furnace    {      public:        virtual void Start() = 0;        virtual void Stop() = 0;    };    ---------thermometer.h----------    class Thermometer    {      public:        virtual double Read() = 0;    };    ------------ regulator.h ------------    class Furnace;    class Thermometer;    class Regulator    {      public:        Regulator(Furnace& f, Thermometer& t);        void Regulate(double minTemp, double maxTemp);      private:        Furnace& itsFurnace;        Thermometer& itsThermometer;    };    ---------------- regulator.cc ------------    #include "regulator.h"    #include "furnace.h"    #include "thermometer.h"    Regulator::Regulator(Furnace& f, Thermometer& t)    : itsFurnace(f)    , itsThermometer(t)    {}    void Regulator::Regulate(double minTemp, double maxTemp)    {        while(;;)        {            while (itsThermometer.Read() > theMinTemp)                wait(1);            itsFurnace.Start();            while (itsThermometer.Read() < theMaxTemp)                wait(1);            itsFurnace.Stop();        }    }    -------------------detailedFurnace.h---------------------    #include "furnace.h"    class DetailedFurnace : public Furnace    {      public:        virtual void Stop();        virtual void Start();    };    -------------------detailedFurnace.cc-------------------    #define FURNACE     0x87    #define FURNACE_ON  0x01    #define FURNACE_OFF 0x00    void   DetailedFurnace::Start() {out(FURNACE, FURNACE_ON);}    void   DetailedFurnace::Stop()  {out(FURNACE, FURNACE_OFF);}    -----------detailedThermometer.h --------------    class DetailedThermometer : public Thermometer    {      public:        virtual double Read();    };    ------------detailedThermometer.cc-------------    #define THERMOMETER 0x86    double DetailedThermometer::Read() {return in(THERMOMETER);}    -------------------------------------------------------------Notice that now the high level algorithm depends only upon abstractclasses.  Notice also that the details depend only upon theabstractions.  Notice that the Regulator class can be reused with anyderivative of a Furnace and a Thermometer.  Morever, any applicationcan have many instance of Regulators, Thermometers, and Furnaces.Thus, we could reuse this algorithm in, say, an application thatcontrols the reaction temperature of many different vessels....Notice also that there is much more code in the OO version.  It takescode to invert dependencies.  This is the price we pay for the reusabilityand maintainability that dependency inversion affords.--------------------------------------------------------------------   4. The granule of reuse is the same as the granule of release.      Only components that are released through a tracking system can      be effectively reused.--------------------------------------------------------------------Reuse does not come automatically.  One cannot simply write a classand claim that it is reusable.  First, a reusable class probably hasseveral classes that it collaborates with.  Thus the class is notreusable in isolation, it must be reused in conjunction with otherclasses.  Second, reusers do not want the classes that they arereusing to change out from under them.  So they will require some kindof release tracking system to be put into place.It should be stated at this point that "code copying" is an inferiorform of code reuse.  Code copying puts the burden of maintenance uponthe reuser, not upon the author.  In such cases, the only thing thatis being reused is the initial design of the code.  Yet we all knowthat initial design is worth a small percentage of the total effortthrough the lifecycle of a project.  Thus we want reusable code to bemaintained by the author, or by a common maintainer.  We want all thereusers to benefit from the single source of maintenance.In order to achieve reuse of this kind, the reusable software must beput into a form that the reusers can manage.  Specifically, this meansthat it must be segregated into "chunks" which are relativelyindependent of each other, and given version numbers so that thereusers can track which version of a chunk they are currently using.The chunks must be small enough so that reusers can pick and choosethe software that they want to reuse.  Reuse is not worth much when itis an all-or-nothing proposition.When changes are made to these released "chunks", new version numbersmust be assigned, and notification must be given to all reusers.Reusers will then decide if they wish to use the new releaseimmediately, delay such use until their software can be madecompatible, or reject such use and take over maintenance of theprevious version themselves.In the absence of a release strategy and version numbering scheme,reuse of commonly maintained software modules is extremely difficult,if not impossible.  Thus, we say that "the granule of reuse is thesame as the granule of release."Now this has implications for the way that object oriented programsshould be structured.   One such structuring mechanism is employed byBooch.  He organizes a group of cohesive classes into an entity calleda class category.  Class categories can be used as the granule ofrelease, and therefore the granule of reuse.--------------------------------------------------------------------   5. Classes within a released component should share common closure.      That is, if one needs to be changed, they all are likely to need      to be changed.  What affects one, affects all.  (The principle      of Common Closure).--------------------------------------------------------------------Released components are the targets for dependencies.  In fact, thereason that they are "released" is to limit the affect of changes uponthe users of the component.  This implies that releases should notoccur often, and that they should occur in isolation where possible.The worst case scenario is when a change to the system causesmodification of all the released components, such that they all needto be re-released.  When changes occur, we want those changes toaffect the smallest possible number of released components.In OOD, the released coponent is the "category".  And the principle weare discussing is the principle of "Common Closure within Categories."This priciple is the first and most important of the three rules forcategory cohesion.  A category is cohesive, if the classes within itare all closed to the same kinds of modifications.The open closed principle states that a class should be open forextension but closed for modification.  This is an ideal that cannotbe completely achieved.  Regardless of the design of a class, therewill always exist some kind of change that will force the class to beopened.  However, do not have to protect ourselves from every kind ofmodification.  We can anticipate the kinds of modifications that arelikely to be requested, and protect ourselves from those.Thus, we design our classes to be closed to the most likely kinds ofchanges that we can forsee.  This means that the closure of a class ispartial, and specifically targeted at certain kinds of changes.The principle of common closure states that, given a particular kindof change, either all of the classes within a category are closed toit, or they are all open to it.When this principle can be achieved, changes do not propogate throughthe system.  Rather they focus upon one, or a few categories, whilethe rest of the categories remain unaffected.  This greatly lessensthe number of categories that are affected by a change, and reducesthe frequency with which categories must be released.--------------------------------------------------------------------   6. Classes within a released componen should be reused together.      That is, it is impossible to separate the components from each      other in order to reuse less than the total.--------------------------------------------------------------------When a user decides to reuse a component, he creates a dependency uponthe whole component.  When a new release of that component is created, theuser must reintroduce that new release into his existing applications.Therefore, the user will want each component to be as focused aspossible.  If the component contains classes which the user does notmake use of, then the user may be placed in the position of acceptingthe burden of a new release which does not affect any of the classeswithin the component that he is using.   Thus, comoponents should bekept relatively narrow.  If the user uses one of the classes in thecomponent, then it should be extremely likely that he should reuseall the other classes in the component.Generally, this kind of focus is enforced by the relationships thatexist between classes that are reused together.  Those relatioshipsrepresent dependencies that force the user to bring along all theclasses within a component.It is important that dependencies that are associated with reuse beencapsulated within a single component where possible.  If the reuseof a particular class within a component forces the reuse of othercomponents, then the user has a bigger reuse burden.--------------------------------------------------------------------   7. The dependency structure for released components must be a DAG.      There can be no cycles.--------------------------------------------------------------------Consider an application that is divided up into many different classcategories.  A given class category can be released, only when it iscompatible with those categories that it depends upon.This ability to release an application in peices facilitatesdevelopment.  If applications cannot be released in pieces, then thedevelopers interfere with each other as they are making changes totheir code.The typical horror story is of an engineer who works all day to gethis stuff working.  He goes home a night satisfied.  However uponreturning the next morning, he is dismayed to find that his stuff nolonger works.  The reason:  Sombody stayed later than he did andchanged something that he depended upon.If this happened only once in a while, it would not be so bad, but inlarge projects it can happen on a daily (even hourly) basis.  Thus weneed a way to release the application in pieces so that developers canchoose to depend upon older releases of the categories that theydepend upon.However, when there are dependency cycles, then this rational schemefor developing applications breaks down.  All of the categories withinthe cycle must be released simultaneously.Consider the following diagram:                  +---------------+                  | Control Panel |                  +---------------+                     / 	     \	   +-----------+     +---------+           | Transport |     | Revenue |           +-----------+     +---------+	    /       \               \   +----------+ +----------+   +----------+   | Elevator | | Conveyor |   | Database |   +----------+ +----------+   +----------+       	     \ 	  /	   +-------+

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -