Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I have implemented a series of classes to manage search / detail page with JSF and PrimeFaces.
More in detail, I've created an abstract class SearchDetailView<C extends BaseView, M> in order to centralize common functionality for Search/Detail page.
In short, I've a class MyView that extends the base SearchDetailView.
Now I'd like to add another behavior to MyView, that is Confirm Dialog.
I'm wondering what design pattern I have to use? I was going to use the design pattern Decorator, but I don't need to add new behaviors at runtime, but I've already know what behaviors MyView needs.
I can't extends two classes (obviously), but I didn't like to have many combinations of "base" classes. I'd like to create a second abstract class like ConfirmDialogDecorator in order to add "programmatically" the extra functionality.
So, I ask you which design pattern add behavior to a class?
Actually my code is like the following:
public abstract class SearchDetailView<C extends BaseController, M> extends BaseView {
[...]
}
public abstract class ConfirmDialogDecorator<C extends BaseController, M> extends SearchDetailView<C, M> {
public void showDialog(final String message) { [...] }
}
public class MyView extends ConfirmDialogDecorator<MyController, MyModel> {
[...]
}
But I'd like to separate ConfirmDialogDecorator from SearchDetailView.
Any idea? Thanks.
UPDATE:
As suggested in the two answers I used the Java 8 default methods (Mixin pattern?):
public interface ConfirmDialog {
Dialog dialog = new Dialog();
default public String getConfirmMessage() {
return "Do you confirm?";
}
default String getWidgetVar() {
return "confirmDialog";
}
public void onConfirm();
default void showDialog(final String message) {
dialog.setWidgetVar(this.getWidgetVar());
dialog.setMessage(message);
dialog.showDialog(message);
}
class Dialog {
private String message;
private String widgetVar;
String getMessage() {
return message;
}
void setMessage(final String message) {
this.message = message;
}
public String getWidgetVar() {
return widgetVar;
}
public void setWidgetVar(final String widgetVar) {
this.widgetVar = widgetVar;
}
void showDialog(final String message) {
final PrimeFaces current = PrimeFaces.current();
current.executeScript("PF('" + this.widgetVar + "').show();");
}
}
}
public class MyView extends SearchDetailView<MyController, MyModel>
implements ConfirmDialog {
public void onSave() {
if(!this.someCheck()) {
this.showDialog("Are you really sure?");
} else {
this.save();
}
}
#Override
public void onConfirm() {
this.save();
}
public void save() {
// The save
}
}
In the xhtml:
<p:confirmDialog widgetVar="confirmDialog" global="true">
<h:outputText value="#{myView.confirmMessage}" />
<p:commandButton value="Yes" type="button" styleClass="ui-confirmdialog-yes" icon="pi pi-check" />
<p:commandButton value="No" type="button" styleClass="ui-confirmdialog-no" icon="pi pi-times" />
</p:confirmDialog>
I was going to use the design pattern Decorator, but I don't need to
add new behaviors at runtime, but I've already know what behaviors
MyView needs.
and then
I'd like to create a second abstract class like ConfirmDialogDecorator
in order to add "dynamically" the extra functionality.
Don't you say a thing and its contrary ?
The fact that you know decorating possibilities at compile time doesn't mean that the pattern is not adapted.
But I'd like to separate ConfirmDialogDecorator from SearchDetailView.
Decorator is also a alternative to subclassing and avoid classes hierarchies.
Using the pattern by introducing a decorator interface is probably a right way for your requirement.
As alternative Java 8 introduced the notion of default methods in interfaces that allows to add behaviors to classes implementing it.
In a some way, we can consider it as a way to decorate statically classes with additional behaviors without subclassing. Note that as interfaces cannot define instance fields, default methods cannot use it either. So you should consider this alternative according to this constraint.
Usually to add functionality to a class without inheritance be used mixim/trait conception.
You can use default methods or aspect-objected programming in Java to the implementation of this conception
Related
I have an enum from a common Library (it cannot be changed) as a field from a Class.
I need to use that enum values as a switch-case in order to do something accordingly (for example save some data to a database).
This is for a Java 11 micro-service using Spring as a framework.
What I did before knowing the enum has to stay immutable, I avoided an ugly switch case with an overridden abstract function inside the enum like this:
public enum InvoiceStatus {
DRAFT {
#Override public void action(InputMessage inputMessage) {
invoiceFileService.draft(inputMessage);
}
},
VALID {
#Override public void action(InputMessage inputMessage) {
invoiceFileService.valid(eiInvoiceFileMessage);
}
},
NOT_VALID {
#Override public void action(InputMessage inputMessage) {
invoiceFileService.notValid(eiInvoiceFileMessage);
}
};
//+20 more values...
#Autowired
InvoiceFileService invoiceFileService;
public abstract void action(InputMessage inputMessage);
}
and I simply called the enum like this, so with different values from the enum the called function from the service would be different without writing a long switch-case.
invoice.getStatus().action(inputMessage);
Now the new requirement needs the enum to live inside a common library so it can refer to InvoiceFileService class which will be only local to my project.
I tried different options like HashMaps but the code went ugly and un-maintainable.
Is there a clean way to extend the simple enum (with only values definition) and add to it the abstract function to do stuff? maybe java 8 added some new way to do this.
You could create a wrapper enum.
public enum WrappedInvoiceStatus {
DRAFT(InvoiceStatus.DRAFT, this::someAction),
// other values
private WrappedInvoiceStatus(InvoiceStatus status, Action action) {
this.status = status;
this.action = action;
}
private interface Action { // can be one of Java default functional interfaces as well
void doSomething(InputMessage msg);
}
private void someAction(InputMessage msg) {
// behavior
}
// some plumbing required
}
Basically I’m suggesting using wrapping and lambda expressions or method references. The world of functional programming takes some getting used to. Not everyone is a fan. Your mileage may vary.
As others already said, you can not extend the enum at runtime.
But an enum can implement an interface.
So the basic idea is:
You make an interface with the action as sole abstract method:
public interface InvoiceAction {
void action(InputMessage message);
}
Your enum implements that interface
public enum InvoiceStatus implements InvoiceAction {
// ... no other changes needed
}
In all the cases where you only need to use the actual action, change InvoiceStatus to InvoiceAction. This is the most risky change. Make sure to recompile all code.
Because InvoiceAction only has one abstract method, it's a functional interface, and can be implemented with a lambda expression:
invoice.setStatus(msg -> ...);
This change is probably the most invasive change, but it might be the right thing to do - if you need a different action next time, you won't have the same problem as today.
Enum type is not extendable and implicitly final as specified in JLS:-
An enum declaration is implicitly final unless it contains at least one enum constant that has a class body (§8.9.1).
Hence a class could not extends an enum type. However you could use wrapper or adapter pattern to add additional behaviours/fields of the enum. For example:-
#Service
public class SimpleInvoiceFileService implements InvoiceFileService{
private final InvoiceStatus invoiceStatus;
public SimpleInvoiceFileService(InvoiceStatus status){
invoiceStatus = status;
}
#Override
public void draft(InputMessage input){
this.invoiceStatus.action(input);
}
#Override
public void valid(InputMessage input){
this.invoiceStatus.action(input);
}
// Add more methods to InvoiceFileService interface
// as required and override them here.
}
JLS Reference:-
https://docs.oracle.com/javase/specs/jls/se11/html/jls-8.html#jls-8.9
We are trying to implement the MVP pattern. Because it requires quite a lot of code just to have a functioning view, we try to use inheritance as much as possible. As I am pretty new to Java, I don't know exactly if I'm doing it right:
So, I started with a very simple Interface which all the views will implement (and the `getName`` method will be used for breadcrumb Feature):
public interface IView {
public String getName();
}
On top of that, I built a BaseView which will be used for most views:
public interface IBaseView extends IView {
public void addListener(IBaseViewListener l);
interface IBaseViewListener {
void viewEntered(Long id);
}
}
And the implementation
public class BaseView extends CustomComponent implements View, IBaseView{
private String name = "";
private List<IBaseViewListener> listeners;
public BaseView(String name) {
this.name = name;
listeners = new ArrayList<IBaseViewListener>();
buildLayout();
}
#Override
public void addListener(IBaseViewListener l) {
listeners.add(l);
}
protected void buildLayout() {
this.setId("base_view");
// initialize layout....
}
#Override
public void enter(ViewChangeEvent event) {
for (IBaseViewListener l : listeners) {
l.viewEntered(id);
}
}
#Override
public String getName() {
return name;
}
}
And last we have a ScaffoldingView which will be used for some views (mainly for mocking):
public interface IScaffoldingView extends IBaseView{
public void showTable(AbstractComponent t);
interface IScaffoldingViewListener extends IBaseViewListener {
void itemSelected(DataBaseObject selectedObject);
}
}
And the implementation:
public class ScaffoldingView extends BaseView implements IScaffoldingView{
private AbstractComponent table = null;
public ScaffoldingView(String name) {
super(name);
}
#Override
protected void buildLayout() {
// here is a lot more code...
}
public void showTable(AbstractComponent t) {
// here is a lot of code...
}
}
First of all:
- Does that approach make any sense? especially the access modifiers. I'm totally weak when it Comes to polymorphism :(
I am very unsure about the handling of the EventListeners. For example: In the constructor of the BaseView, I am implementing the addListener function.
Now, in the ScaffoldingView's, there will be a specialized IScaffoldingViewListener. Will the super class (BaseView) addListener() method be able to handle These IScaffoldingViewListeners?
edit: Sorry, I forgot to mention that View and CustomComponent are some classes of a 3rd Party Framework (Vaadin) which we use and which offer the enter Event in which we call the eventListeners (Presenter).
First, declaring an interface inside another interface is not quite clean, obscures the code quite a bit.
Second, about BaseView which extends CustomComponent, and implements IView and IBaseView, first a small detail, if it implements IBaseView, you do not need to implement IView, as IBaseView already extends IView, but the bigger issue i see is:
If you have a somewhere in some class, a method with an IBaseView as a parameter, but inside that function you expect to be able to use the overrided methods from CustomComponent, you won't be able to, you'll only have the methods declared on IBaseView.
If you wanted to use the CustomComponent methods, you'd had to do a cast inside that method, but that is not clean and a source of bugs, because if in the future, you add more classes that implement IBaseView but do not extend CustomComponent, that function will throw exceptions complaining about casting.
Also, about the ScaffoldingView, if you are going to use it only for mocking purposes in tests and you are extending the IBaseView behaviour, with more methods, if you test a method that has an IBaseView as parameter, you have the same exact situation as before, the method you are testing will not be aware of the IScaffoldingView declared methods, and then it won't use them, and your tests can't be trusted.
P.D.: if you are interested in learning about abstractions and inheritance design, i'd recomend you to check S.O.L.I.D. principles, there's a lot of literature in the web about those.
Edit: Response to your comment
First you need to ask yourself without thinking about internal details or implementations or testing or anything else, what are the behaviour my Views have? are they all behaving the same way? do i have different types of views or not really? Once you answer these questions and got an idea of what is going on, you'll have what it will need to design the interface hierarchy, and thats what is going to be exposed to the rest of the system.
You can (optionally) have abstract classes that derive from those interfaces, where you can provide some initialization, defaults, but, do not go further in offering more functionality than the interface offers, you can have some extra methods, but only for internal use.
And then you can derive the actual implementation of the views from the interface or the intermediate abstract classes if you have defined any.
Just think of this as a black box, in which the only thing you can see are the input and output interfaces, everything else that is going inside that box, the rest of the system doesn't and shouldn't need to know about.
Can't really give you specific solution because i'm not aware of the needs of your application.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I have been trying to find an appropriate design pattern, if a formal one exists, for the following scenario:
Object A requires an object B. Now, object B can be created using data from different sources, say S_1 or S_2. I don't want A to have to care about creating B, it should just be given it and proceed. So then, is there a nice clean way of creating B? I have thought about factory-type patterns but I do not have polymorphism at play. I was thinking something like:
B obj_b = B.createInstance(type_S_1);
obj_A.doSomething(obj_B);
where I give the type of data soruce to the static method createInstance().
I'm still learning a lot about design patterns, so that's why I ask. I may be over complicating things, so please feel free to say so!
As you realized, the Abstract Factory pattern is overkill for your use case as you do not need polymorphism. Still, the Concrete Factory part of this design pattern make sense. So this could look a bit like:
Datasource ds1 = ...;
Datasource ds2 = ...;
MyObject objectA = ...;
DatasourceBasedFactory factory1 = new DatasourceBasedFactory(ds1);
objectA.doSomething(factory1.create());
Knowing more about what you actually want to do might help to give you a better answer. Your current problem description is extremely abstract ... If you could give us some more details about your domain, that would help to give you a better answer.
I'm not sure, but perhaps the Builder Pattern? You can give it a type to specify what to build.
I would consider 2 differents approaches using generics.
The client will only deal with a common result Object that could be final for example.
No matter what your DataSource is, you can reduce the impact for the client.
Approach 1
Example
public interface DataSourceExtractor<T> {
public DataSourceExtractResult extract(T source);
}
public final ResultSetExtractor implements DataSourceExtractor<ResultSet>{
public DataSourceExtractResult extract(ResulSet source) {
//CODE HERE
return null;
}
}
public final ResultSetExtractor implements DataSourceExtractor<JsonNode>{
public DataSourceExtractResult extract(JsonNode source) {
//CODE HERE
return null;
}
}
But you can also meet the advantage of Abstract Class and Interface.
The advantage is that the client will inherit common methods or you can even implement template methods.
Example
public AbstractDataSourceExtractor<T> implements DataSourceExtractor<T> {
public static final SomeObject commonMethod(DataSourceExtractResult result) {
//CODE HERE
return null;
}
}
public final ResultSetExtractor extends AbstractDataSourceExtractor<ResultSet>{
public DataSourceExtractResult extract(ResulSet source) {
//CODE HERE
return null;
}
}
public final ResultSetExtractor extends AbstractDataSourceExtractor<JsonNode>{
public DataSourceExtractResult extract(JsonNode source) {
//CODE HERE
return null;
}
}
Approach 2
Example
You can also think about a generic Abstract builder, if many elements need to be set for the construction of the Instance.
The advatange of that solution is that you can set a default value, provide internal implementation hiding from the client if necessary.
public abstract class AbstractDataSourceExtractResultBuilder<T>{
private T _source;
public AbstractDataSourceExtractResultBuilder(T source) {
_source = source;
}
public abstract DataSourceExtractResult build();
}
public final class JsonDataSourceExtractBuilder extends AbstractDataSourceExtractResultBuilder<JsonNode> {
private String _name;
private Charset _charset;
public JsonDataSourceExtractBuilder(JsonNode source, String name){
//GUARD CODE
super(source);
_name = name;
_charset = Charset.defaultCharset();
}
public JsonDataSourceExtractBuilder useCharset(Charset charset){
if(charset == null){
throw new IllegalStateException("The charset is null");
}
_charset = charset;
return this;
}
//etc...
public DataSourceExtractResult build(){
//CODE HERE
return null;
}
}
I'm implementing MVP in my first GWT app using the recommended API from their docs, and admittedly, am doing some cargo cult programming while scrambling to learn/understand the API:
public class DefaultSignInView extends Composite implements SignInView {
private static DefaultSignInViewUiBinder uiBinder = GWT
.create(DefaultSignInViewUiBinder.class);
public DefaultSignInView() {
// ERROR: The method initWidget(Widget) in the type Composite is not applicable
// for the arguments (DivElement)
initWidget(uiBinder.createAndBindUi(this));
}
// Extends the UiBinder interface for this particular view.
interface DefaultSignInViewUiBinder extends UiBinder<DivElement, DefaultSignInView> {
// No-op.
}
}
In the above code snippet, the call to initWidget is a syntax/compiler error:
The method initWidget(Widget) in the type Composite is not applicable for the arguments (DivElement).
Now in the documentation (linked above) they show that you should extend UiBinder without the generic arguments. But I've also seen examples that use the generics, and again, cargo culting it, I borrowed from another example that used DivElement as the first argument. So, a few questions:
Why am I getting this syntax error?
What can I change DivElement to (or what else would I have to change) to correct it, besides removing the generic arguments? And if the generic arguments are deprecated or are truly no longer used, can someone explain why? In that case I'll just #SuppressWarnings.
Would someone provide a clear, layman's explanation of what the code is doing here? I hate cargo culting my code.
I sincerely think you are looking in the wrong place. Try this here. Most of it is explained in the docs, still i will try to highlight a few points,
What you are trying to do is very simple example of a UiBinder template that contains no widgets, only HTML.
So not being a widget, you cannot add it to a panel as a widget, instead you need to do a direct DOM manipulation.
I am adding a my sample code below
public class ImageViewer implements EntryPoint
{
#Override
public void onModuleLoad()
{
SampleUI sampleUI = new SampleUI();
sampleUI.setNameSpan(" Trying it out!!");
Document.get().getBody().appendChild(sampleUI.getElement());
}
}
SampleUI ui-binder
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder">
<ui:style>
.important {
font-weight: bold;
}
</ui:style>
<div>
Hello,
<span class="{style.important}" ui:field="nameSpan" />
</div>
</ui:UiBinder>
SampleUI java
public class SampleUI extends UIObject
{
private static SampleUIUiBinder uiBinder = GWT.create(SampleUIUiBinder.class);
interface SampleUIUiBinder extends UiBinder<DivElement, SampleUI>
{
}
private DivElement root;
#UiField
SpanElement nameSpan;
public SampleUI()
{
setElement(uiBinder.createAndBindUi(this));
}
public DivElement getRoot()
{
return root;
}
public void setNameSpan(String firstName)
{
nameSpan.setInnerText(firstName);
}
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I am currently working on an Object Oriented Design project, and would like to know if there is a better way to validate data in mutators of subclasses.
For example, I have a Home class with the subclasses Apartment, Condo, and House. In the Home class, I would like to include the mutators for (private) fields that the subclasses share. Say one of the fields is squareFootage. Is there a way to make the mutator in Home generic enough so that the subclasses can then set their own valid values for squareFootage without having to override the mutator completely? That is, I want different valid ranges for squareFootage for each subclass.
I've tried setting possible range values in Home, then override them in the subclasses. Unfortunately, the mutator in Home still grabs from the Home class and not the subclass.
So, I've resorted to abstracting the mutators, but unfortunately this results in a lot of repeated code, since I can literally copy and paste the mutators in each subclass.
I want to make the possible range values static if possible, and I understand this may be possible with reflection, but I'd really like to avoid using it for this project.
I think is possible by adding an abstract "validator" method that have to be implemented in the subclasses, something like this:
public class Home {
private float squareFootage;
public abstract void validateSquareFootage() throws MyValidationException; // you could throw an exception, runtime exception or return a boolean to indicate if value is valid or not
public void setSquareFootage(float squareFootage) {
validateSquareFootage(squareFootage); // again, throws exception or returns boolean, up to you
this.squareFootage = squareFootage;
}
// ... rest of implementation
}
And in a subclase:
public class Condo extends Home {
#Override
public void validateSquareFootage(float squareFootage) throws MyValidationException {
// ... do validations
}
}
and you don't have to override the mutator at all, just implement the correct validator.
It would probably be best to make the Home class an abstract class and have that extended in your subclasses. That way you can create methods in the home class that will hold true for all your subclasses but you can override them in the subclasses
If I understood your problem correctly, I think you want something like this ?
abstract class Home<T>{
protected T squareFootage;
abstract void setSquareFootage(T t);
}
class Apartment extends Home<String>{
#Override void setSquareFootage(String t) {
//...do something about the parameter
this.squareFootage = t;
}
}
class Condo extends Home<Integer>{
#Override void setSquareFootage(Integer t) {
//...do something about the parameter
this.squareFootage = t;
}
}
class House extends Home<Boolean>{
#Override void setSquareFootage(Boolean t) {
//...do something about the parameter
this.squareFootage = t;
}
}