What common methods are employed to separate data storage from algorithms? - oop

Say you store all your data in a class, likeKittenStorage. You then have a class that wants to find a specific color kitten, probably called KittenFinder. Obviously, you have designed your object oriented program to separate these two distinctly different classed, but now KittenFinder needs to directly interact with KittenStorage. How do you connect these two different classes?

You need to use layers. First of all, you need a Data Access Layer. This layer will contain classes which support direct data storage commands. Next, you need a Business Layer. This Layer performs anything needed to be performed in your business logic. This layer will use the data storage via the Data Access Layer. Optionally you can create an Engine Layer where some more complex algorithms might be implemented, which will communicate with the data storage via the business layer. Finally, you have the UI, which will communicate with your data storage through the Engine Layer or the Business Layer. In real-life your storage is a database and your Data Access Layer communicates with the database. I hope this was helpful.

Depends, some would put a Find Method on KittenStorage that returned a kitten.
Assuming KittenStorage is a Store for Kittens
And KittenFinder is a Finder for a Kittens or Kittens(s) in a KittenStorage
And that Kitten is a Storable and Findable Item
That also has some behaviours e.g. Scratch, that are nothing todo with it being storable and Findable, then Kitten would be linked to KittenStorage by IStorable, and KittenFinder to KittenStorage by IFindable
There's also a good reason to have a DTO (Data Transfer Object). Which would be simply Kitten's state, ie what you are finding and storing aren't Kitten's that scratch
Basically all the above is making the assumption that there's also a PuppyStorage and PuppyFinder etc, and that you want to be as decoupled as you can.

Lets evolve your example a bit - lets say that KittenStorage gives you a indexed access to the kittens in the form of storage.get(0) or storage[0], and that it also has a count or size property toknow how many kittens it stores.
This way KittenFinder can be implemented to do forward search i.e.
for (int i = 0; i < storege.size; i++)
{
//return kitten if matches
}
or it can do a BinarySearch
Also the KittenStorage class may include an persistence mechanism (like saving kittens to DB, or file). Maybe it can contain a perisitance strategy - a different class so that persistence mechanism could be swapped.
This is called Separation of Concerns - A class should do only one thing and only in one way - this way it's easy to maintain code.

In general terms, KittenFinder has a "dependency" on KittenStorage. Your question is how to set (inject) this dependency. That goes to your choice of application framework. Spring framework is one popular way of doing this.

Related

Design / Architecture for many instances OOP (or another) implementation

We want to write an API (Python Library) which provides information about few systems in our company. We really aren't sure what is the best OOP approach to implement what we want, so I hope you'll have an idea.
The API will expose a series of tests for each system. Each system will be presented as a Class (with properties and methods) and all systems will inherit from a base class (GenericSystem) which will contain basic, generic info regarding the system (I.E dateOfCreation, authors, systemType, name, technology, owner, etc.) Each system has many instances and each instance has a unique ID. Data about each system instance is stored in different databases, so the API will be a place where all users can find info regarding those systems at once. These are the requirements:
We want each user to be able to create an instance of a system (SystemName Class for example) and to be able to get some info about it.
We want each user to be able to create multiple instances of a system (or of GenericSystem) and to be able to get info about all of them at once. (It must be efficient. One query only, not one for each instance). So we thought that we may need to create MultipleSystemNames class which will implement all those plural-approach methods. This is the most challenging requirement, as it seems.
We want that data will be populated and cached to the instances properties and methods. So if I create a SystemName instance and calls systemNameInstance.propertyName, it will run needed queries and populate the data into propertyName. Next time the user will call this property, the data will be immediately returned.
Last one, a single system class approach must be preserved. Each system must be presented as a sole system. We can later create MultiSystem class if needed (For requirement 2) but at it's most basic form, each system must be represented singly (I hope you understand what I mean).
The second and the fourth (2,4) requirements are the ones that we really struggle to figure out.
Should we use MultiSystemNames class for each class and also for GenericSystem (MultiGenericSystems)? We don't want to complicate the user and ourselves.
Do you know any OOP (or another) best practice clean and simplified way? Have we missed something?
I'm sorry if I added some unnecessary information but I really wanted to give you a feel about how we want things to be.
If you've reach so far or not, thank you!
System and instance represents exactly the same think but are used in different contexts. It doesn't matter how you store or retrieve them. So if you need a collection of System you just use native collection data structure (e.g List, Queue, Map in java). The operations related to System/List must be decoupled from POJOs. That means you implement them in services, repositories,etc.
How you store and retrieve the data must not have impact on how you design your data structures. You achieve performance by applying different techniques and/or using proper technologies e.g caching, using key-value stores or nosql databases, denormalize relational database tables and/or using indexes,etc

