Design approach (Domain driven or Service Driven) - java

My problem statement is :
I want to write design file management (add, copy, delete etc. operations). There are two approach :
Service Driven approach
Write file VO which contains only file attributes. For e.g.
public Class File {
private boolean hidden;
private boolean read;
private boolean write;
public boolean isHidden() {
return hidden;
}
public void setHidden(boolean hidden) {
this.hidden = hidden;
}
public boolean isRead() {
return read;
}
public void setRead(boolean read) {
this.read = read;
}
public boolean isWrite() {
return write;
}
public void setWrite(boolean write) {
this.write = write;
}
}
and separates service for File related operations. For e.g. :
public Class FileService {
public boolean deleteFile(File file) {
//Add delete logic.
}
//Same way you can add methods for Add and copy file.
}
Domain Driven approach (I might be wrong here.)
Where file VO contains all the attributes plus required operations :
public class File {
private boolean hidden;
private boolean read;
private boolean write;
public boolean isHidden() {
return hidden;
}
public void setHidden(boolean hidden) {
this.hidden = hidden;
}
public boolean isRead() {
return read;
}
public void setRead(boolean read) {
this.read = read;
}
public boolean isWrite() {
return write;
}
public void setWrite(boolean write) {
this.write = write;
}
public boolean deleteFile() {
//Add delete logic.
}
//Same way you can add methods for Add and copy file.
}
So what are the pros and cons of both the approach ?

In an object oriented language, putting the logic in the class itself, rather than a service class, is the typical approach (and better IMO). It follows the "tell, don't ask" principle, for example, by telling a File to delete itself, rather than asking some service to delete it. One of the main reasons behind this is to allow for inheritance. For example, if you have a subclass of File and wanted to have it write a log message before it was deleted, that would be difficult to do with a service class because you would need a different service class for every subclass.
In terms of a service-oriented approach, this is typically thought of at a higher level (i.e. a service oriented architecture). Consider a financial stock system, you might have a "buy stock" service and a "sell stock" service. Have a service class that corresponds to individual classes (i.e. a Stock service, which knows how to buy and sell stocks) wouldn't be very object oriented.
You might also have a service layer in your system, which provides integration points with other external services (i.e. a database), but again, I don't think this is what you're talking about here. So, I could stick with the approach of encapsulating the logic in the File class itself.

Without much information about what kind of system your are desigining it's hard to pronounce. To me, the choice depend on the system boundaries.
If you need to offer an API that is exposed as a service and accessible to external consumer, go for solution 1, that's the only way. If you system is rather an library whose API will be used internally by other applications, go for a rich domain model as in solution 2, it's a lot more OO. You don't want to bloat your API with service-, manager-, and utility classes for which no real reason exist.
But again, without knowing your final goal, it's hard to say.

Related

Java abstract Step Builder pattern

I am designing a java system where users can define some rules in a fluent style.
Rules have many properties, which are partly mutually exclusive.
We use a builder pattern with validation for this.
To make the system easier to use, we want to introduce a StepBuilder, to guide the user to all necessary steps.
There are different types of rules, but all share some common properties.
Current System:
abstract BaseBuilder<T extends BaseBuilder<T>> {
protected String property1;
protected String property2;
protected String property3;
abstract Rule build();
public T withProperty1(String data) {
this.property1 = data;
return this;
}
public T withProperty2(String data) {
this.property2 = data;
return this;
}
public T withProperty3(String data) {
//this should only be possible if property2 is not set or similar logic
this.property3 = data;
return this;
}
}
//there are a few others like this e.g. SpecialBuilder1-10
class SpecialRuleBuilder extends BaseBuilder<SpecialBuilder> {
protected String special1;
protected String special2;
public T withSpecial1(String data) {
this.special1 = data;
return this;
}
public T withSpecial2(String data) {
this.special2 = data;
return this;
}
#Override
Rule builder() {
return new SpecialRule(property1, property3, special1, special2, ....);
}
static SpecialRuleBuilder builder() {
return new SpecialRuleBuilder();
}
}
class BuilderTest() {
//User can set anything, no steps are enforced at compile time
Result result = SpecialBuilder.builder()
.property1("some")
.special2("thing")
.build();
}
How can we use a StepBuilder including a hierarchy (parent class), so the user cannot get to the same step twice cannot accidentally go back to a previous base step and set some mutually exclusive properties again.
Ideally the user should not be aware of all the special builders and have the same entry point and guided steps. For example:
Result result = GeneralBuilder.builder()
.withBaseProperty1("asdas") <-- Step 1
.withBaseProperty2("asd") <-- Step 2, Step 3 is now not visible, continue with all possible special options
.withSpecial1("asd") <-- no we are in the step of one concrete builder, and should not get "out" again, not even to the base methods
I know how to define the interface steps, I just dont know how to include all possible starting steps of the special builders at the end of the base steps, since the higher interface/class should probably not rely on the lower parts of the hierarchy.
Is this somehow possible?
This is a bad idea; the sheer amount of code you need to write is staggering. Also, whilst the appeal of a guided 'auto-complete' experience in an IDE is obvious, realize that sometimes builders are used in a more fluent (heh) fashion: Some code makes a builder, sets half the stuff, and then returns the builder so that other code can pick up where it left off. Or, a utility method that takes a builder as param, and sets a few things on it. These use cases become awkward to impossible when you go down this path. So, you spend a ton of time writing this code and it's not even a clean win, API-wise!
If you want to ignore my advice and do it anyway, well, okay. Your funeral. A warned person counts for two, and all that. It looks like this:
public interface BridgeBuilder1 {
public BridgeBuilder2 name(String name); // mandatory
}
public interface BridgeBuilder2 {
public BridgeBuilder3 buildYear(int year); // mandatory
}
public interface BridgeBuilder3 {
// one of these two is mandatory, and they are mutually exclusive.
public BridgeBuilder4 lanes(int lanes);
public BridgeBuilder4 width(int widthInM);
}
public interface BridgeBuilder4 {
// optional stuff, and the build itself.
public BridgeBuilder4 color(Color c);
public BridgeBuilder4 country(String name);
public Bridge build();
}
// intentionally private class! Should be an inner class
// of your public Bridge class.
private static class BridgeBuilder implements BridgeBuilder1, BridgeBuilder2, BridgeBuilder3, BridgeBuilder4 {
private String name;
public BridgeBuilder2 name(String name) {
this.name = name;
return this;
}
// the fluent, chaining 'setters' for _ALL_ properties here.
// Match the return types exactly to how they
// are defined in the interfaces.
public Bridge build() {
return new Bridge(name, year, ....);
}
}
...
public class Bridge {
Bridge(String name, ...) {
// a package private constructor.
}
public static BridgeBuilder1 builder() {
return new BridgeBuilder();
}
}
That should be sufficient to highlight how this works.
But don't.
NB: The actually good solution is to enshrine the notion of a builder into the editor/lang tooling itself. An eclipse or intellij plugin, in other words. Annotations can be used to identify everything (annotate a builder() method to indicate it makes a builder, annotate a class that it is a builder class, etc), then annotate each method in a builder as being optional or not, and as being multiple or not (imagine a builder method that is intended to be invoked multiple times to e.g. fill a list). Armed with that info a plugin can 'fix' the auto-complete dialog to skip all the crap from j.l.Object, and to show all mandatory fields in bold, all already-set stuff greyed out, all optionals in normal colour, and the build method greyed out until all mandatories are set, and bold once they are. That's the real solution. I invite anybody to write these plugins instead of wasting time maintaining this ridiculous-length API extravaganza to create a hampered take on the idea.

OO design - is this design flawed?

