Is it appropriate for a Factory class to also include functionality of extracting data from a database
One of the main aspects of software development that I struggle with is delegating the correct responsibility into classes within my program. Working at my first junior role I'm also being exposed to a lot of different design patterns and ideas, and sometimes the information can be overwhelming.
Obviously when we are building software we tend to state that a class should be responsible for one thing and one thing only. It should do that thing well and nothing more. So in the case of the Factory pattern the Factory class should be responsible for building the product and exposing an interface that allows the director to extract the product from the factory.
However the factory class obviously needs to receive the data to build the product from somewhere, without input data we have no output product. Therefore I'd like to know whether including functionality for a factory to query a database is appropriate? My rationale for this is that if the factory is tasked with building a particular product, then it should also be responsible for retrieving the data required to build that product. But I'm not 100% sure if this is correct.
Alternatively, should there be a repository class who's responsibility is to retrieve the data in question from the database, which can be then passed to the factory for assembly into the required product? The use of a repository class seems a bit excessive in this case as we have a class that will hold a large number of different pieces of data which then must be shipped into the factory class.
If we also bear in mind Uncle Bob's teachings that state that functions and methods should have absolutely no more than three parameters then we will be breaking this rule by passing in a large amount of data to the factory. If we first assemble the data into an encompassing class before passing to the factory then we are essentially doing the factory's job within the repository class.
Some guidance would be really appreciated on this, as in my head the lines are very blurry and I'm not sure how I should proceed.
c# design-patterns
add a comment |
One of the main aspects of software development that I struggle with is delegating the correct responsibility into classes within my program. Working at my first junior role I'm also being exposed to a lot of different design patterns and ideas, and sometimes the information can be overwhelming.
Obviously when we are building software we tend to state that a class should be responsible for one thing and one thing only. It should do that thing well and nothing more. So in the case of the Factory pattern the Factory class should be responsible for building the product and exposing an interface that allows the director to extract the product from the factory.
However the factory class obviously needs to receive the data to build the product from somewhere, without input data we have no output product. Therefore I'd like to know whether including functionality for a factory to query a database is appropriate? My rationale for this is that if the factory is tasked with building a particular product, then it should also be responsible for retrieving the data required to build that product. But I'm not 100% sure if this is correct.
Alternatively, should there be a repository class who's responsibility is to retrieve the data in question from the database, which can be then passed to the factory for assembly into the required product? The use of a repository class seems a bit excessive in this case as we have a class that will hold a large number of different pieces of data which then must be shipped into the factory class.
If we also bear in mind Uncle Bob's teachings that state that functions and methods should have absolutely no more than three parameters then we will be breaking this rule by passing in a large amount of data to the factory. If we first assemble the data into an encompassing class before passing to the factory then we are essentially doing the factory's job within the repository class.
Some guidance would be really appreciated on this, as in my head the lines are very blurry and I'm not sure how I should proceed.
c# design-patterns
add a comment |
One of the main aspects of software development that I struggle with is delegating the correct responsibility into classes within my program. Working at my first junior role I'm also being exposed to a lot of different design patterns and ideas, and sometimes the information can be overwhelming.
Obviously when we are building software we tend to state that a class should be responsible for one thing and one thing only. It should do that thing well and nothing more. So in the case of the Factory pattern the Factory class should be responsible for building the product and exposing an interface that allows the director to extract the product from the factory.
However the factory class obviously needs to receive the data to build the product from somewhere, without input data we have no output product. Therefore I'd like to know whether including functionality for a factory to query a database is appropriate? My rationale for this is that if the factory is tasked with building a particular product, then it should also be responsible for retrieving the data required to build that product. But I'm not 100% sure if this is correct.
Alternatively, should there be a repository class who's responsibility is to retrieve the data in question from the database, which can be then passed to the factory for assembly into the required product? The use of a repository class seems a bit excessive in this case as we have a class that will hold a large number of different pieces of data which then must be shipped into the factory class.
If we also bear in mind Uncle Bob's teachings that state that functions and methods should have absolutely no more than three parameters then we will be breaking this rule by passing in a large amount of data to the factory. If we first assemble the data into an encompassing class before passing to the factory then we are essentially doing the factory's job within the repository class.
Some guidance would be really appreciated on this, as in my head the lines are very blurry and I'm not sure how I should proceed.
c# design-patterns
One of the main aspects of software development that I struggle with is delegating the correct responsibility into classes within my program. Working at my first junior role I'm also being exposed to a lot of different design patterns and ideas, and sometimes the information can be overwhelming.
Obviously when we are building software we tend to state that a class should be responsible for one thing and one thing only. It should do that thing well and nothing more. So in the case of the Factory pattern the Factory class should be responsible for building the product and exposing an interface that allows the director to extract the product from the factory.
However the factory class obviously needs to receive the data to build the product from somewhere, without input data we have no output product. Therefore I'd like to know whether including functionality for a factory to query a database is appropriate? My rationale for this is that if the factory is tasked with building a particular product, then it should also be responsible for retrieving the data required to build that product. But I'm not 100% sure if this is correct.
Alternatively, should there be a repository class who's responsibility is to retrieve the data in question from the database, which can be then passed to the factory for assembly into the required product? The use of a repository class seems a bit excessive in this case as we have a class that will hold a large number of different pieces of data which then must be shipped into the factory class.
If we also bear in mind Uncle Bob's teachings that state that functions and methods should have absolutely no more than three parameters then we will be breaking this rule by passing in a large amount of data to the factory. If we first assemble the data into an encompassing class before passing to the factory then we are essentially doing the factory's job within the repository class.
Some guidance would be really appreciated on this, as in my head the lines are very blurry and I'm not sure how I should proceed.
c# design-patterns
c# design-patterns
asked Nov 21 '18 at 9:27
Jake12342134
967
967
add a comment |
add a comment |
3 Answers
3
active
oldest
votes
You shouldn't use the factory pattern to object building that extracted from a database. There are the Repository pattern and the Data Mapper pattern for this goal. Those patterns must encapsulate all logic of work with the data storage. Those patterns must have the following responsibility:
- the Repository must give an interface to business logic for work with data storage
- the Data Mapper must convert data from database to concrete object
The algorithm of cooperation between objects can look like:
- business logic uses a repository to read/persist objects.
- the repository uses a Data Mapper to convert objects to INSERT or UPDATE queries and to convert data from data storage to object
Also, you can read more details about the repository pattern in C# on the site of Microsoft and you can see C# example of the repository pattern
Usually, the repository does not persist entities, only retrieves entities and stores them in memory… Even semantically it sounds wrong… We might rather implement a facade encapsulating the abstracted (from data mapper) CRUD operations and making use internally of the repositories for READ operations.
– ClemC
Nov 22 '18 at 10:52
Repository might have different implementations. In some cases, it only can retrieve entities from data storage, in other cases, it also can persist entities to storage. For example deviq.com/repository-pattern. The main idea of the repository pattern is the creation of abstraction over a database that will work as a collection. Martin Fowler said about repository "Objects can be added to and removed from the Repository, as they can from a simple collection of objects, and the mapping code encapsulated by the Repository will carry out the appropriate operations behind the scenes".
– Maxim Fedorov
Nov 22 '18 at 11:45
Of course in some implementation of a repository might stores entities which extracted from storage in memory, but often it is the responsibility of Often, Unit Of Work pattern . In any case, it is a detail of Data Layer realization
– Maxim Fedorov
Nov 22 '18 at 11:48
Indeed now that I see it with your eyes it makes more sense to me, but still... Martin Fowler states that entities can be removed from the repository, that's obvious if they get added during a READ operation, they have to be removed from during a DELETE operation. I just checked again in his book and found no evidence that his repository is intended to be used to persist objects. He emphasizes the whole repository chapter on the retrieving aspect. To summarize, it encapsulates high level querying logic plus the entity collection. That's a kind of pool.
– ClemC
Nov 22 '18 at 12:34
IMHO the high level persisting operations which have nothing to do with high level querying logic plus entity pool of a specific domain model should be encapsulated separately for separation of concerns.
– ClemC
Nov 22 '18 at 13:12
|
show 1 more comment
Use 2 different classes.
A Data Access Object (DAO) provides an abstract interface to the database, and hides its details.
A factory abstracts and hides the details of the creation of your objects. For example, for unit testing you might want to configure the factory so that it doesn't use the Database at all.
To reduce the number of parameters between the DAO and the factory, wrap your many pieces of data in a few logically related classes.
add a comment |
Is it apropriate for a Factory class to also include functionality of extracting data from a database
My rationale for this is that if the factory is tasked with building a particular product, then it should also be responsible for retrieving the data required to build that product. But I'm not 100% sure if this is correct.
A product to retrieve from database is not a trivial object, it is a domain model.
A domain model (aka business model, aka entity(which might indicate a particular instance of it)) belongs to your domain layer (aka business layer).
In this regard, there are some patterns you should be a minimum familiar with...
(Active Record) VS (Data Mapper + Repository) VS (Table Data Gateway + Factory)
Active record pattern kind of violate the Single Responsibility Principle by leading you to implement database access logic inside your domain model and tightly couples them.
Ideally, to avoid the cons above for the cost of a slightly increased complexity (on short term only), we separate the database access logic into a supplementary layer, the data access layer. One of the main component of this layer being the data mapper which in our context (READ operation) is in charge to retrieve data from database and map it to a new domain model instance, your specific product (entity). More generally it encapsulates CRUD operations to the database abstracting this database. Its API inputs and outputs are entity objects and possibly Query Objects.
Optionally, a featured data mapper would make use of patterns such as:
- Unit Of Work
- Lazy Loading
- Identity Map
- Transaction
- Lock Strategies
- Metadata Mapping
Alternatively, should there be a repository class who's responsibility is to retrieve the data in question from the database, which can be then passed to the factory for assembly into the required product? The use of a repository class seems a bit excessive in this case as we have a class that will hold a large number of different pieces of data which then must be shipped into the factory class.
Repository is not a part of your data access layer, but of your domain layer. So it is client of your data access layer. It doesn't encapsulate any database access logic but uses the data mapper.
A repository encapsulates query logic for a particular domain model plus a collection of in-memory entities you've previously retrieved.
A very basic example:
class ProductRepository
{
private $productCollection;
public function findById($id)
{
if (!$this->productCollection->has($id)) {
$product = $this->dataMapper->get(new Query(Product::class, $id));
$this->productCollection->add($product);
return $product;
}
return $this->productCollection->get($id);
}
}
Finally, we can encapsulate database access logic in a table data gateway and use it in a factory. This would result in a solution similar to Gonen I's one. It is simple to implement but there might be cons compared to the data mapper solution. I've never implemented, used or even studied this approach so I can't tell much...
You'd definitely learn a lot by attempting to implement all that by yourself and I'd encourage you to, but keep in mind that if you need a serious solution, ORMs might be interesting for you.
If you're keen to learn more about all this, I recommend Martin Fowler's Patterns of Enterprise Application Architecture book which is summarized here: https://www.martinfowler.com/eaaCatalog/index.html
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53408889%2fis-it-appropriate-for-a-factory-class-to-also-include-functionality-of-extractin%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
You shouldn't use the factory pattern to object building that extracted from a database. There are the Repository pattern and the Data Mapper pattern for this goal. Those patterns must encapsulate all logic of work with the data storage. Those patterns must have the following responsibility:
- the Repository must give an interface to business logic for work with data storage
- the Data Mapper must convert data from database to concrete object
The algorithm of cooperation between objects can look like:
- business logic uses a repository to read/persist objects.
- the repository uses a Data Mapper to convert objects to INSERT or UPDATE queries and to convert data from data storage to object
Also, you can read more details about the repository pattern in C# on the site of Microsoft and you can see C# example of the repository pattern
Usually, the repository does not persist entities, only retrieves entities and stores them in memory… Even semantically it sounds wrong… We might rather implement a facade encapsulating the abstracted (from data mapper) CRUD operations and making use internally of the repositories for READ operations.
– ClemC
Nov 22 '18 at 10:52
Repository might have different implementations. In some cases, it only can retrieve entities from data storage, in other cases, it also can persist entities to storage. For example deviq.com/repository-pattern. The main idea of the repository pattern is the creation of abstraction over a database that will work as a collection. Martin Fowler said about repository "Objects can be added to and removed from the Repository, as they can from a simple collection of objects, and the mapping code encapsulated by the Repository will carry out the appropriate operations behind the scenes".
– Maxim Fedorov
Nov 22 '18 at 11:45
Of course in some implementation of a repository might stores entities which extracted from storage in memory, but often it is the responsibility of Often, Unit Of Work pattern . In any case, it is a detail of Data Layer realization
– Maxim Fedorov
Nov 22 '18 at 11:48
Indeed now that I see it with your eyes it makes more sense to me, but still... Martin Fowler states that entities can be removed from the repository, that's obvious if they get added during a READ operation, they have to be removed from during a DELETE operation. I just checked again in his book and found no evidence that his repository is intended to be used to persist objects. He emphasizes the whole repository chapter on the retrieving aspect. To summarize, it encapsulates high level querying logic plus the entity collection. That's a kind of pool.
– ClemC
Nov 22 '18 at 12:34
IMHO the high level persisting operations which have nothing to do with high level querying logic plus entity pool of a specific domain model should be encapsulated separately for separation of concerns.
– ClemC
Nov 22 '18 at 13:12
|
show 1 more comment
You shouldn't use the factory pattern to object building that extracted from a database. There are the Repository pattern and the Data Mapper pattern for this goal. Those patterns must encapsulate all logic of work with the data storage. Those patterns must have the following responsibility:
- the Repository must give an interface to business logic for work with data storage
- the Data Mapper must convert data from database to concrete object
The algorithm of cooperation between objects can look like:
- business logic uses a repository to read/persist objects.
- the repository uses a Data Mapper to convert objects to INSERT or UPDATE queries and to convert data from data storage to object
Also, you can read more details about the repository pattern in C# on the site of Microsoft and you can see C# example of the repository pattern
Usually, the repository does not persist entities, only retrieves entities and stores them in memory… Even semantically it sounds wrong… We might rather implement a facade encapsulating the abstracted (from data mapper) CRUD operations and making use internally of the repositories for READ operations.
– ClemC
Nov 22 '18 at 10:52
Repository might have different implementations. In some cases, it only can retrieve entities from data storage, in other cases, it also can persist entities to storage. For example deviq.com/repository-pattern. The main idea of the repository pattern is the creation of abstraction over a database that will work as a collection. Martin Fowler said about repository "Objects can be added to and removed from the Repository, as they can from a simple collection of objects, and the mapping code encapsulated by the Repository will carry out the appropriate operations behind the scenes".
– Maxim Fedorov
Nov 22 '18 at 11:45
Of course in some implementation of a repository might stores entities which extracted from storage in memory, but often it is the responsibility of Often, Unit Of Work pattern . In any case, it is a detail of Data Layer realization
– Maxim Fedorov
Nov 22 '18 at 11:48
Indeed now that I see it with your eyes it makes more sense to me, but still... Martin Fowler states that entities can be removed from the repository, that's obvious if they get added during a READ operation, they have to be removed from during a DELETE operation. I just checked again in his book and found no evidence that his repository is intended to be used to persist objects. He emphasizes the whole repository chapter on the retrieving aspect. To summarize, it encapsulates high level querying logic plus the entity collection. That's a kind of pool.
– ClemC
Nov 22 '18 at 12:34
IMHO the high level persisting operations which have nothing to do with high level querying logic plus entity pool of a specific domain model should be encapsulated separately for separation of concerns.
– ClemC
Nov 22 '18 at 13:12
|
show 1 more comment
You shouldn't use the factory pattern to object building that extracted from a database. There are the Repository pattern and the Data Mapper pattern for this goal. Those patterns must encapsulate all logic of work with the data storage. Those patterns must have the following responsibility:
- the Repository must give an interface to business logic for work with data storage
- the Data Mapper must convert data from database to concrete object
The algorithm of cooperation between objects can look like:
- business logic uses a repository to read/persist objects.
- the repository uses a Data Mapper to convert objects to INSERT or UPDATE queries and to convert data from data storage to object
Also, you can read more details about the repository pattern in C# on the site of Microsoft and you can see C# example of the repository pattern
You shouldn't use the factory pattern to object building that extracted from a database. There are the Repository pattern and the Data Mapper pattern for this goal. Those patterns must encapsulate all logic of work with the data storage. Those patterns must have the following responsibility:
- the Repository must give an interface to business logic for work with data storage
- the Data Mapper must convert data from database to concrete object
The algorithm of cooperation between objects can look like:
- business logic uses a repository to read/persist objects.
- the repository uses a Data Mapper to convert objects to INSERT or UPDATE queries and to convert data from data storage to object
Also, you can read more details about the repository pattern in C# on the site of Microsoft and you can see C# example of the repository pattern
edited Nov 22 '18 at 11:54
answered Nov 21 '18 at 11:33
Maxim Fedorov
2,905419
2,905419
Usually, the repository does not persist entities, only retrieves entities and stores them in memory… Even semantically it sounds wrong… We might rather implement a facade encapsulating the abstracted (from data mapper) CRUD operations and making use internally of the repositories for READ operations.
– ClemC
Nov 22 '18 at 10:52
Repository might have different implementations. In some cases, it only can retrieve entities from data storage, in other cases, it also can persist entities to storage. For example deviq.com/repository-pattern. The main idea of the repository pattern is the creation of abstraction over a database that will work as a collection. Martin Fowler said about repository "Objects can be added to and removed from the Repository, as they can from a simple collection of objects, and the mapping code encapsulated by the Repository will carry out the appropriate operations behind the scenes".
– Maxim Fedorov
Nov 22 '18 at 11:45
Of course in some implementation of a repository might stores entities which extracted from storage in memory, but often it is the responsibility of Often, Unit Of Work pattern . In any case, it is a detail of Data Layer realization
– Maxim Fedorov
Nov 22 '18 at 11:48
Indeed now that I see it with your eyes it makes more sense to me, but still... Martin Fowler states that entities can be removed from the repository, that's obvious if they get added during a READ operation, they have to be removed from during a DELETE operation. I just checked again in his book and found no evidence that his repository is intended to be used to persist objects. He emphasizes the whole repository chapter on the retrieving aspect. To summarize, it encapsulates high level querying logic plus the entity collection. That's a kind of pool.
– ClemC
Nov 22 '18 at 12:34
IMHO the high level persisting operations which have nothing to do with high level querying logic plus entity pool of a specific domain model should be encapsulated separately for separation of concerns.
– ClemC
Nov 22 '18 at 13:12
|
show 1 more comment
Usually, the repository does not persist entities, only retrieves entities and stores them in memory… Even semantically it sounds wrong… We might rather implement a facade encapsulating the abstracted (from data mapper) CRUD operations and making use internally of the repositories for READ operations.
– ClemC
Nov 22 '18 at 10:52
Repository might have different implementations. In some cases, it only can retrieve entities from data storage, in other cases, it also can persist entities to storage. For example deviq.com/repository-pattern. The main idea of the repository pattern is the creation of abstraction over a database that will work as a collection. Martin Fowler said about repository "Objects can be added to and removed from the Repository, as they can from a simple collection of objects, and the mapping code encapsulated by the Repository will carry out the appropriate operations behind the scenes".
– Maxim Fedorov
Nov 22 '18 at 11:45
Of course in some implementation of a repository might stores entities which extracted from storage in memory, but often it is the responsibility of Often, Unit Of Work pattern . In any case, it is a detail of Data Layer realization
– Maxim Fedorov
Nov 22 '18 at 11:48
Indeed now that I see it with your eyes it makes more sense to me, but still... Martin Fowler states that entities can be removed from the repository, that's obvious if they get added during a READ operation, they have to be removed from during a DELETE operation. I just checked again in his book and found no evidence that his repository is intended to be used to persist objects. He emphasizes the whole repository chapter on the retrieving aspect. To summarize, it encapsulates high level querying logic plus the entity collection. That's a kind of pool.
– ClemC
Nov 22 '18 at 12:34
IMHO the high level persisting operations which have nothing to do with high level querying logic plus entity pool of a specific domain model should be encapsulated separately for separation of concerns.
– ClemC
Nov 22 '18 at 13:12
Usually, the repository does not persist entities, only retrieves entities and stores them in memory… Even semantically it sounds wrong… We might rather implement a facade encapsulating the abstracted (from data mapper) CRUD operations and making use internally of the repositories for READ operations.
– ClemC
Nov 22 '18 at 10:52
Usually, the repository does not persist entities, only retrieves entities and stores them in memory… Even semantically it sounds wrong… We might rather implement a facade encapsulating the abstracted (from data mapper) CRUD operations and making use internally of the repositories for READ operations.
– ClemC
Nov 22 '18 at 10:52
Repository might have different implementations. In some cases, it only can retrieve entities from data storage, in other cases, it also can persist entities to storage. For example deviq.com/repository-pattern. The main idea of the repository pattern is the creation of abstraction over a database that will work as a collection. Martin Fowler said about repository "Objects can be added to and removed from the Repository, as they can from a simple collection of objects, and the mapping code encapsulated by the Repository will carry out the appropriate operations behind the scenes".
– Maxim Fedorov
Nov 22 '18 at 11:45
Repository might have different implementations. In some cases, it only can retrieve entities from data storage, in other cases, it also can persist entities to storage. For example deviq.com/repository-pattern. The main idea of the repository pattern is the creation of abstraction over a database that will work as a collection. Martin Fowler said about repository "Objects can be added to and removed from the Repository, as they can from a simple collection of objects, and the mapping code encapsulated by the Repository will carry out the appropriate operations behind the scenes".
– Maxim Fedorov
Nov 22 '18 at 11:45
Of course in some implementation of a repository might stores entities which extracted from storage in memory, but often it is the responsibility of Often, Unit Of Work pattern . In any case, it is a detail of Data Layer realization
– Maxim Fedorov
Nov 22 '18 at 11:48
Of course in some implementation of a repository might stores entities which extracted from storage in memory, but often it is the responsibility of Often, Unit Of Work pattern . In any case, it is a detail of Data Layer realization
– Maxim Fedorov
Nov 22 '18 at 11:48
Indeed now that I see it with your eyes it makes more sense to me, but still... Martin Fowler states that entities can be removed from the repository, that's obvious if they get added during a READ operation, they have to be removed from during a DELETE operation. I just checked again in his book and found no evidence that his repository is intended to be used to persist objects. He emphasizes the whole repository chapter on the retrieving aspect. To summarize, it encapsulates high level querying logic plus the entity collection. That's a kind of pool.
– ClemC
Nov 22 '18 at 12:34
Indeed now that I see it with your eyes it makes more sense to me, but still... Martin Fowler states that entities can be removed from the repository, that's obvious if they get added during a READ operation, they have to be removed from during a DELETE operation. I just checked again in his book and found no evidence that his repository is intended to be used to persist objects. He emphasizes the whole repository chapter on the retrieving aspect. To summarize, it encapsulates high level querying logic plus the entity collection. That's a kind of pool.
– ClemC
Nov 22 '18 at 12:34
IMHO the high level persisting operations which have nothing to do with high level querying logic plus entity pool of a specific domain model should be encapsulated separately for separation of concerns.
– ClemC
Nov 22 '18 at 13:12
IMHO the high level persisting operations which have nothing to do with high level querying logic plus entity pool of a specific domain model should be encapsulated separately for separation of concerns.
– ClemC
Nov 22 '18 at 13:12
|
show 1 more comment
Use 2 different classes.
A Data Access Object (DAO) provides an abstract interface to the database, and hides its details.
A factory abstracts and hides the details of the creation of your objects. For example, for unit testing you might want to configure the factory so that it doesn't use the Database at all.
To reduce the number of parameters between the DAO and the factory, wrap your many pieces of data in a few logically related classes.
add a comment |
Use 2 different classes.
A Data Access Object (DAO) provides an abstract interface to the database, and hides its details.
A factory abstracts and hides the details of the creation of your objects. For example, for unit testing you might want to configure the factory so that it doesn't use the Database at all.
To reduce the number of parameters between the DAO and the factory, wrap your many pieces of data in a few logically related classes.
add a comment |
Use 2 different classes.
A Data Access Object (DAO) provides an abstract interface to the database, and hides its details.
A factory abstracts and hides the details of the creation of your objects. For example, for unit testing you might want to configure the factory so that it doesn't use the Database at all.
To reduce the number of parameters between the DAO and the factory, wrap your many pieces of data in a few logically related classes.
Use 2 different classes.
A Data Access Object (DAO) provides an abstract interface to the database, and hides its details.
A factory abstracts and hides the details of the creation of your objects. For example, for unit testing you might want to configure the factory so that it doesn't use the Database at all.
To reduce the number of parameters between the DAO and the factory, wrap your many pieces of data in a few logically related classes.
answered Nov 21 '18 at 11:44
Gonen I
1,8021228
1,8021228
add a comment |
add a comment |
Is it apropriate for a Factory class to also include functionality of extracting data from a database
My rationale for this is that if the factory is tasked with building a particular product, then it should also be responsible for retrieving the data required to build that product. But I'm not 100% sure if this is correct.
A product to retrieve from database is not a trivial object, it is a domain model.
A domain model (aka business model, aka entity(which might indicate a particular instance of it)) belongs to your domain layer (aka business layer).
In this regard, there are some patterns you should be a minimum familiar with...
(Active Record) VS (Data Mapper + Repository) VS (Table Data Gateway + Factory)
Active record pattern kind of violate the Single Responsibility Principle by leading you to implement database access logic inside your domain model and tightly couples them.
Ideally, to avoid the cons above for the cost of a slightly increased complexity (on short term only), we separate the database access logic into a supplementary layer, the data access layer. One of the main component of this layer being the data mapper which in our context (READ operation) is in charge to retrieve data from database and map it to a new domain model instance, your specific product (entity). More generally it encapsulates CRUD operations to the database abstracting this database. Its API inputs and outputs are entity objects and possibly Query Objects.
Optionally, a featured data mapper would make use of patterns such as:
- Unit Of Work
- Lazy Loading
- Identity Map
- Transaction
- Lock Strategies
- Metadata Mapping
Alternatively, should there be a repository class who's responsibility is to retrieve the data in question from the database, which can be then passed to the factory for assembly into the required product? The use of a repository class seems a bit excessive in this case as we have a class that will hold a large number of different pieces of data which then must be shipped into the factory class.
Repository is not a part of your data access layer, but of your domain layer. So it is client of your data access layer. It doesn't encapsulate any database access logic but uses the data mapper.
A repository encapsulates query logic for a particular domain model plus a collection of in-memory entities you've previously retrieved.
A very basic example:
class ProductRepository
{
private $productCollection;
public function findById($id)
{
if (!$this->productCollection->has($id)) {
$product = $this->dataMapper->get(new Query(Product::class, $id));
$this->productCollection->add($product);
return $product;
}
return $this->productCollection->get($id);
}
}
Finally, we can encapsulate database access logic in a table data gateway and use it in a factory. This would result in a solution similar to Gonen I's one. It is simple to implement but there might be cons compared to the data mapper solution. I've never implemented, used or even studied this approach so I can't tell much...
You'd definitely learn a lot by attempting to implement all that by yourself and I'd encourage you to, but keep in mind that if you need a serious solution, ORMs might be interesting for you.
If you're keen to learn more about all this, I recommend Martin Fowler's Patterns of Enterprise Application Architecture book which is summarized here: https://www.martinfowler.com/eaaCatalog/index.html
add a comment |
Is it apropriate for a Factory class to also include functionality of extracting data from a database
My rationale for this is that if the factory is tasked with building a particular product, then it should also be responsible for retrieving the data required to build that product. But I'm not 100% sure if this is correct.
A product to retrieve from database is not a trivial object, it is a domain model.
A domain model (aka business model, aka entity(which might indicate a particular instance of it)) belongs to your domain layer (aka business layer).
In this regard, there are some patterns you should be a minimum familiar with...
(Active Record) VS (Data Mapper + Repository) VS (Table Data Gateway + Factory)
Active record pattern kind of violate the Single Responsibility Principle by leading you to implement database access logic inside your domain model and tightly couples them.
Ideally, to avoid the cons above for the cost of a slightly increased complexity (on short term only), we separate the database access logic into a supplementary layer, the data access layer. One of the main component of this layer being the data mapper which in our context (READ operation) is in charge to retrieve data from database and map it to a new domain model instance, your specific product (entity). More generally it encapsulates CRUD operations to the database abstracting this database. Its API inputs and outputs are entity objects and possibly Query Objects.
Optionally, a featured data mapper would make use of patterns such as:
- Unit Of Work
- Lazy Loading
- Identity Map
- Transaction
- Lock Strategies
- Metadata Mapping
Alternatively, should there be a repository class who's responsibility is to retrieve the data in question from the database, which can be then passed to the factory for assembly into the required product? The use of a repository class seems a bit excessive in this case as we have a class that will hold a large number of different pieces of data which then must be shipped into the factory class.
Repository is not a part of your data access layer, but of your domain layer. So it is client of your data access layer. It doesn't encapsulate any database access logic but uses the data mapper.
A repository encapsulates query logic for a particular domain model plus a collection of in-memory entities you've previously retrieved.
A very basic example:
class ProductRepository
{
private $productCollection;
public function findById($id)
{
if (!$this->productCollection->has($id)) {
$product = $this->dataMapper->get(new Query(Product::class, $id));
$this->productCollection->add($product);
return $product;
}
return $this->productCollection->get($id);
}
}
Finally, we can encapsulate database access logic in a table data gateway and use it in a factory. This would result in a solution similar to Gonen I's one. It is simple to implement but there might be cons compared to the data mapper solution. I've never implemented, used or even studied this approach so I can't tell much...
You'd definitely learn a lot by attempting to implement all that by yourself and I'd encourage you to, but keep in mind that if you need a serious solution, ORMs might be interesting for you.
If you're keen to learn more about all this, I recommend Martin Fowler's Patterns of Enterprise Application Architecture book which is summarized here: https://www.martinfowler.com/eaaCatalog/index.html
add a comment |
Is it apropriate for a Factory class to also include functionality of extracting data from a database
My rationale for this is that if the factory is tasked with building a particular product, then it should also be responsible for retrieving the data required to build that product. But I'm not 100% sure if this is correct.
A product to retrieve from database is not a trivial object, it is a domain model.
A domain model (aka business model, aka entity(which might indicate a particular instance of it)) belongs to your domain layer (aka business layer).
In this regard, there are some patterns you should be a minimum familiar with...
(Active Record) VS (Data Mapper + Repository) VS (Table Data Gateway + Factory)
Active record pattern kind of violate the Single Responsibility Principle by leading you to implement database access logic inside your domain model and tightly couples them.
Ideally, to avoid the cons above for the cost of a slightly increased complexity (on short term only), we separate the database access logic into a supplementary layer, the data access layer. One of the main component of this layer being the data mapper which in our context (READ operation) is in charge to retrieve data from database and map it to a new domain model instance, your specific product (entity). More generally it encapsulates CRUD operations to the database abstracting this database. Its API inputs and outputs are entity objects and possibly Query Objects.
Optionally, a featured data mapper would make use of patterns such as:
- Unit Of Work
- Lazy Loading
- Identity Map
- Transaction
- Lock Strategies
- Metadata Mapping
Alternatively, should there be a repository class who's responsibility is to retrieve the data in question from the database, which can be then passed to the factory for assembly into the required product? The use of a repository class seems a bit excessive in this case as we have a class that will hold a large number of different pieces of data which then must be shipped into the factory class.
Repository is not a part of your data access layer, but of your domain layer. So it is client of your data access layer. It doesn't encapsulate any database access logic but uses the data mapper.
A repository encapsulates query logic for a particular domain model plus a collection of in-memory entities you've previously retrieved.
A very basic example:
class ProductRepository
{
private $productCollection;
public function findById($id)
{
if (!$this->productCollection->has($id)) {
$product = $this->dataMapper->get(new Query(Product::class, $id));
$this->productCollection->add($product);
return $product;
}
return $this->productCollection->get($id);
}
}
Finally, we can encapsulate database access logic in a table data gateway and use it in a factory. This would result in a solution similar to Gonen I's one. It is simple to implement but there might be cons compared to the data mapper solution. I've never implemented, used or even studied this approach so I can't tell much...
You'd definitely learn a lot by attempting to implement all that by yourself and I'd encourage you to, but keep in mind that if you need a serious solution, ORMs might be interesting for you.
If you're keen to learn more about all this, I recommend Martin Fowler's Patterns of Enterprise Application Architecture book which is summarized here: https://www.martinfowler.com/eaaCatalog/index.html
Is it apropriate for a Factory class to also include functionality of extracting data from a database
My rationale for this is that if the factory is tasked with building a particular product, then it should also be responsible for retrieving the data required to build that product. But I'm not 100% sure if this is correct.
A product to retrieve from database is not a trivial object, it is a domain model.
A domain model (aka business model, aka entity(which might indicate a particular instance of it)) belongs to your domain layer (aka business layer).
In this regard, there are some patterns you should be a minimum familiar with...
(Active Record) VS (Data Mapper + Repository) VS (Table Data Gateway + Factory)
Active record pattern kind of violate the Single Responsibility Principle by leading you to implement database access logic inside your domain model and tightly couples them.
Ideally, to avoid the cons above for the cost of a slightly increased complexity (on short term only), we separate the database access logic into a supplementary layer, the data access layer. One of the main component of this layer being the data mapper which in our context (READ operation) is in charge to retrieve data from database and map it to a new domain model instance, your specific product (entity). More generally it encapsulates CRUD operations to the database abstracting this database. Its API inputs and outputs are entity objects and possibly Query Objects.
Optionally, a featured data mapper would make use of patterns such as:
- Unit Of Work
- Lazy Loading
- Identity Map
- Transaction
- Lock Strategies
- Metadata Mapping
Alternatively, should there be a repository class who's responsibility is to retrieve the data in question from the database, which can be then passed to the factory for assembly into the required product? The use of a repository class seems a bit excessive in this case as we have a class that will hold a large number of different pieces of data which then must be shipped into the factory class.
Repository is not a part of your data access layer, but of your domain layer. So it is client of your data access layer. It doesn't encapsulate any database access logic but uses the data mapper.
A repository encapsulates query logic for a particular domain model plus a collection of in-memory entities you've previously retrieved.
A very basic example:
class ProductRepository
{
private $productCollection;
public function findById($id)
{
if (!$this->productCollection->has($id)) {
$product = $this->dataMapper->get(new Query(Product::class, $id));
$this->productCollection->add($product);
return $product;
}
return $this->productCollection->get($id);
}
}
Finally, we can encapsulate database access logic in a table data gateway and use it in a factory. This would result in a solution similar to Gonen I's one. It is simple to implement but there might be cons compared to the data mapper solution. I've never implemented, used or even studied this approach so I can't tell much...
You'd definitely learn a lot by attempting to implement all that by yourself and I'd encourage you to, but keep in mind that if you need a serious solution, ORMs might be interesting for you.
If you're keen to learn more about all this, I recommend Martin Fowler's Patterns of Enterprise Application Architecture book which is summarized here: https://www.martinfowler.com/eaaCatalog/index.html
edited Nov 22 '18 at 11:04
answered Nov 21 '18 at 20:46
ClemC
405411
405411
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53408889%2fis-it-appropriate-for-a-factory-class-to-also-include-functionality-of-extractin%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown