Clément 148 Posted December 27, 2019 Hi, I have a base Frame that I use to derive most of UI. Is there any problem if I use several interfaces in my child frames? For example : TMyCustomerFrame = Class( TBaseFrame, ISupportDataset, ISupportResize, ISupportSelection, ISupportCRUD, .. ) TMySupplierFrame = Class( TBaseFrame, ISupportORM, ISupportResize, ISupportExcel, ISupportDragDrop ) There's one Frame that implements 8 Interfaces. It Works! but ... Is there any limit (Design or concept)? Because so far using Interfaces is helping me a lot and coding got a lot simpler too. Happy New Year! Clément Share this post Link to post
Anders Melander 1784 Posted December 27, 2019 I don't see any problems with it; It's a very common (and very sensible) pattern. Just make sure, if your base class is reference counted, that all references to the object is through interfaces. If it's not reference counted then that doesn't matter. Share this post Link to post
Clément 148 Posted December 27, 2019 2 hours ago, Anders Melander said: I don't see any problems with it; It's a very common (and very sensible) pattern. Just make sure, if your base class is reference counted, that all references to the object is through interfaces. If it's not reference counted then that doesn't matter. Yes, all references to the object are through interfaces. Really cool! Share this post Link to post
Stefan Glienke 2004 Posted December 28, 2019 If an object implements many interfaces it handles many responsibilities and not only a single one (SRP). You can use aggregation and delegation of those interfaces. 3 Share this post Link to post
Emil Mustea 6 Posted December 28, 2019 Be aware of: https://stackoverflow.com/a/20387132 It's a better way to use TFrame only as a view with minimum code and use a separate "controller" where to use aggregation and delegation. Share this post Link to post
Anders Melander 1784 Posted December 28, 2019 4 hours ago, Stefan Glienke said: You can use aggregation and delegation of those interfaces I can't really tell from your statement if you're saying that he doesn't do that but should or if you're just stating a general principle. From the code posted it's not possible to see if the implementation uses aggregation and/or delegation. 2 hours ago, Emil Mustea said: It's a better way [...] to use aggregation and delegation No. It's another way. Which is better depends on many factors and we can only guess since we don't know anything about the architecture or size of Clément's application, and it's not really relevant to the question asked. In my experience an application has to reach a certain size and complexity before it's worth even considering the overhead and added complexity of SRP. And even then I would only apply it if it solved an actual (present or near future) problem. Share this post Link to post
Clément 148 Posted December 28, 2019 Hi, It's a n-tier platform to help me build applications faster. I'm using TFrame to handle One thing : Visualization. For example: The ISupportAdjustToFrame will handle special form dimension. This mode doesn't allow the user to resize the form, the form is resized automatically to fit all editors and labels so they are displayed correctly (DPI, User fonts, etc). The ISupportDataset will handle data-aware editors with TDataset / TDatasource. The ISupportGrid will handle Grid, and in this case the form will be sized to a predefined value specified at design or runtime, and the user is allowed to resize up to a constraint limit. I like this solution because I can have a Frame that support Grid and Datasets, and another that support Grid and ORM. ( TFrameGridDataset = TBaseFrame+ISupportDataset + ISupportGrid and TFrameGridORM = TBaseFrame+ISupportORM + ISupportGrid respectivelly). The server side platform is holding part of the visual definition. The client request a "form design definition" and the response will contain the corresponding Frame name along with the visual components definition, all of them will be created at runtime. The client side platform has a few key "Form Containers" that will handle all those interface the frame depends on and display all those controls correctly. This way most definition will happen at server side. It's just a matter of picking the right Frame for the job Clément Share this post Link to post
Anders Melander 1784 Posted December 28, 2019 40 minutes ago, Clément said: The server side platform is holding part of the visual definition. I don't like this part; It sounds like you're polluting your business logic tier with presentation stuff. Even if you're just using the database and BO tiers for storage of the UI definitions, my guess is that you have created a strong binding between the UI definitions and the presentation tier, so the definitions can only be used by the one presentation tier(s). I've seen this done several times and it always ends up with half the UI being created the way you describe and the other done the traditional way because of special UI needs that the generic framework can't handle. And then eventually the need arises for a new type of client (e.g. web or mobile) that cannot use the existing UI definitions and slowly the definition framework decays because it turns out that it's faster to just create the whole UI on the client than trying to make the definition framework handle everything for everybody. It's a bit like the write once, run everywhere promise. Sometimes it just faster to write three separate applications than to have one application support three separate platforms. Share this post Link to post
Clément 148 Posted December 28, 2019 (edited) 2 hours ago, Anders Melander said: I don't like this part; It sounds like you're polluting your business logic tier with presentation stuff. Even if you're just using the database and BO tiers for storage of the UI definitions, my guess is that you have created a strong binding between the UI definitions and the presentation tier, so the definitions can only be used by the one presentation tier(s). I've seen this done several times and it always ends up with half the UI being created the way you describe and the other done the traditional way because of special UI needs that the generic framework can't handle. And then eventually the need arises for a new type of client (e.g. web or mobile) that cannot use the existing UI definitions and slowly the definition framework decays because it turns out that it's faster to just create the whole UI on the client than trying to make the definition framework handle everything for everybody. It's a bit like the write once, run everywhere promise. Sometimes it just faster to write three separate applications than to have one application support three separate platforms. I tried to keep the post as short as possible, but I guess it won't be possible My English is not very technical (or good), I must use some examples to help me explain. The client side platform has "ready to use frames" with editors placed at design time. Some frames are easy to create at runtime, I won't talk about those. Others not so easy (Customer, Orders, Contract, Services, Billing etc). So I derive from the my baseFrame and drop the corresponding controls at Design time. This is almost the only thing I can do. My users have different monitor resolutions, some have some sight problems, and sometimes Windows cannot natively display some information in a way they can read it. So in my application offer them a way to choose their favorite fonts and font sizes (some of them uses Tahoma 20 bold for normal label/editors). For this reason, I must resize the form in order to fit them as "designed". There other factors too, like for example skins (Some customer want me to design skin to match their logo, company colors and stuff ). Anyway, this is strictly handled on the client side. But as any other application there are some restrictions applied to users ( or modules). Fields they can't edit, or fields they can't see. Those are the definitions coming from the server. At server side, there are some "hard validation rules", like for example StartDate must be Less or equal do EndDate. This kind is still hard coded and I guess this falls into your strong binding UI Definition. I try to keep those to a minimum. But there are some soft rules that applies depending on the user ( or module ). For example, I must check if document number is valid when editing data on Module A, but that same document is optional for Module B, so no validation is required. Yet again, this rule can apply to Customer A, but Customer B wants both modules A and B to validate the document number. The way I implemented it all I have to do assign the "IsRequired" for that particular document number field of module A and Module B accordingly to that customer needs. The server side platform (REST API with JSON) is handling complex requests (Definition + Data) only from my client side platform. Third party system integrate with my server platform using another authorization scheme and a different REST API route. No UI Presentation to deal with. So far, no customer requested complex browser features. The mobile side is pretty simple too. Data entry is not practical at all so the UI must be very well thought, objective, touchy, battery and processor friendly. The only thing the app receives is Data, no definition or maybe some soft rules definition to display some nice glyph to the user in the next few months. Mobiles get their own set of "forms". This was a way I found to deal with all this UI presentation logic. This is just an example to help illustrate. I'm sure there are better ways to manage it, that's why I like it here! Always learning a better way to implement things Clément Edited December 29, 2019 by Clément 1 Share this post Link to post
Anders Melander 1784 Posted December 29, 2019 Thanks for the explanation. It seems much more reasonable now. With regard to validation rules some purists will insist that they belong with the business logic on that tier, and I've seen many examples that implement n-tier that way (post data to the server - get an error message back), but in my experience that result in poor user experience. Much better to validate data as early as possible, on the client, and validate it on the server. If the server can supply the meta data required for the client to build the UI and do validation I see no problem with that. Just out of curiosity: Have you tried using the DevExpress layout control to handle different font sizes and resolutions? Since I started using it to layout dialogs I've pretty much stopped worrying about what resolution/font/sizes the users are using; The layout control takes care of it. Share this post Link to post
Clément 148 Posted December 29, 2019 3 hours ago, Anders Melander said: Just out of curiosity: Have you tried using the DevExpress layout control to handle different font sizes and resolutions? Since I started using it to layout dialogs I've pretty much stopped worrying about what resolution/font/sizes the users are using; The layout control takes care of it. Yes. I'm redesigning to use their layout control. Most of my frames have standard VCL controls and some components of my own. Layout Control has an Import facility, but I can't use it right now. I have to reformat my frames to minimize rework. I tried importing some simple TFrames and it was easier to restart those from scratch. Some more complex frames got completely messed up. I'm experimenting with some reformatting/realigning to see if the Import result improves. Using their Layout Control is the way to go. Most of my visual problems are solved with it not to mention the component alignment is perfect. Share this post Link to post
Anders Melander 1784 Posted December 29, 2019 3 minutes ago, Clément said: I tried importing some simple TFrames and it was easier to restart those from scratch That's my experience too. 5 minutes ago, Clément said: the component alignment is perfect Yup. I'm very satisfied too. There are some layouts that are hard to get right (layout in columns comes to mind), but generally it has saved me a ton of work. Share this post Link to post
Fritzew 51 Posted December 29, 2019 Yes, it was one of the best moves we have done. The Layout-Control is a amazing component. We have refactored a big application to it (around 300 Forms) and it that has solved all of the problems with High-DPI. But the best, all of the translations problems, length of text's in label's etc are gone now. We supporting 7 languages. Share this post Link to post