"Cross-tree" inter-container communication between encapsulated objects

Encapsulation lends itself to hierarchical "silos" or "trees" of objects, with a given application's major functionalities decomposed into core trunks, each further decomposed into sub-functionalities instantiated as sub-branch member objects of their respective branches.
As an example, suppose I'm programming a GUI in QT. To separate GUI elements from business logic, for every widget I have a class for the GUI elements, a class for the business logic associated with the GUI elements, and what I'll call a controller which serves as a container for both and exists primarily to pass signals/slots in between. I understand this pattern to be called dependency injection.
Let's suppose our application has 2 windows A and B.
Window A contains 2 independent widgets that have separate business functions i and ii, so we might have the structure A::i and A::ii, where :: is "contains an instance of" and not "extends".
Then i and ii both contain gui and business logic units, so we have A::i::business and A::i::gui.
Now, suppose A::i::business and A::ii::business want to pass information between each other, or engage in bidirectional communication with the model-view for my database, identified as MV. Generally speaking, what are my options for doing this?
What I've thought of so far:
1) Pass signals up and down the tree, i.e., the Verilog solution. This seems the most strictly object oriented, but most tedious.
2) Have a flatter architecture to ease the implementation of solution 1). This hurts encapsulation.
3) Make A::i::business and A::ii::business public all the way down, and have either the other object or a third-party shared class access A::i::business or A::ii:business directly. This hurts encapsulation.
4) Have a relatively unencapsulated object, like the database MV or some other form of "shared storage", exist in a public form near the top level of the program with few/ no super-containers. This seems most appealing, as the relatively encapsulated objects can stay encapsulated and communicate through unidirectional reading/ writing to something that's unencapsulated. However, if I want other objects to perform actions based on changes shared storage, some way of notifying the dependent objects while keeping them private is necessary. This might be called the "multi-threading inspired" or "multi-processing inspired" model of communication.
And any other suggestions you all may have.
I've read this post here, but at my level of understanding, the solutions in the accepted answer such as controller, listener and pub-sub, refer to general design patterns that don't seem to commit to a solution for the concrete problem of how to route signals and make decisions about public/ private accessibility of member classes. It may be the case that these solutions have associated conventions for where the communication objects go and how they access the different variables in either silo that I'm not familiar with.
Most generally speaking, I seem to be running into a general problem of communication across container-trees in well-encapsulated programming.
For future reference, is there a general term for this problem to aide future searching? Is my architectural approach of having the object-container structure directly reflecting the tree-decomposition of application functionality lending itself to too hierarchical a design, and would a different pattern of object containment and cross-branch communication be more optimal?

Strategy for Sharing Business and Data Access Entities

I'm designing a layered application where 90% of the business and data access entities have the same properties. Basically it doesn't make sense to create one set of classes for each layer (and map) with the same properties for the sake of separation of concerns. I'm completely aware of automappers but I'd rather not use one in this case as I think it's unecessary. Is it ok to share share the business entities between the business and data access layer in this scenario? We will manage the remaining 10% of the classes by creating adhoc/transformed classes within the same namespace.
Any other design approach?
I think sharing between layers is the whole point of having model classes backed by a data store. I would avoid adding unnecessary architecture unless the code really needs it. If you get to a point where you need to be agnostic of the data store or some other similar situation, I would you might look into the Repository pattern. Simple code = maintainable code.

Model Object From Both Core Data & External Source

