Loose coupling and shuffling dependencies

I have a bunch of classes that look something like this:

public class MyGame()
{
    private Graphics graphics;

    private Player player;

    public MyGame()
    {
        graphics = new Graphics();
        //...
    }

    protected void Initialize()
    {
        player = new Player();
        //...
    }

    protected void Update()
    {
        player.DoStuff();
        //...
    }

I’ve been reading about design patterns, and I’ve come to understand that this is not a very good design because it isn’t loosely coupled. Instead of coding to interfaces, I’m coding to implementations (Graphics, Player, etc.).

In order to fix this perceived problem, I start by changing those dependencies to interfaces:

public class MyGame()
{
    private IGraphics graphics;

    private IPlayer player;

    public MyGame()
    {
        graphics = new Graphics();
        //...
    }

    protected void Initialize()
    {
        player = new Player();
        //...
    }

I’m not sure how helpful that really is, but it’s nice that the graphics field (for example) isn’t tied to the Graphics class – I can use the AwesomeGraphics class or SparklyGraphics class instead as long as those classes implement IGraphics.

But I still have hard dependencies on Graphics and Player, so what was the point of all that refactoring? (My actual code is much more complicated.) I’ve also come to understand that dependency injection is a good idea, so that’s what I try to do next:

public class MyGame()
{
    private IGraphics graphics;

    private IPlayer player;

    public MyGame( IGraphics graphics, IPlayer player )
    {
        this.graphics = graphics;
        this.player = player;
        //...
    }

This looks really nice because I no longer have any hard dependencies in MyGame. However, the dependencies are still in my code – they’ve just been moved to the class that instantiates MyGame:

static class Program
{
    static void Main( string[] args )
    {
        using ( var game = new Game( new Graphics(), new Player() )
        {
            game.Run();
        }
    }
}

Now I’m back where I started! This class is not loosely coupled at all! So, again, what was the point of all that refactoring? I’m pretty sure I could use an IoC container to take care of these dependencies somehow, but that would likely just add a ton of complication to an already complicated project. Plus, wouldn’t that just be moving those dependencies once again to another class?

Should I stick with what I had in the first place, or is there some tangible benefit that I’m not seeing yet?

6

You have gained the benefits of loose coupling in your refactoring. You’ve moved the knowledge of the precise implementation outside of your MyGame class and into a higher-level class. This is good: by keeping all knowledge of what the precise implementations are together, you’re improving the structure of your code, making it easier for high level changes to take place, and making it easier to make changes that involve, for example, using multiple implementations of your Player class (perhaps by introducing a NetworkPlayer or AIPlayer later). MyGame now has one fewer reason to change, so is closer to having a single responsibility, and the Single Responsibility Principle is now considered one of the most important in object-oriented design by many programmers.

Eventually, all code has to depend on a concrete implementation, whether that’s specified in code or some sort of DI framework configuration file. The benefit of depending on an interface is that you can more easily depend on multiple concrete implementations, as the situation calls for.

However, those benefits aren’t actually realized until you actually have multiple concrete implementations. Most frequently, the second concrete implementation is a mock object used in unit testing. It could also be things like multiple target platforms. For example, I have a project that depends on interfaces for the UI so I can substitute concrete implementations for either Swing or Android. It’s common to have interfaces for multiple databases or operating system-specific functionality.

If you don’t ever have that second implementation, you aren’t actually receiving any tangible benefit. You just have a future assurance that if you ever need a second implementation, it will be easier to integrate. It’s like owning non-dividend stock. It’s worth something on paper, but you don’t get any real benefit until you actually sell it.

At the program level, there will always be a point at which a decision needs to be made which concrete implementations of IGraphics and IPlayer will be given to Game. This is what you’re seeing here.

The point of your work is that you’ve moved the decision out of Game itself, so it isn’t tightly coupled to any particular implementations, and left it to your higher level program code to decide.

This means that Game is much more flexible (as are IGraphics, and IPlayer), and your program is now made up of freely composable units instead of one inflexible hierarchical unit.

It may not seem like a big deal with such a simple contrived example, but once you get even a little bit more complex, the composability becomes much more beneficial.

You certainly have gained substantial benefit from changing the structure.

When coding new systems or fairly stable systems implementing design patterns can seem like a waste of effort and time since it didn’t make your life easier right now.

Consider that the Graphics object you were using originally was developed for rendering 2D graphics and does all kinds of logic under the covers to make development easier. Later on your game grows and now needs to start doing some 3D graphics, normally you would start by inheriting from Graphics, only 2D graphics while it may have some similar methods such as Render(), Refresh(), or Invalidate() has nothing to do with 3D graphics.

By opening up several SIMPLE interfaces for Graphics you open the door to much more flexibility in your code.

As an example of the strategy pattern (dependency inversion) and coding to interfaces:

MyGame requires several things to function.

It needs our Render(), Refresh(), Invalidate(). (IGraphics)
It needs additional 3D methods such as Transform(), Rotate() . (IGraphicsManipulations3D)

And if those multiple interfaces make sense to be lumped together for something you can make a combined interface

public interface IGraphics3D : IGraphics, IGraphicsManipulations3D

so now instead of saying you need a SPECIFIC graphics implementation you just need some object that does the basic things, you could even swap in completely different rendering engines if you wanted to.

public class UnityEngineGraphics : IGraphics3D

or

public class HavokEngineGraphics : IGraphics3D

But your game doesn’t care one bit.

public class MyGame(IGraphics3D, IPlayer)

The important thing to note and most likely where you find it difficult to see value is that these circumstances tend to come up later rather than sooner and when you are building the MyGame you are fully intent on using one implementation of the graphics object. Never forget that requirements change, sometimes for good, sometimes for headaches and design patterns are THE way to be preemptive.

In this example:

public MyGame( IGraphics graphics, IPlayer player )

the statement:

However, the dependencies are still in my code

is not correct. The are no dependencies because now the class is tied to a contract and not an implementation.

In some cases it is not necessary to be loosely coupled. For example, the player class may not be a good candidate to be loosely coupled if it just contains properties or core logic.

Let’s take a look at a better example, let’s say your game uses a 3rd party ranking engine to rank players.

So your constructor may look like this:

public MyGame( IRankingProvider Provider )

Now you can swap out different implementations of a ranking provider rather easily, your code may have 3 or 4 implementations depending on what platform the game is running on.

Also, for unit testing you can create a fake Provider to unit test the logic on MyGame without any external ranking provider dependencies. This makes it easy to run all the unit tests on a development/build machine without installing/setting up any of the providers.

Now eventually on a development/deployment server one would want to perform integration tests using actual providers to ensure the implementation are correct, in those cases the test fixture would inject a real implementation.

So, the main benefits are:

  1. Increased testability
  2. Ability to switch out implementations or use multiple implementations
  3. Removal of dependencies

One should choose carefully which parts of the system are loosely coupled. In some cases it is not needed and when employed causes a needless layer of abstraction.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa

Loose coupling and shuffling dependencies

I have a bunch of classes that look something like this:

public class MyGame()
{
    private Graphics graphics;

    private Player player;

    public MyGame()
    {
        graphics = new Graphics();
        //...
    }

    protected void Initialize()
    {
        player = new Player();
        //...
    }

    protected void Update()
    {
        player.DoStuff();
        //...
    }

I’ve been reading about design patterns, and I’ve come to understand that this is not a very good design because it isn’t loosely coupled. Instead of coding to interfaces, I’m coding to implementations (Graphics, Player, etc.).

In order to fix this perceived problem, I start by changing those dependencies to interfaces:

public class MyGame()
{
    private IGraphics graphics;

    private IPlayer player;

    public MyGame()
    {
        graphics = new Graphics();
        //...
    }

    protected void Initialize()
    {
        player = new Player();
        //...
    }

I’m not sure how helpful that really is, but it’s nice that the graphics field (for example) isn’t tied to the Graphics class – I can use the AwesomeGraphics class or SparklyGraphics class instead as long as those classes implement IGraphics.

But I still have hard dependencies on Graphics and Player, so what was the point of all that refactoring? (My actual code is much more complicated.) I’ve also come to understand that dependency injection is a good idea, so that’s what I try to do next:

public class MyGame()
{
    private IGraphics graphics;

    private IPlayer player;

    public MyGame( IGraphics graphics, IPlayer player )
    {
        this.graphics = graphics;
        this.player = player;
        //...
    }

This looks really nice because I no longer have any hard dependencies in MyGame. However, the dependencies are still in my code – they’ve just been moved to the class that instantiates MyGame:

static class Program
{
    static void Main( string[] args )
    {
        using ( var game = new Game( new Graphics(), new Player() )
        {
            game.Run();
        }
    }
}

Now I’m back where I started! This class is not loosely coupled at all! So, again, what was the point of all that refactoring? I’m pretty sure I could use an IoC container to take care of these dependencies somehow, but that would likely just add a ton of complication to an already complicated project. Plus, wouldn’t that just be moving those dependencies once again to another class?

Should I stick with what I had in the first place, or is there some tangible benefit that I’m not seeing yet?

6

You have gained the benefits of loose coupling in your refactoring. You’ve moved the knowledge of the precise implementation outside of your MyGame class and into a higher-level class. This is good: by keeping all knowledge of what the precise implementations are together, you’re improving the structure of your code, making it easier for high level changes to take place, and making it easier to make changes that involve, for example, using multiple implementations of your Player class (perhaps by introducing a NetworkPlayer or AIPlayer later). MyGame now has one fewer reason to change, so is closer to having a single responsibility, and the Single Responsibility Principle is now considered one of the most important in object-oriented design by many programmers.

Eventually, all code has to depend on a concrete implementation, whether that’s specified in code or some sort of DI framework configuration file. The benefit of depending on an interface is that you can more easily depend on multiple concrete implementations, as the situation calls for.

However, those benefits aren’t actually realized until you actually have multiple concrete implementations. Most frequently, the second concrete implementation is a mock object used in unit testing. It could also be things like multiple target platforms. For example, I have a project that depends on interfaces for the UI so I can substitute concrete implementations for either Swing or Android. It’s common to have interfaces for multiple databases or operating system-specific functionality.

If you don’t ever have that second implementation, you aren’t actually receiving any tangible benefit. You just have a future assurance that if you ever need a second implementation, it will be easier to integrate. It’s like owning non-dividend stock. It’s worth something on paper, but you don’t get any real benefit until you actually sell it.

At the program level, there will always be a point at which a decision needs to be made which concrete implementations of IGraphics and IPlayer will be given to Game. This is what you’re seeing here.

The point of your work is that you’ve moved the decision out of Game itself, so it isn’t tightly coupled to any particular implementations, and left it to your higher level program code to decide.

This means that Game is much more flexible (as are IGraphics, and IPlayer), and your program is now made up of freely composable units instead of one inflexible hierarchical unit.

It may not seem like a big deal with such a simple contrived example, but once you get even a little bit more complex, the composability becomes much more beneficial.

You certainly have gained substantial benefit from changing the structure.

When coding new systems or fairly stable systems implementing design patterns can seem like a waste of effort and time since it didn’t make your life easier right now.

Consider that the Graphics object you were using originally was developed for rendering 2D graphics and does all kinds of logic under the covers to make development easier. Later on your game grows and now needs to start doing some 3D graphics, normally you would start by inheriting from Graphics, only 2D graphics while it may have some similar methods such as Render(), Refresh(), or Invalidate() has nothing to do with 3D graphics.

By opening up several SIMPLE interfaces for Graphics you open the door to much more flexibility in your code.

As an example of the strategy pattern (dependency inversion) and coding to interfaces:

MyGame requires several things to function.

It needs our Render(), Refresh(), Invalidate(). (IGraphics)
It needs additional 3D methods such as Transform(), Rotate() . (IGraphicsManipulations3D)

And if those multiple interfaces make sense to be lumped together for something you can make a combined interface

public interface IGraphics3D : IGraphics, IGraphicsManipulations3D

so now instead of saying you need a SPECIFIC graphics implementation you just need some object that does the basic things, you could even swap in completely different rendering engines if you wanted to.

public class UnityEngineGraphics : IGraphics3D

or

public class HavokEngineGraphics : IGraphics3D

But your game doesn’t care one bit.

public class MyGame(IGraphics3D, IPlayer)

The important thing to note and most likely where you find it difficult to see value is that these circumstances tend to come up later rather than sooner and when you are building the MyGame you are fully intent on using one implementation of the graphics object. Never forget that requirements change, sometimes for good, sometimes for headaches and design patterns are THE way to be preemptive.

In this example:

public MyGame( IGraphics graphics, IPlayer player )

the statement:

However, the dependencies are still in my code

is not correct. The are no dependencies because now the class is tied to a contract and not an implementation.

In some cases it is not necessary to be loosely coupled. For example, the player class may not be a good candidate to be loosely coupled if it just contains properties or core logic.

Let’s take a look at a better example, let’s say your game uses a 3rd party ranking engine to rank players.

So your constructor may look like this:

public MyGame( IRankingProvider Provider )

Now you can swap out different implementations of a ranking provider rather easily, your code may have 3 or 4 implementations depending on what platform the game is running on.

Also, for unit testing you can create a fake Provider to unit test the logic on MyGame without any external ranking provider dependencies. This makes it easy to run all the unit tests on a development/build machine without installing/setting up any of the providers.

Now eventually on a development/deployment server one would want to perform integration tests using actual providers to ensure the implementation are correct, in those cases the test fixture would inject a real implementation.

So, the main benefits are:

