Интернет магазин китайских планшетных компьютеров



Компьютеры - Внедрение зависимости - Примеры кода

23 января 2011


Оглавление:
1. Внедрение зависимости
2. Примеры кода
3. Существующие фреймворки



Представим, что IFoo это общий класс, определяющий свой интерфейс:

  class IFoo:
        def do_bar:
            "perform bar"
        def do_baz:
            "perform baz"

Также есть несколько реализаций, которые реализуют IFoo по-разному:

  class DatabaseFoo:
        interface.implements
        def do_bar:
            db.select_bar.execute # Использовать базу данных, чтобы сделать bar
        def do_baz:
            db.select_baz.run # Использовать базу данных, чтобы сделать baz
 
  class PixieDustFoo:
        interface.implements
        def do_bar:
            cast_spell # Магия...
        def do_baz:
            cast_spell # ...и волшебство
 
  class EnterpriseFoo:
        interface.implements
        def do_bar:
            bar = EnterpriseFactoryObserverFactoryCreator
            bar.creatify
            bar.preparify
            bar.configurise
            bar.make_award_winning
            bar.opportunities.leverage
        def do_baz:
            baz = EnterpriseFactoryObserverFactoryCreator
            baz.creatify
            baz.preparify
            baz.configurise
            baz.make_award_winning
            baz.opportunities.leverage

IFoo определяет только операции, которые доступны в интерфейсе, но не предоставляет никакой их реализации, позволяя другим классам реализовывать методы, в нем определенные. Поэтому пользователь, желающий использовать функционал IFoo, может использовать любую реализацию, не имея никакого понятия о том, как оно работает, кроме того, что они соответствуют спецификации интерфейса Foo.

  class ImportantClass:
        def __init__:
            self.foo = EnterpriseFoo
        def do_really_important_stuff:
            self.foo.do_bar # оно ничего не делает!

Хотя, это подрывает весь смысл использования интерфейсов вместо конечных реализаций. Чтобы исправить ситуацию, достаточно предоставить вызывающей стороне возможность указывать ту реализацию IFoo, которую она посчитает нужным:

        def __init__:
            self.foo = foo

При использовании внедрения зависимостей, как правило, существует конфигурационный механизм или архитектура, которая определяет целесообразность выбора той или иной реализации в зависимости от поставленных целей.

Пример кода на Java

public interface ICar {
    public float getSpeed;
    public void setPedalPressure;
}
 
public interface IEngine {
    public float getEngineRotation;
    public void setFuelConsumptionRate;
}


Без использования dependancy injection

public class DefaultEngineImpl implements IEngine {
    private float engineRotation = 0;
 
    public float getEngineRotation {
        return engineRotation;
    }
 
    public void setFuelConsumptionRate {
        engineRotation = …;
    }
}
 
public class DefaultCarImpl implements ICar {
    private IEngine engine = new DefaultEngineImpl;
 
    public float getSpeed {
        return engine.getEngineRotation*…;
    }
 
    public void setPedalPressure {
        engine.setFuelConsumptionRate;
    }
}
 
public class MyApplication {
    public static void main {
        ICar car = new DefaultCarImpl;
        car.setPedalPressure;
        float speed = car.getSpeed;
        System.out.println;
    }
}


Dependency injection вручную

public class DefaultCarImpl implements ICar {
    private IEngine engine;
 
    public DefaultCarImpl {
        engine = engineImpl;
    }
 
    public float getSpeed {
        return engine.getEngineRotation*…;
    }
 
    public void setPedalPressure {
        engine.setFuelConsumptionRate;
    }
}
 
public class CarFactory {
    public static ICar buildCar {
        return new DefaultCarImpl);
    }
}
 
public class MyApplication {
    public static void main {
        ICar car = CarFactory.buildCar;
        car.setPedalPressure;
        float speed = car.getSpeed;
        System.out.println;
    }
}


Dependency injection при помощи фреймворка

    <service-point id="CarBuilderService">
        <invoke-factory>
            <construct class="Car">
                <service>DefaultCarImpl</service>
                <service>DefaultEngineImpl</service >
            </construct>
        </invoke-factory>
    </service-point>
/** Implementation not shown **/
 
public class MyApplication {
    public static void main {
        Service service = DependencyManager.get;
        ICar car = service.getService;
        car.setPedalPressure;
        float speed = car.getSpeed;
    }
}




Просмотров: 2780


<<< Аспектно-ориентированная разработка программного обеспечения
Домен приложения >>>