i'm need your help again.
I have an document viewer application what can read two different kinds of documents:
Special one (based on PDF, with custom header)
Standart one ("raw" PDF).
With raw PDF viewer should acts like any other one.
With custom - execute some additional actions during it's opening, which are not available to raw PDF.
These actions should be available later in the application's menu only. And only for custom document.
Project OOP architecture (designed by other man) looks like this:
class GenericDocument
class PdfLibDocument
class CustomDocumentHighLevel
class CustomDocumentLowLevel
I.e. each higher-level class contains the lower-level one as member:
class GenericDocument
{
SmartPointer< PdfLibDocument > m_document;
...
};
and so on.
Custom document has much specific functionaly:
class CustomDocumentLowLevel
{
public:
void DoSomeBlackMagic();
...
// Another black magic
};
The problem occurs then i need to "pull" some low-level method from CustomDocumentLowLevel to GenericDocument (to show in app menu) - because i need to add this method to ALL FOUR classes!
And probably in the future i need to "pull" more methods from custom document.
Looks like this software architecture is bad choice in such case, isn't it?
So i need find a way to refactor this code. Should i replace aggregating with inheritance? Introduce interfaces?
Usually composition is preferred over inheritance, but it doesn't seem applicable to your case. Why not to inherit Viewers from one another? Make a base viewer with a simple functionality, available all over and then inherit specialised one from it adding new functionality.
As for menu and actions, connected with it, they should be represented as a separate objects. Check Command pattern for that.
UI can request available command list from your Viewers. Each viewer can fill its internal command list on initialization or construction or whatever you choose.
Related
I'm looking for an easy way (I think there isn't) to serialize a QGraphicsView or QGraphicsScene into XML or JSON.
I don't know if I'm supposed to save the View or the Scene. XML or JSON are fine I only need one of them. I just want to save a scene in a file to save it/load it
I found few stuff on other websites but it's seems quite complicated, or not really functional.
First of all, check out this very useful tutorial for working with json. Secondly, I think I've read you're working with a model-view based project?
If so, all model info should be saved and then there are two possibilities (depending on your design). Let's say you have created a model class PlayerList and you are showing all players using a PlayerListLayout or PlayerListView, a derived class from QVBoxLayout. Now there are two possibilities:
In each of the view classes, you have a direct reference to the model class. Well, all you need is to ask the model using getters (these getters would exist already, else you don't want to visualize the information). You don't need the json file, as long as you initialize your model first. So, for the PlayerListLayout, all you need to do is ask each Player* of that PlayerList-member and call PlayerLayout::read(Player* player) on all PlayerLayout members of PlayerListLayout. PlayerLayout will initialize it's new player-reference and ask the name, the capital, etc. to visualize it.
In one of the view class, you have no reference to any model class. Then you shall have to pass either the model or the json file to that view class, so you can get/read the information (again). This is a less clean way, which I don't prefer. It happened to me that I was creating large functions to read; that's when I found out something had to change. Reading and writing should be easy (if you divide the responsibilities in multiple classes).
I've had a Monopoly project, where I used this serialization as well, and the tutorial was really helpful. Secondly, I opened the .json file outside the model class (so in the view class), which you might want to consider as well. The disadvantage is that "when you want wo re-use the model classes, but not the view classes", you shall have to reimplement the opening and closing of a file in your new gui.
However, this way you create parallelism throughout your code, because returning true/false will happen in the view class of the main model (MonopolyLayout in my case), so the methods Monopoly::read(...), Board::read(...) all behave in a similar way.
Trying to learn some new design patterns , I came across the following problem.
Let's say we have the following interface : GUI_ITEM.
We have some classes that implement it like : Canvas , TextView , ListView ..
The target is to add some extra behavior to those classes such as :
Scrollbars , Title , Border ..
Now since we want to add a combination of behaviors to a given objects from the same interface ,
i'm guessing the right design to be used is a decorator .
This is the UML
UML
(this is from a slide-show i'm learning from)
So usage would be something like this :
GUI_Item* gui = new Scrollbars(new Border(new Title(new Canvas() ) ) );
The following question arises ;
What if I want to enforce a creation order ?
Since the border can hide the scroll bar , or we added another feature which is created at the same spot of another feature , thus can hide it .
I'm trying to figure out which design pattern will be the best solution here and how to implement it since I want to remove this responsibility from the client.
I can't seem to think of a proper design pattern here ? maybe I should combine the decorator with another solution ?
I thought about adding a member to each decorator-class marking its hierarchy(such that objects with the same hierarchy cannot be created together)
in the displaying order but this seems like a bad solution (Because I feel like its violating the OPEN/CLOSED principle)
Thanks !
I think (as you may also be thinking) that Decorator is not the most useful pattern for what you're trying to do. In particular, it seems like with your design, the widget-hierarchy can only be a straight line (with each widget having at most one decorator/child widget below it), whereas most GUIs fit more naturally with a branching-tree-structure, where each widget can hold (and serve as the "parent" of) any number of child widgets that represent other objects that are to be kept physically within the widget's geometric boundaries.
You might want to look at some other popular GUI APIs to see how they were designed -- in particular, I think Qt has a pretty good design -- a QWidgets-based-program's GUI consists of a tree of QWidgets, with the z-ordering defined by the structure of the tree (child widgets's pixels render "in front of" their parents' pixels), and each widget's x/y/w/h layout/positioning within its parent-widget is managed by separate QLayout objects.
What if I want to enforce a creation order ?
You could specify it in the constructor by specifying compatible subclasses to decorate but it is really clumsy and goes against the idea of the decorators where clients can easily decorate "decorable" objects and where implementations of decorator can be added/removed without breaking the code. It echoes to the OPEN/CLOSED principle you quote.
I thought about adding a member to each decorator-class marking its
hierarchy(such that objects with the same hierarchy cannot be created
together) in the displaying order but this seems like a bad solution
(Because I feel like its violating the OPEN/CLOSED principle)
It will duplicate/scatter rules of decoration in many decorator classes and it violates againts the OPEN/CLOSED principle : adding/removing/updating a decorator code may require change in many decorators.
I think that having a base class to represent gui items and specific kinds of items make sense but using the decorator will not be helpful since the rendering logic should be gathered and performed at a single place to make rules consistent and maintainable (one class to change).
I think that it should be a root gui item where you add the components in.
In this way, all rules would be applied to a single place when you do RootUi.add(GuiItem) or RootUi.addAll(GuiItem...).
This pattern is the mediator.
Note that the mediator can split its logical in multiple processing classes if it makes things clearer. For example a BackgroundProcessing class could handle the background, a ForegroundProcessing the foreground, another the overlay, and so for...
Our Application has components which consume components with consume components of varying complexity. So i just want the input on the page, to validate when an object is set that the text is correct. The issue is that it is one of these subcomponents.
My colleague told me that there is 2 ways to do this, The first is to use Page Objects, and Chaining annotation to find it on my page, and then find the next id etc until my input is found. It requires me to look through another teams' Component Markup to narrow it down to the input i want to leverage. I dont believe I should have to go into another component definition, or a definition of a definition to get the appropriate chain to get this arbitrary input. It starts to create issues where if a lateral team creates changes unbeknownst to me, my PO will be broken.
The other option my friend asked was to use fixture.query to find the component. This would be as simple as:
fixture.query((el)=> el.attribute["id"] == "description",
(comp){
expect(comp.value, value);
});`
Using Query looks at the markup but then will automatically componentize it as the appropriate SubComponent. In this case, comp.value is the value stored in the HTML. So, if i did something like:
fixture.update((MainComponent comp) {
comp.myinput.value = new Foo();
});
Then I am setting and getting this programmatically, so i am a bit unsure if it properly would reflect what is on the screen.
Whats the best course of action? It seems PO would be better, but im not sure if there is a way around having to deep query for input boxes outside of the component i am testing.
Thanks
I don't think I have a definitive answer for you but I can tell you how we do it at Google. For pretty much any component we provide the page object alongside the component. This is twofold it is for testing that widget, and also so we can have this as a shareable resource for other tests.
For leaf widgets the page objects are a little less fleshed out and are really just there for the local test. For components that are shared heavily the page object is a bit more flushed out for reusability. Without this much of the API for the widget (html, css, etc) we would need to consider public and changes to them would be very hard (person responsible for making the public breaking change needs to fix all associated code.) With it we can have a contract to only support the page object API and html structure changes are not considered breaking changes. At times we have even gone so far as to have two page objects for a widget. One for the local test, and one to share. Sometimes the API you want to expose for a local test is much more than you want people to use themselves.
We can then compose these page objects into higher level page objects that represent the widget. Good page objects support a higher level of abstraction for that widget. For example a calendar widget would let you go to the next/previous month, get the current selected date, etc. rather than directly exposing the buttons/inputs that accomplish those actions.
We plan to expose these page objects for angular_components eventually, but we are currently working on how to expose these. Our internal package structure is different than what we have externally. We have many packages per individual widget (page_objects, examples, widget itself) and we need to reconcile this externally before we expose them.
Here is an example:
import 'package:pageloader/objects.dart';
import 'material_button_po.dart';
/// Webdriver page object for `material-yes-no-buttons` component.
#EnsureTag('material-yes-no-buttons')
class MaterialYesNoButtonsPO {
#ByClass('btn-yes')
#optional
MaterialButtonPO yesButton;
#ByClass('btn-no')
#optional
MaterialButtonPO noButton;
}
I'm currently working on a project based on Qt4/QtCreator. I'd like to ask You for advice on how to organize my application.
There are 3 seperate tools, each has it's own view. All views are integrated in main window as non-closable tabs. I've prepare 3 views: Tool1View, Tool2View, Tool3View
Each tool is suppose to perform some task triggered by user actions. But these are not database related operations (list/add/modify...) - at least the user is not going add/modify/list records in gui elements.
I am thinking to implement each tool in 2 classes:
First class ToolXView implementing the widget and all tasks related to gui changes.
Second class ToolX implementing application logic. Member functions of this class are triggered by View class. Whenever this class has to update GUI elements it cals specialised functions in View class. So no direct calls to widgets are made from here.
View class and logic class will be linked with each other to allow 2 way communication.
Now I'm wondering if this is a good way to go. Please advice me based on Your experience.
I'm planning to encapsulate pointer to logic class as a property of a view class and pointer to view class as a property of logic class. This way I plan to integrade them.
Should I use signals/slots to provide comuncation or just call member functions ?
I'll have to store some data in QtSql database. Should I provide a seperate class for database access. Or just implement sepereate member function inside Logic class ?
How do You name Your classes. Is this scheme good or should I change it ?
Thanks for help. I appreciate your comments.
Using the mvc architecture is great.
1 & 2 - In the link above you will see the UML diagram of a mvc architecture. Regarding it, I would connect view signals to controller methods and then call a view method from controller.
3 - Regarding Database access I would add a Data Access part in your architecture which is specialized to the data access. You can have an interface to define the data access object signature and then implement it in a specialized class for database (So you will be able to change data location without modifying the whole application).
4 - You class naming seems good. But I would go further and call classes:
For view : ClassNameView
For Controller : ClassNameController
For DataAccessObject : ClassNameDAO
Model : ClassName (and IClassName for interface)
Hope that helps
I've got 2 applications (lets call them AppA and AppB) communicating with each other.
AppA is sending objects to AppB.
There could be different objects and AppB does not support every object.
An object could be a Model (think of a game, where models are vehicles, houses, persons etc).
There could be different AppBs. Each supporting another base of objects.
E.g. there could be an AppB which just supports vehicle-models. Another AppB just supports specific airplane-models.
The current case is the following:
There is a BasicModel which has a position and an orientation.
If another user wants extra attributes, he inherits an ExpandedModel. And adds e.g. an attribute Color.
Now every user who needs additional attributes inherits from a more general model. After a while there is a VehicleModel which could activate windshield-wipers, an AircraftModel which could have landing lights or a PersonModel which could wave goodbye when a certain boolean is set to true.
The AppB always needs to be customized if it should support a new Model.
This approach has a big disadvantage: It's getting extremely complex after a few inheritations. Perhaps there are redundancies like an ExpandedAircraftModel which could use windschield-wipers too.
Another approach:
I create just one Model-class which has an attribute-list. The most easy implementation would be a std::map where the Key is the attribute-name and the Value is the attribute-value.
The user could now enter as much information as he wants. If he wants to use a windshieldwiper he just adds a "windshieldwiper - ON"-pair.
If AppB supports windshieldwipers it just looks if there is such an attribute in the list and reads the related value.
A developer of AppB needs to document well what attributes he supports. Every developer has to check if the specific attribute is already existing and how it is called (e.g. one developer could name his attribute windshieldwiper and another calls it windshield-wiper)
This could get extremely complex too and the only thing a user can relate to is the documentation or a specific standard-specification which has to be kept at a central space.
Finally, the question:
Which approach is better?
Did you see any additional disadvantages?
Is there a third approach which should be used instead of these two?
Just for a comparison, Google's Protocol Buffers uses a combination of both but leans hard toward your second example.
If you have distinctly different data that needs to be sent over the channel, you use the tool to generate a derivitive of the "message" class, but each message can contain other messages, and you can nest message definitions in themselves. When a message is sent out, the receiver checks the fields to determine what type of message it is and what fields are contained within.
The downside is that your code becomes overly verbose very quickly, as you can't really use inheritance to automate the process of acting on an incoming message, but the upside is that your protocol messages stay highly organized and easy to DEBUG since you're using a reflexive attribute list of sorts.