I am creating a logic for web application to managing consents from user.
The model class that is persisted in the DB will have multiple fields, from which only a set will be changed with user request. E. g. class will have 10 fields with various consents, but user will be willing to change only 2 of those. To avoid writing a big chain of if-else's I designed this classes, to harness polymorphism to do the job for me, but somehow this design seems flawed to me. Could you tell me if this is proper way to do it?
PROBLEM: Change values of only subset of fields from large set of fields in class.
For sake of simplicity I removed getter/setters methods and some fields.
Main logic for changing consents:
public class GdprServiceImpl implements GdprService {
private final ConsentRepository consentRepository;
#Autowired
public GdprServiceImpl(ConsentRepository consentRepository) {
this.consentRepository = consentRepository;
}
#Override
public void changeConsent(User user, List<ConsentDto> consents) {
Optional<Consent> optionalConsent = consentRepository.findByUser(user);
if(optionalConsent.isPresent()) {
Consent consent = optionalConsent.get();
for(ConsentDto consentDto : consents) {
consentDto.apply(consent);
}
consentRepository.save(consent);
}
else {
Consent consent = new Consent();
consent.setUser(user);
for(ConsentDto consentDto : consents) {
consentDto.apply(consent);
}
consentRepository.save(consent);
}
}
Model class:
public class Consent {
private Boolean messageConsent;
private Boolean recordConsent;
/*CONSTRUCTOR, OTHER METHODS AND FIELDS OMITTED*/
}
Classes that will change a set of fields from Consent class:
public abstract class ConsentDto {
public abstract void apply(Consent consent);
}
public class RecordConsentDto extends ConsentDto {
private boolean consentValue;
public RecordConsentDto(boolean consentValue) {
this.consentValue = consentValue;
}
#Override
public void apply(Consent consent) {
consent.setRecordConsent(consentValue);
}
}
public class MessageConsentDto extends ConsentDto {
private boolean consentValue;
public MessageConsentDto(boolean consentValue) {
this.consentValue = consentValue;
}
#Override
public void apply(Consent consent) {
consent.setMessageConsent(this.consentValue);
}
}
You are right about the design having a "smell".
This is because the DB design is not normalized.
having a list of consents in one record is an indication. while technically it is allowed, classic RDBMS design dictatets that arrays should be represented as either one-to-many or many-to-many relation between tables. Of course, same in the object model.
a Fully normalized solution will have a consent_catalog table and many-to-many relation to users:
table consent_catalog {
int id // PK
String name
}
The catalog acts as "consent enum", having one row per type of consent (record, message, etc)
table user_consents {
int user_id references users(id)
int consent_id references consent_catalog(id)
}
This table has rows only for consents accepted by the user. no "false" consents. This design opens up new possibilities like knowing which users have a specific consent or mulitple consents in common.
This design feels like an overkill. At the end of the day you are always calling consent.setMessageConsent() or similar it's wrapped with an enum field and a class implementing ConsumerDto (which is really a Consumer). Generally DTO are not supposed to implement business logic yet one could argue that apply method is one.
It really would be cleaner to have UserConsent POJO with Boolean fields. The exception would be if triggering one consent should trigger other but it's not clear from your example.
Just my two cents. I'd prefer to see either an anemic POJO passed around or DDD aggregate root for user that manages consents but not something in between.

how to determine if a method has been overriden?

Consider the following scenario:
I am working on a framework that allows users to subclass a particular abstract class provided by the framework, which will allow them to insert their own functionality into the flow of the application.
For example a class like this:
public class MyAbstractClass {
protected String step1(String input) {
// default implementation
}
public final void process(MyObject objct) {
// some steps
String someData = step1(object.getInput());
// some more steps
}
}
Now, in a newer version of the framework, I want to change the step1 method to use some object (which can be converted to the argument of the current step1 method) as a parameter. However, I do not want to break the code for the users who have already extended this class.
I am currently planning to do it this way:
public class MyAbstractClass {
private boolean isOldStep1Overriden = true;
protected String step1(MyObject input) {
String oldValue = step1(input.getInput());
if (isOldStep1Overriden) {
// the method has been overriden - some logic here to handle this (assume this logic is known)
} else {
// the method has not been overriden - ignore the old value and carry out the new default processing
}
}
#Deprecated
protected String step1(String input) {
// default implementation
isOldStep1Overriden = false;
}
public final void process(MyObject objct) {
// some steps
String someData = step1(object);
// some more steps
}
}
Are there any other ways to implement such a use case?
The following options are also on hold :
Create a new abstract class for the new implementation - This would prevent existing users from getting the new features without modifying their code.
Use reflection - I would prefer not to, if possible
EDIT: Some more relevant background information:
The framework in question is actually an application which is deployed to a shared location, and users (developers) of this framework submit extensions to be installed in it. So the application itself could be upgraded without the developers of the extensions having made any changes to their code. To take an example of a similar system, consider firefox and its addons - both developed by separate teams, and firefox can be updated without the addon developer's knowledge.

Force a user of my library to implement an interface or extend an abstract class

I'm developing an android library (.aar) and I was wondering if it was possible to, as the title suggest, force a user to implement an interface or extend an abstract class of my library.
I already know that I could just go with a class like this in my library :
public class MyLibrary
{
public interface VariablesInterface
{
void createVariables();
}
private static VariablesInterface vi = null;
public void setVariablesInterface(VariablesInterface v)
{
vi = v;
}
private static void SomeWork()
{
if (vi == null)
{
throw new RuntimeException("You noob.");
}
else
{
// do work
}
}
}
The library will work "alone" at some point, and when it will come to SomeWork(), if the interface isn't implemented it will crash, but this could only be seen at runtime.
Is there a way to have this behaviour when compiling the user's application ?
The goal is to avoid the user forgetting that he have to implement this without having to write it in the documentation and hope the user will probably read it.
Thanks for reading !
EDIT
I think that this question need some enhancement and background.
The purpose of the library is to provide classes that create variables which manages preferences, e.g. :
public class VarPreferenceBoolean extends VarPreference
{
private boolean defaultValue;
public VarPreferenceBoolean(String key, boolean defaultValue)
{
super(key, true);
this.defaultValue = defaultValue;
}
public void setValue(Context context, boolean value)
{
SharedPreferences.Editor e = context.getSharedPreferences(PropertiesManager.preferenceFileName, Context.MODE_PRIVATE).edit();
e.putBoolean(key, value);
e.commit();
}
public boolean getValue(Context context)
{
readPropFile(context);
SharedPreferences sp = context.getSharedPreferences(PropertiesManager.preferenceFileName, Context.MODE_PRIVATE);
return sp.getBoolean(key, defaultValue);
}
}
The same goes for int, string and so on.
In the super class, I add each VarPreference to a List to keep the library acknowledged of all the variables availables.
Note the readPropFile inside the getter.
Then, the user use the library in his project like this :
public class Constants
{
public static final VarPreferenceInt FILETYPE;
public static final VarPreferenceInt DATAMODE;
public static final VarPreferenceString URL_ONLINE;
public static final VarPreferenceBoolean UPDATING;
public static final VarPreferenceLong LAST_UPDATE;
static
{
FILETYPE = new VarPreferenceInt("FileType", MyFile.FileType.LOCAL.getValue());
DATAMODE = new VarPreferenceInt("DataMode", DataProvider.DataMode.OFFLINE.getValue());
URL_ONLINE = new VarPreferenceString("UrlOnline", "http://pouetpouet.fr");
UPDATING = new VarPreferenceBoolean("Updating", false);
LAST_UPDATE = new VarPreferenceLong("LastUpdate", 0L);
}
}
Now, when the user call an accessor, readPropFile will first search if a .properties file exist and modify accordingly the preferences if it found matches between the list of VarPreference and the properties of the file. Then it will delete the file and the accessor will return the value.
This is what exists today.
Now we want another application (let's say Pilot) to be able to get the VarPreferences of the user's application (let's say Client). Both implements the library.
Pilot send an Intent asking for the VarPreference list of Client, putting in extra the package name of Client.
The library receive the intent, verify the packagename, if it's Client it send back the list.
Problem is, if Client hasn't started, no VarPreference exists, and the list is empty.
I need to force the user to create his VarPreference in an method that my library know, to be able to call it whenever I want, and create the VarPreferences of the user when it's necessary.
Hope this is clearer !
EDIT
I rethought about all of this with a colleague and it just hit us that all this stack is biaised.
I didn't explain well and even if I said it, I didn't take account enough of this : everything needs to be done from the library.
So, even if I give an interface to the library, the application will have to run and call this affectation first in order to let the library work alone.
We are heading towards introspection now.
(This is the goal, it may not be possible...)
There will be an abstract class inside the library, with an abstract method where the user will place all of the VarPreferences creations. The user will have to extends this class and call the method in order to create his VarPreferences.
In the library, a method will search by introspection a child of the abstract class, create an instance of this child and call the method that will create the VarPreferences.
I would leave the abstract classes and interfaces in the main library and load the rest of your code via classloader from another. JDBC works like this.
Is there a way to have this behaviour when compiling the user's application ?
I see no way to force a compilation failure. However, if you force them to supply a VariablesInterface in the constructor then it will fail immediately. Make the VariablesInterface be final and only initialize it in the constructor:
public class MyLibrary {
private final VariablesInterface vi;
public MyLibrary(VariablesInterface vi) {
if (vi == null) {
throw new IllegalArgumentException("vi can't be null");
}
this.vi = vi;
}
...
If you can't change the constructor then you can also add to any SomeWork public methods some sort of configuration check method to make sure the the vi wiring has properly been done but this requires careful programming to make sure all public methods are covered.
public void somePublicMethod() {
checkWiring();
...
}
private void checkWiring() {
if (vi == null) {
throw new IllegalStateException("vi needs to be specified");
}
}

How to implement individual access of one class by two other classes, in Java? [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicates:
‘Friends’ equivalent for Java?
Is there a way to simulate the C++ ‘friend’ concept in Java?
In C++ there is a concept of a "friend", which has access to a class's private variables and functions. So if you have:
class Foo {
friend class Bar;
private:
int x;
}
then any instance of the class Bar can modify any Foo instance's x member, despite it being private, because Bar is a friend of Foo.
Now I have a situation in Java where this functionality would come in handy, but of course it doesn't exist in Java.
There are three classes: Database, Modifier, Viewer. The Database is just a collection of variables (like a struct). Modifier should be "friends" with Database; that is, it should be able to read and write its variables directly. But Viewer should only be able to read Database's variables.
How is this best implemented? Is there a good way to enforce Viewer's read-only access of Database?
There are varying opinions on how pure you should be, but to me you shouldn't give anyone access to any fields. Use getters and setters.
If you need to segregate who can read and who can write, you can throw interfaces into the mix. Define an interface with just the getters and you can restrict your viewer to read only.
Robert Harvey added a comment that points to other options, like using a different access modifier for class or package level access.
I don't think this is a good way to implement such a thing.
You should have a data access layer that hides the database. It should expose CRUD operations.
Start with interfaces. Create a ReaderDao that only has finder methods. Then create a GenericDao that extends the ReaderDao and adds the save, insert, and delete methods.
Implementation classes should implement one interface or the other as needed.
Neither one needs to expose the fact that it's a relational database behind the scenes.
An inner class has access to all the private members of its container class. Make your getters public and your setters private, make Modifer an inner class of Database. Also make it only creatable from inside of Database through a Factory Method pattern. Probably needs to be a Singleton as well.
A package local class is about as close to a "friend" in C++. Make all your getters public, make your setters package local. Make Modifier be in the same package as Database. The first example is cleaner.
The other idiom is applicable is the Memento pattern.
Are you sure this is a good pattern? It directly circumvents encapsulation, one of the main tennets of OO design.
You could create a nested class.
Imagine you have the ViewClass like this:
class Viewer {
Database db;
Viewer( Database db ){
this.db = db;
}
public void whatIsX(){
System.out.println( db.x() );
}
}
And define a modifier with a method to modify that database.
abstract class Modifier {
public void manipulate();
}
You can create the Database with an nested class which have access to the private member, pretty much like friend.
class Database {
private int x;
class DatabaseModifier extends Modifier {
public void manipulate(){
x++;
}
}
public int x(){
return x;
}
}
// To see if works:
class Main{
public static void main( String [] args ) {
Database database = new Database();
Modifier modifier = database.new DatabaseModifier();
Viewer viewer = new Viewer( database );
viewer.whatIsX();
modifier.manipulate();
viewer.whatIsX();
}
}
You can also opt for a static inner class. It could be like this:
class Viewer {
Database db;
public Viewer( Database db ){
this.db = db;
}
public void whatIsX(){
System.out.println( db.x() );
}
}
class Modifier {
Database db;
public Modifier( Database db ){
this.db = db;
}
public void manipulate(){
//db.x++; doesn't work because db.x is private
}
}
class Database {
private int x;
static class DatabaseModifier extends Modifier {
public DatabaseModifier( Database db ){
super(db);
}
#Override
public void manipulate(){
db.x++;
}
}
// public accessor to attribute X
public int x(){// should be getX()
return x;
}
}
class Main{
public static void main( String [] args ) {
Database database = new Database();
Modifier modifier = new Database.DatabaseModifier( database );
Viewer viewer = new Viewer( database );
viewer.whatIsX();
modifier.manipulate();
viewer.whatIsX();
}
}
If you want this kind of access, create an interface to the class that encapsulates the methods you intend to allow only a select few to call. Then create a method where the class passes a private instance of the interface only if the requesting class meets whatever criteria you impose.
A simple example, written with tongue firmly in cheek:
public class Husband {
private Spouse wife;
private int cashInWallet;
public Husband(Wife wife) {
this.cashInWallet = 20;
this.wife = wife;
}
public WalletAccess getWalletAccess(Object other) {
if (other instanceof Wife) {
return new WalletAccessImpl(this);
}
return null;
}
public interface WalletAccess {
public int withdrawCash(int requested);
}
private WalletAccessImpl implements WalletAccess {
private Husband hubby;
private WalletAccessImpl(Husband hubby) {
this.hubby = hubby;
}
public int withdrawCach(int requested) {
if (this.hubby.wallet > requested) {
this.hubby.wallet -= requested;
return requested;
} else {
int allCash = this.hubby.wallet;
this.hubby.wallet = 0;
return allCash;
}
}
}
public class Wife {
private Husband husband;
public Wife(Husband husband) {
this.husband = husband;
}
public void consumeCash() {
Husband.WalletAccess access = husband.getWalletAccess(this);
int cash = access.withdrawCash(20);
}
}
More complex examples are possible, but this improves on the friend access pattern, as even individual instances of the "would-be" friend class could be singled out for access (or refusal). For example, it would be trivial to check that the Wife was actually married to this particular husband in this case by rewriting getWalletAccess(...) like so:
public WalletAccess getWalletAccess(Object other) {
if (other instanceof Wife) {
Wife someone = (Wife)other;
if (someone.getHusband() == this) {
return new WalletAccessImpl(this);
}
}
return null;
}
I'd say interfaces are definitely the solution for your problem.
To start with, don't allow anything else to have access to the actual fields of Database. Create methods that each return one of its fields. Then, make DatabaseView an interface that declares each of these methods for reading. Then have Database implement DatabaseView. Finally, you can add methods for writing (setting) the fields that should be settable to Database.
When you have some class that needs to be able to read from the database, such as your Viewer, have it take a DatabaseView. You can then pass in the Database instance itself, but that class will not know about the methods for writing to it. If something else needs to both read and write, such as your Modifier, you can just give it the Database itself. Better yet, Database itself could be an interface that extends DatabaseView and your actual implementation object could be some class that nothing needs to know about.
You should rethink how much seperation you really want, this "Modifier should be "friends" with Database; that is, it should be able to read and write its variables directly." is impossible in Java - there can't be different access privileges for direct field accesses.
I assume what you really want is to strongly discourage undesirable access patterns. There are a few ways how this can be achieved:
1.) Put Modifier and Database in the same package and make the "Setters" package protected, thus the set-methods become invisible to your Viewer (as long as Viewer is not in the same package). This is more or less impractical for larger designs.
2.) Seperate the concerns into completely different Projects. Then you can set the projects dependencies that only Modifier gets access to Database at all. This implies that you change your design somewhat, either Database becomes two projects (one with the public-readonly interface and one with the full-access interface), or remove the dependency between Viewer and Database completely and make Viewer access Database only through Modifier. This solution has the advantage that its physically impossible to violate access boundaries (It will not compile in the build).
3.) A solution closer to the actual "friend" class concept would be to have two interfaces, one for read, one for write and Database implements those interfaces using inner classes. Then you can "guard" access to the inner class instances with getters that take the client as an argument like this:
public class Database {
public DatabaseReadAccess getReadAccess(Viewer viewer) { ... }
public DatabaseWriteAccess getWriteAccess(Modifier modifier) { ... }
}
This will not prevent a malicious access, but somewhat discourage them. If you want to go one step further, define "Token" classes for Viewer and Modifier and require the token instance for the access getters in Database (then the compiler will enforce the restrictions):
public class ModifierToken {
ModifierToken(Modifier modifier) {
// constructor is package protected, so no outsiders can create tokens!
}
}
I personally would go with the "separate projects" approach, it makes undesirable accesses obvious and violations pop up at latest in the build. I've never tried the "token" approach myself.

Categories

Resources