I am building an app where my primary model objects can either be fetched from a Core Data store or from an external source (public API via internet - > JSON - > object). I'm new to Core Data so my question is can I just take my model object as it stands now and make its superclass NSManagedObject? I'd guess that I'd need to make sure my model's properties match the names and types of the data model entities for this to happen. I don't want to have to use two different model objects in the app - one when I fetch from the core data store and one when I fetch from the internet API.
Is there anything else I'd need to do to make my already built model objects compatible for use with core data?
Any guidance or advice would be much appreciated.
Regards,
Craig
You can add some business logic to your object (subclass of NSManagedObject) to enable to creation of such an object from data (ie an NSDictionary of values to be used). The crux will be deciding whether you want those objects managed/saved to your local datastore or not.
I highly recommend becoming familiar with NSManagedObjectContext: http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/CoreDataFramework/Classes/NSManagedObjectContext_Class/NSManagedObjectContext.html
What I have done in a couple of products is just deal with core data objects, and initialize them from data that I pull from the web service. That way you only have apples. Another option would be to make a protocol that defines the behavior of the analogous classes. You would be tempted to make one the subclass of the other, but that could get complicated, depending on your persistence requirements.

Architecture for a business objects / database access layer

For various reasons, we are writing a new business objects/data storage library. One of the requirements of this layer is to separate the logic of the business rules, and the actual data storage layer.
It is possible to have multiple data storage layers that implement access to the same object - for example, a main "database" data storage source that implements most objects, and another "ldap" source that implements a User object. In this scenario, User can optionally come from an LDAP source, perhaps with slightly different functionality (eg, not possible to save/update the User object), but otherwise it is used by the application the same way. Another data storage type might be a web service, or an external database.
There are two main ways we are looking at implementing this, and me and a co-worker disagree on a fundamental level which is correct. I'd like some advice on which one is the best to use. I'll try to keep my descriptions of each as neutral as possible, as I'm looking for some objective view points here.
Business objects are base classes, and data storage objects inherit business objects. Client code deals with data storage objects.
In this case, common business rules are inherited by each data storage object, and it is the data storage objects that are directly used by the client code.
This has the implication that client code determines which data storage method to use for a given object, because it has to explicitly declare an instance to that type of object. Client code needs to explicitly know connection information for each data storage type it is using.
If a data storage layer implements different functionality for a given object, client code explicitly knows about it at compile time because the object looks different. If the data storage method is changed, client code has to be updated.
Business objects encapsulate data storage objects.
In this case, business objects are directly used by client application. Client application passes along base connection information to business layer. Decision about which data storage method a given object uses is made by business object code. Connection information would be a chunk of data taken from a config file (client app does not really know/care about details of it), which may be a single connection string for a database, or several pieces connection strings for various data storage types. Additional data storage connection types could also be read from another spot - eg, a configuration table in a database that specifies URLs to various web services.
The benefit here is that if a new data storage method is added to an existing object, a configuration setting can be set at runtime to determine which method to use, and it is completely transparent to the client applications. Client apps do not need to be modified if data storage method for a given object changes.
Business objects are base classes, data source objects inherit from business objects. Client code deals primarily with base classes.
This is similar to the first method, but client code declares variables of the base business object types, and Load()/Create()/etc static methods on the business objects return the appropriate data source-typed objects.
The architecture of this solution is similar to the first method, but the main difference is the decision about which data storage object to use for a given business object is made by the business layer, not the client code.
I know there are already existing ORM libraries that provide some of this functionality, but please discount those for now (there is the possibility that a data storage layer is implemented with one of these ORM libraries) - also note I'm deliberately not telling you what language is being used here, other than that it is strongly typed.
I'm looking for some general advice here on which method is better to use (or feel free to suggest something else), and why.
might i suggest another alternative, with possibly better decoupling: business objects use data objects, and data objects implement storage objects. This should keep the business rules in the business objects but without any dependence on the storage source or format, while allowing the data objects to support whatever manipulations are required, including changing the storage objects dynamically (e.g. for online/offline manipulation)
this falls into the second category above (business objects encapsulate data storage objects), but separates data semantics from storage mechanisms more clearly
You can also have a facade to keep from your client to call the business directly. Also it creates common entry points to your business.
As said, your business should not be exposed to anything but your DTO and Facade.
Yes. Your client can deal with DTOs. It's the ideal way to pass data through your application.
I generally prefer the "business object encapsulates data object/storage" best. However, in the short you may find high redundancy with your data objects and your business objects that may seem not worthwhile. This is especially true if you opt for an ORM as the basis of your data-access layer (DAL). But, in the long term is where the real pay off is: application life cycle. As illustrated, it isn't uncommon for "data" to come from one or more storage subsystems (not limited to RDBMS), especially with the advent of cloud computing, and as commonly the case in distributed systems. For example, you may have some data that comes from a Restful service, another chunk or object from a RDBMS, another from an XML file, LDAP, and so on. With this realization, this implies the importance of very good encapsulation of the data access from the business. Take care what dependencies you expose (DI) through your c-tors and properties, too.
That said, an approach I've been toying with is to put the "meat" of the architecture in a business controller. Thinking of contemporary data-access more as a resource than traditional thinking, the controller then accepts in a URI or other form of metadata that can be used to know what data resources it must manage for the business objects. Then, the business objects DO NOT themselves encapsulate the data access; rather the controller does. This keeps your business objects lightweight and specific and allows your controller to provide optimization, composability, transaction ambiance, and so forth. Note that your controller would then "host" your business object collections, much like the controller piece of many ORMs do.
Additionally, also consider business rule management. If you squint hard at your UML (or the model in your head like I do :D ), you will notice that your business rules model are actually another model, sometimes even persistent (if you are using a business rules engine, for example). I'd consider letting the business controller also actually control your rules subsystem too, and let your business object reference the rules through the controller. The reason is because, inevitably, rule implementations often need to perform lookups and cross-checking, in order to determine validity. Often, it might require both hydrated business object lookups, as well as back-end database lookups. Consider detecting duplicate entities, for example, where only the "new" one is hydrated. Leaving your rules to be managed by your business controller, you can then do most anything you need without sacrificing that nice clean abstraction in your "domain model."
In pseudo-code:
using(MyConcreteBusinessContext ctx = new MyConcreteBusinessContext("datares://model1?DataSource=myserver;Catalog=mydatabase;Trusted_Connection=True ruleres://someruleresource?type=StaticRules&handler=My.Org.Business.Model.RuleManager")) {
User user = ctx.GetUserById("SZE543");
user.IsLogonActive = false;
ctx.Save();
}
//a business object
class User : BusinessBase {
public User(BusinessContext ctx) : base(ctx) {}
public bool Validate() {
IValidator v = ctx.GetValidator(this);
return v.Validate();
}
}
// a validator
class UserValidator : BaseValidator, IValidator {
User userInstance;
public UserValidator(User user) {
userInstance = user;
}
public bool Validate() {
// actual validation code here
return true;
}
}
Clients should never deal with storage objects directly. They can deal with DTO's directly, but any object that has any logic for storage that is not wrapped in your business object should not be called by the client directly.
Check out CSLA.net by Rocky Lhotka.
Well, here I am, the co-worker Greg mentioned.
Greg described the alternatives we have been considering with great accuracy. I just want to add some additional considerations to the situation description.
Client code can be unaware about datastorage where business objects are stored, but it is possible either in case when there is only one datastorage, or there are multiple datastorages for the same business object type (users stored in local database and in external LDAP) but the client does not create these business objects. In terms of system analysis, it means that there should be no use cases in which existence of two datastorages of objects of the same type can affect use case flow.
As soon as the need in distinguishing objects created in different data storages arise, the client component must become aware about multiplicity of data storages in its universe, and it will inevitably become responsible for the decision which data storage to use on the moment of object creation (and, I think, object loading from a data storage). Business layer can pretend it is making this decisions, but the algorithm of decision making will be based on type and content of the information coming from the Client component, making the client effectively responsible for the decision.
This responsibility can be implemented in numerous ways: it can be a connection object of specific type for each data storage; it can be segregared methods to call to create new BO instances etc.
Regards,
Michael
CLSA has been around a long time.
However I like the approach that is discussed in Eric Evans book
http://dddcommunity.org/