Which design pattern is the opposite of the Factory pattern?
Asked Answered
L

4

10

I was wondering if there is an opposite pattern of the factory pattern. For example, when a certain object needs to be deleted some extra work needs to be done, to undo the configuration which was performed in the factory object.

Extending the factory object with a Delete method for instance seems wrong, since the factory pattern is a strict creational pattern.

Update: The reason why I'm using a factory is because the configuration which needs to be done would introduce some dependencies to the object which wouldn't fit. Putting this de-configuration in the constructor would pose the same problem.

Leuctra answered 15/9, 2009 at 7:52 Comment(4)
What exactly do you mean with 'deleting' ? Freeing from memory, or removing from a datastore ?Crackdown
With deleting I meant removing it from a datastore, this would be done by the repository.Leuctra
and what sort of "configuration was performed in the factory object"? An object should be capable of cleaning up after itself, the task of destructors and/or dispose. I would argue that a factory should not know anything of the objects it has created.Scourings
The configuration work that the factory object perform connects aggregate roots and initializes the security context. Doing this in the constructor would introduce some dependencies, which would only be used there. The factory pattern seemed appropriate for creation.Leuctra
C
3

That's right way to use factory. Factory is not only way to create objects, but also the way to say: I need a special initialization for these kind of objects. With your problem I think the best solution would be to notify factory with some event, like disposed. So your object creation will be done in such a way: create, subscribe factory to event of newly created object. Every time object is deleted you`ll notify factory on that and perform action you need.

If you don't like to put this into factory, you can delegate it to some kind of other object, like DeathKeeper ;-). So your code will look sometihng like this:

//Inside factory create method
MyObject obj = GetNewInitializedObject();
_deathKeeper.RegisterObject(obj);

return obj;

Now every time you will need to delete object, your object will notify death keeper and it would make all dispose logic. By the way, I do not know how it all works, but you can use IDisposable interface to do the custom logic for disposing resources held by object. The decision depends on what`s there in your project and is up to you.

Cockroach answered 16/9, 2009 at 4:1 Comment(0)
R
4

A repository could be used to delete a persisted object, or you could use the dispose method to do some cleanup on an in memory only object.

Ruel answered 15/9, 2009 at 7:55 Comment(2)
I'll put this "de-configuration" in the repository for now.Leuctra
Do you need to destroy any persisted (Database/File) information?Ruel
C
3

That's right way to use factory. Factory is not only way to create objects, but also the way to say: I need a special initialization for these kind of objects. With your problem I think the best solution would be to notify factory with some event, like disposed. So your object creation will be done in such a way: create, subscribe factory to event of newly created object. Every time object is deleted you`ll notify factory on that and perform action you need.

If you don't like to put this into factory, you can delegate it to some kind of other object, like DeathKeeper ;-). So your code will look sometihng like this:

//Inside factory create method
MyObject obj = GetNewInitializedObject();
_deathKeeper.RegisterObject(obj);

return obj;

Now every time you will need to delete object, your object will notify death keeper and it would make all dispose logic. By the way, I do not know how it all works, but you can use IDisposable interface to do the custom logic for disposing resources held by object. The decision depends on what`s there in your project and is up to you.

Cockroach answered 16/9, 2009 at 4:1 Comment(0)
Q
3

I use a "Recycling Facility" pattern working in tandem with the Factory:

  • have a "clean" method for each class that can be recycled
  • have a "unique id" for each object instance

Each time an object reaches its end-of-life, send it to the "Recycling Facility" (RF):

  • The RF stores the object according to some policy ( e.g. keep only X instances of class Y )
  • When a an instance of class Y is required, the Factory "asks" the RF if its got one
    • if the RF has one handy, the RF calls the "clean()" method on the instance and returns it to the Factory

... and so on so forth.

Hope this helps.

Quinquennium answered 19/9, 2009 at 18:44 Comment(0)
C
0

I had the same question and I am not happy with the existing answers and I don't like the terms Recycling (I do not reuse it) or DeathKeeper (sounds lighthearted). Repository is nice but sometimes overkill. It might not even be an essential part of your application and more of a GDPR feature.

There is no exact opposite pattern of the factory pattern and I would agree that the name implies creational and the single responsibility rule would speak against adding delete functionality to it.

I decided on creating a Disposer like an AccountDisposer:

public interface IAccount
{
    int Id { get; }
    void Dispose(AccountDisposer accountDisposer);
    // Other properties and methods
}

public interface IAccountDisposer {
    void DisposeAccount(AccountSet account);
}

public class AccountSet : IAccount
{
    public int Id { get; set; }

    //TODO: move into AccountFactory
    public static void Create(int id) {
        var accountSet = new AccountSet { Id = id };
    }

    public void Dispose(AccountDisposer accountDisposer)
    {
        accountDisposer.DisposeAccount(this);
    }
}

public class AccountDisposer : IAccountDisposer
{
    private readonly MyDbContext _dbContext;

    public AccountDisposer(MyDbContext dbContext) {
        _dbContext = dbContext;
    }

    public void DisposeAccount(AccountSet account)
    {
        _dbContext.AccountSet.Remove(account); // <- this matters
    }
}

Notice that I did not use IDisposable because I need a parameter. If you know a smarter way or have other feedback tell me in the comments. Having DisposeAccount() method in AccountSet is generally optional.

Cryptanalysis answered 29/3, 2023 at 20:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.