  1. Increased testability
  2. Ability to switch out implementations or use multiple implementations
  3. Removal of dependencies

One should choose carefully which parts of the system are loosely coupled. In some cases it is not needed and when employed causes a needless layer of abstraction.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa

Loose coupling and shuffling dependencies

I have a bunch of classes that look something like this:

public class MyGame()
{
    private Graphics graphics;

    private Player player;

    public MyGame()
    {
        graphics = new Graphics();
        //...
    }

    protected void Initialize()
    {
        player = new Player();
        //...
    }

    protected void Update()
    {
        player.DoStuff();
        //...
    }

I’ve been reading about design patterns, and I’ve come to understand that this is not a very good design because it isn’t loosely coupled. Instead of coding to interfaces, I’m coding to implementations (Graphics, Player, etc.).

In order to fix this perceived problem, I start by changing those dependencies to interfaces:

public class MyGame()
{
    private IGraphics graphics;

    private IPlayer player;

    public MyGame()
    {
        graphics = new Graphics();
        //...
    }

    protected void Initialize()
    {
        player = new Player();
        //...
    }

I’m not sure how helpful that really is, but it’s nice that the graphics field (for example) isn’t tied to the Graphics class – I can use the AwesomeGraphics class or SparklyGraphics class instead as long as those classes implement IGraphics.

But I still have hard dependencies on Graphics and Player, so what was the point of all that refactoring? (My actual code is much more complicated.) I’ve also come to understand that dependency injection is a good idea, so that’s what I try to do next:

public class MyGame()
{
    private IGraphics graphics;

    private IPlayer player;

    public MyGame( IGraphics graphics, IPlayer player )
    {
        this.graphics = graphics;
        this.player = player;
        //...
    }

This looks really nice because I no longer have any hard dependencies in MyGame. However, the dependencies are still in my code – they’ve just been moved to the class that instantiates MyGame:

static class Program
{
    static void Main( string[] args )
    {
        using ( var game = new Game( new Graphics(), new Player() )
        {
            game.Run();
        }
    }
}

Now I’m back where I started! This class is not loosely coupled at all! So, again, what was the point of all that refactoring? I’m pretty sure I could use an IoC container to take care of these dependencies somehow, but that would likely just add a ton of complication to an already complicated project. Plus, wouldn’t that just be moving those dependencies once again to another class?

Should I stick with what I had in the first place, or is there some tangible benefit that I’m not seeing yet?

6

You have gained the benefits of loose coupling in your refactoring. You’ve moved the knowledge of the precise implementation outside of your MyGame class and into a higher-level class. This is good: by keeping all knowledge of what the precise implementations are together, you’re improving the structure of your code, making it easier for high level changes to take place, and making it easier to make changes that involve, for example, using multiple implementations of your Player class (perhaps by introducing a NetworkPlayer or AIPlayer later). MyGame now has one fewer reason to change, so is closer to having a single responsibility, and the Single Responsibility Principle is now considered one of the most important in object-oriented design by many programmers.

Eventually, all code has to depend on a concrete implementation, whether that’s specified in code or some sort of DI framework configuration file. The benefit of depending on an interface is that you can more easily depend on multiple concrete implementations, as the situation calls for.

However, those benefits aren’t actually realized until you actually have multiple concrete implementations. Most frequently, the second concrete implementation is a mock object used in unit testing. It could also be things like multiple target platforms. For example, I have a project that depends on interfaces for the UI so I can substitute concrete implementations for either Swing or Android. It’s common to have interfaces for multiple databases or operating system-specific functionality.

If you don’t ever have that second implementation, you aren’t actually receiving any tangible benefit. You just have a future assurance that if you ever need a second implementation, it will be easier to integrate. It’s like owning non-dividend stock. It’s worth something on paper, but you don’t get any real benefit until you actually sell it.

At the program level, there will always be a point at which a decision needs to be made which concrete implementations of IGraphics and IPlayer will be given to Game. This is what you’re seeing here.

The point of your work is that you’ve moved the decision out of Game itself, so it isn’t tightly coupled to any particular implementations, and left it to your higher level program code to decide.

This means that Game is much more flexible (as are IGraphics, and IPlayer), and your program is now made up of freely composable units instead of one inflexible hierarchical unit.

It may not seem like a big deal with such a simple contrived example, but once you get even a little bit more complex, the composability becomes much more beneficial.

You certainly have gained substantial benefit from changing the structure.

When coding new systems or fairly stable systems implementing design patterns can seem like a waste of effort and time since it didn’t make your life easier right now.

Consider that the Graphics object you were using originally was developed for rendering 2D graphics and does all kinds of logic under the covers to make development easier. Later on your game grows and now needs to start doing some 3D graphics, normally you would start by inheriting from Graphics, only 2D graphics while it may have some similar methods such as Render(), Refresh(), or Invalidate() has nothing to do with 3D graphics.

By opening up several SIMPLE interfaces for Graphics you open the door to much more flexibility in your code.

As an example of the strategy pattern (dependency inversion) and coding to interfaces:

MyGame requires several things to function.

It needs our Render(), Refresh(), Invalidate(). (IGraphics)
It needs additional 3D methods such as Transform(), Rotate() . (IGraphicsManipulations3D)

And if those multiple interfaces make sense to be lumped together for something you can make a combined interface

public interface IGraphics3D : IGraphics, IGraphicsManipulations3D

so now instead of saying you need a SPECIFIC graphics implementation you just need some object that does the basic things, you could even swap in completely different rendering engines if you wanted to.

public class UnityEngineGraphics : IGraphics3D

or

public class HavokEngineGraphics : IGraphics3D

But your game doesn’t care one bit.

public class MyGame(IGraphics3D, IPlayer)

The important thing to note and most likely where you find it difficult to see value is that these circumstances tend to come up later rather than sooner and when you are building the MyGame you are fully intent on using one implementation of the graphics object. Never forget that requirements change, sometimes for good, sometimes for headaches and design patterns are THE way to be preemptive.

In this example:

public MyGame( IGraphics graphics, IPlayer player )

the statement:

However, the dependencies are still in my code

is not correct. The are no dependencies because now the class is tied to a contract and not an implementation.

In some cases it is not necessary to be loosely coupled. For example, the player class may not be a good candidate to be loosely coupled if it just contains properties or core logic.

Let’s take a look at a better example, let’s say your game uses a 3rd party ranking engine to rank players.

So your constructor may look like this:

public MyGame( IRankingProvider Provider )

Now you can swap out different implementations of a ranking provider rather easily, your code may have 3 or 4 implementations depending on what platform the game is running on.

Also, for unit testing you can create a fake Provider to unit test the logic on MyGame without any external ranking provider dependencies. This makes it easy to run all the unit tests on a development/build machine without installing/setting up any of the providers.

Now eventually on a development/deployment server one would want to perform integration tests using actual providers to ensure the implementation are correct, in those cases the test fixture would inject a real implementation.

So, the main benefits are:

  1. Increased testability
  2. Ability to switch out implementations or use multiple implementations
  3. Removal of dependencies

One should choose carefully which parts of the system are loosely coupled. In some cases it is not needed and when employed causes a needless layer of abstraction.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật